@dudousxd/nestjs-agent-react 0.35.1 → 0.35.3
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/dist/{generative-ui-D1efzu_K.d.ts → generative-ui-DySIh0up.d.ts} +3 -0
- package/dist/{generative-ui-ClYT7OgL.d.cts → generative-ui-Pz1t-Ap3.d.cts} +3 -0
- package/dist/genui-json-render.cjs +88 -45
- package/dist/genui-json-render.cjs.map +1 -1
- package/dist/genui-json-render.d.cts +1 -1
- package/dist/genui-json-render.d.ts +1 -1
- package/dist/genui-json-render.js +91 -46
- package/dist/genui-json-render.js.map +1 -1
- package/dist/genui.cjs +88 -45
- package/dist/genui.cjs.map +1 -1
- package/dist/genui.d.cts +1 -1
- package/dist/genui.d.ts +1 -1
- package/dist/genui.js +91 -46
- package/dist/genui.js.map +1 -1
- package/dist/index.cjs +172 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +251 -161
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1380,6 +1380,39 @@ function useAmbientRenderUi() {
|
|
|
1380
1380
|
// src/genui/generative-ui.tsx
|
|
1381
1381
|
var import_react4 = require("react");
|
|
1382
1382
|
|
|
1383
|
+
// src/genui/share-structure.ts
|
|
1384
|
+
function isPlainObject(value) {
|
|
1385
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
1386
|
+
const prototype = Object.getPrototypeOf(value);
|
|
1387
|
+
return prototype === Object.prototype || prototype === null;
|
|
1388
|
+
}
|
|
1389
|
+
function shareStructure(previous, next) {
|
|
1390
|
+
if (Object.is(previous, next)) return next;
|
|
1391
|
+
if (Array.isArray(next)) {
|
|
1392
|
+
if (!Array.isArray(previous)) return next;
|
|
1393
|
+
let same = previous.length === next.length;
|
|
1394
|
+
const shared3 = next.map((value, index) => {
|
|
1395
|
+
const kept = shareStructure(previous[index], value);
|
|
1396
|
+
if (kept !== previous[index]) same = false;
|
|
1397
|
+
return kept;
|
|
1398
|
+
});
|
|
1399
|
+
return same ? previous : shared3;
|
|
1400
|
+
}
|
|
1401
|
+
if (isPlainObject(next)) {
|
|
1402
|
+
if (!isPlainObject(previous)) return next;
|
|
1403
|
+
const keys = Object.keys(next);
|
|
1404
|
+
let same = keys.length === Object.keys(previous).length;
|
|
1405
|
+
const shared3 = {};
|
|
1406
|
+
for (const key of keys) {
|
|
1407
|
+
const kept = shareStructure(previous[key], next[key]);
|
|
1408
|
+
if (kept !== previous[key] || !Object.hasOwn(previous, key)) same = false;
|
|
1409
|
+
shared3[key] = kept;
|
|
1410
|
+
}
|
|
1411
|
+
return same ? previous : shared3;
|
|
1412
|
+
}
|
|
1413
|
+
return next;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1383
1416
|
// src/genui/use-generative-ui.ts
|
|
1384
1417
|
var import_react3 = require("react");
|
|
1385
1418
|
|
|
@@ -1551,10 +1584,10 @@ var TreeScopeContext = (0, import_react4.createContext)(null);
|
|
|
1551
1584
|
var GenuiNodeContext = sharedContext(
|
|
1552
1585
|
"@dudousxd/nestjs-agent-react:genui-node"
|
|
1553
1586
|
);
|
|
1554
|
-
function renderPlaceholder(
|
|
1555
|
-
const { placeholder } =
|
|
1587
|
+
function renderPlaceholder(look, node) {
|
|
1588
|
+
const { placeholder } = look;
|
|
1556
1589
|
if (typeof placeholder === "function") return placeholder(node);
|
|
1557
|
-
return placeholder !== void 0 ? placeholder :
|
|
1590
|
+
return placeholder !== void 0 ? placeholder : look.loading;
|
|
1558
1591
|
}
|
|
1559
1592
|
function renderFallback(fallback2, problem) {
|
|
1560
1593
|
if (typeof fallback2 === "function") return fallback2(problem);
|
|
@@ -1588,9 +1621,33 @@ var ItemBoundary = class extends import_react4.Component {
|
|
|
1588
1621
|
function nodeItem(node, id) {
|
|
1589
1622
|
return { id, component: node.type, props: node.props ?? {}, version: null, toolCallId: null };
|
|
1590
1623
|
}
|
|
1591
|
-
function
|
|
1624
|
+
function failsWhole(scope) {
|
|
1625
|
+
return !scope.hasFallback && scope.fallbackText !== void 0;
|
|
1626
|
+
}
|
|
1627
|
+
var TreeNode = (0, import_react4.memo)(
|
|
1628
|
+
function TreeNode2({ node, id, bounded }) {
|
|
1629
|
+
const scope = (0, import_react4.useContext)(TreeScopeContext);
|
|
1630
|
+
const item = (0, import_react4.useMemo)(() => nodeItem(node, id), [node, id]);
|
|
1631
|
+
if (scope === null) return null;
|
|
1632
|
+
if (!bounded || failsWhole(scope)) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TreeNodeBody, { node, id, item });
|
|
1633
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1634
|
+
ItemBoundary,
|
|
1635
|
+
{
|
|
1636
|
+
item,
|
|
1637
|
+
fallback: scope.look.current.fallback,
|
|
1638
|
+
onError: scope.look.current.onError,
|
|
1639
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TreeNodeBody, { node, id, item })
|
|
1640
|
+
}
|
|
1641
|
+
);
|
|
1642
|
+
},
|
|
1643
|
+
(previous, next) => previous.node === next.node && previous.id === next.id && previous.bounded === next.bounded
|
|
1644
|
+
);
|
|
1645
|
+
function TreeNodeBody({
|
|
1646
|
+
node,
|
|
1647
|
+
id,
|
|
1648
|
+
item
|
|
1649
|
+
}) {
|
|
1592
1650
|
const scope = (0, import_react4.useContext)(TreeScopeContext);
|
|
1593
|
-
const item = (0, import_react4.useMemo)(() => nodeItem(node, id), [node, id]);
|
|
1594
1651
|
const incomplete = node.incomplete === true;
|
|
1595
1652
|
const held = node.held === true;
|
|
1596
1653
|
const state = (0, import_react4.useMemo)(
|
|
@@ -1612,45 +1669,37 @@ function TreeNode({ node, id }) {
|
|
|
1612
1669
|
item.props
|
|
1613
1670
|
);
|
|
1614
1671
|
if (scope === null) return null;
|
|
1672
|
+
const look = scope.look.current;
|
|
1615
1673
|
if (held) {
|
|
1616
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GenuiNodeContext.Provider, { value: state, children: renderPlaceholder(
|
|
1674
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GenuiNodeContext.Provider, { value: state, children: renderPlaceholder(look, state) });
|
|
1617
1675
|
}
|
|
1618
|
-
if (resolution.status === "loading" || validation.status === "pending") return
|
|
1676
|
+
if (resolution.status === "loading" || validation.status === "pending") return look.loading;
|
|
1619
1677
|
if (resolution.status === "unknown") {
|
|
1620
|
-
if (scope
|
|
1621
|
-
|
|
1622
|
-
return renderFallback(scope.fallback, { reason: "unknown", item });
|
|
1678
|
+
if (failsWhole(scope)) throw new Error("Unknown tree component");
|
|
1679
|
+
return renderFallback(look.fallback, { reason: "unknown", item });
|
|
1623
1680
|
}
|
|
1624
1681
|
if (resolution.status === "error") {
|
|
1625
|
-
if (scope
|
|
1626
|
-
return renderFallback(
|
|
1682
|
+
if (failsWhole(scope)) throw resolution.error;
|
|
1683
|
+
return renderFallback(look.fallback, { reason: "error", item, error: resolution.error });
|
|
1627
1684
|
}
|
|
1628
1685
|
if (validation.status === "invalid") {
|
|
1629
|
-
if (scope
|
|
1630
|
-
|
|
1631
|
-
return renderFallback(scope.fallback, { reason: "invalid", item, issues: validation.issues });
|
|
1686
|
+
if (failsWhole(scope)) throw new Error("Invalid tree component");
|
|
1687
|
+
return renderFallback(look.fallback, { reason: "invalid", item, issues: validation.issues });
|
|
1632
1688
|
}
|
|
1633
1689
|
const Renderer = resolution.Component;
|
|
1634
1690
|
const children = Array.isArray(node.children) ? node.children : [];
|
|
1635
1691
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GenuiNodeContext.Provider, { value: state, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Renderer, { ...validation.props, children: children.length > 0 ? children.map((child, index) => {
|
|
1636
1692
|
const childId = `${id}.${index}`;
|
|
1637
|
-
|
|
1638
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TreeNode, { node: child, id: childId }, childId);
|
|
1639
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1640
|
-
ItemBoundary,
|
|
1641
|
-
{
|
|
1642
|
-
item: nodeItem(child, childId),
|
|
1643
|
-
fallback: scope.fallback,
|
|
1644
|
-
onError: scope.onError,
|
|
1645
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TreeNode, { node: child, id: childId })
|
|
1646
|
-
},
|
|
1647
|
-
childId
|
|
1648
|
-
);
|
|
1693
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TreeNode, { node: child, id: childId, bounded: true }, childId);
|
|
1649
1694
|
}) : void 0 }) });
|
|
1650
1695
|
}
|
|
1651
1696
|
function GenuiTree({ root }) {
|
|
1652
|
-
|
|
1653
|
-
|
|
1697
|
+
const previous = (0, import_react4.useRef)(void 0);
|
|
1698
|
+
const valid = root !== void 0 && root !== null && typeof root.type === "string";
|
|
1699
|
+
const shared3 = valid ? shareStructure(previous.current, root) : void 0;
|
|
1700
|
+
previous.current = shared3;
|
|
1701
|
+
if (shared3 === void 0) return null;
|
|
1702
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TreeNode, { node: shared3, id: "root", bounded: false });
|
|
1654
1703
|
}
|
|
1655
1704
|
function GenerativeUIScope({
|
|
1656
1705
|
registry,
|
|
@@ -1664,6 +1713,12 @@ function GenerativeUIScope({
|
|
|
1664
1713
|
onError,
|
|
1665
1714
|
children
|
|
1666
1715
|
}) {
|
|
1716
|
+
const versionsRef = (0, import_react4.useRef)(void 0);
|
|
1717
|
+
const versions = shareStructure(versionsRef.current, componentVersions);
|
|
1718
|
+
versionsRef.current = versions;
|
|
1719
|
+
const look = (0, import_react4.useRef)({ fallback: fallback2, loading, placeholder, onError });
|
|
1720
|
+
look.current = { fallback: fallback2, loading, placeholder, onError };
|
|
1721
|
+
const hasFallback = fallback2 !== void 0;
|
|
1667
1722
|
const scope = (0, import_react4.useMemo)(
|
|
1668
1723
|
() => ({
|
|
1669
1724
|
options: {
|
|
@@ -1671,24 +1726,12 @@ function GenerativeUIScope({
|
|
|
1671
1726
|
...catalog !== void 0 ? { catalog } : {},
|
|
1672
1727
|
...resolveComponent !== void 0 ? { resolveComponent } : {}
|
|
1673
1728
|
},
|
|
1674
|
-
|
|
1675
|
-
...
|
|
1729
|
+
hasFallback,
|
|
1730
|
+
...versions !== void 0 ? { componentVersions: versions } : {},
|
|
1676
1731
|
...fallbackText !== void 0 ? { fallbackText } : {},
|
|
1677
|
-
|
|
1678
|
-
placeholder,
|
|
1679
|
-
onError
|
|
1732
|
+
look
|
|
1680
1733
|
}),
|
|
1681
|
-
[
|
|
1682
|
-
registry,
|
|
1683
|
-
catalog,
|
|
1684
|
-
resolveComponent,
|
|
1685
|
-
fallback2,
|
|
1686
|
-
fallbackText,
|
|
1687
|
-
componentVersions,
|
|
1688
|
-
loading,
|
|
1689
|
-
placeholder,
|
|
1690
|
-
onError
|
|
1691
|
-
]
|
|
1734
|
+
[registry, catalog, resolveComponent, hasFallback, fallbackText, versions]
|
|
1692
1735
|
);
|
|
1693
1736
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TreeScopeContext.Provider, { value: scope, children });
|
|
1694
1737
|
}
|
|
@@ -4245,6 +4288,7 @@ function useTranscriptItems({
|
|
|
4245
4288
|
);
|
|
4246
4289
|
const callbackCache = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
|
|
4247
4290
|
const reasoningToggleCache = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
|
|
4291
|
+
const uiBlocks = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
|
|
4248
4292
|
const toggleReasoning = (0, import_react17.useCallback)((key, open) => {
|
|
4249
4293
|
setOpenReasoning((current) => {
|
|
4250
4294
|
const next = new Map(current);
|
|
@@ -4439,6 +4483,14 @@ function useTranscriptItems({
|
|
|
4439
4483
|
}, []);
|
|
4440
4484
|
const lastAssistantId = findLastAssistant(messages)?.id ?? null;
|
|
4441
4485
|
const items = [];
|
|
4486
|
+
const previousUi = uiBlocks.current;
|
|
4487
|
+
const keptUi = /* @__PURE__ */ new Map();
|
|
4488
|
+
const keepUiIdentity = (blocks) => blocks.map((block) => {
|
|
4489
|
+
if (block.kind !== "ui") return block;
|
|
4490
|
+
const kept = shareStructure(previousUi.get(block.key), block);
|
|
4491
|
+
keptUi.set(block.key, kept);
|
|
4492
|
+
return kept;
|
|
4493
|
+
});
|
|
4442
4494
|
for (let index = visibleStart; index < messages.length; index++) {
|
|
4443
4495
|
const message = messages[index];
|
|
4444
4496
|
if (!message) {
|
|
@@ -4461,37 +4513,39 @@ function useTranscriptItems({
|
|
|
4461
4513
|
isAssistant,
|
|
4462
4514
|
isLastAssistant,
|
|
4463
4515
|
isStreaming: message.id === streamingMessageId,
|
|
4464
|
-
blocks:
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4516
|
+
blocks: keepUiIdentity(
|
|
4517
|
+
buildTranscriptBlocks(message, {
|
|
4518
|
+
isReasoningOpen: (key, isStreamingRun) => openReasoning.get(key) ?? isStreamingRun,
|
|
4519
|
+
toggleReasoning: (key, open) => stableToggle(key)(open),
|
|
4520
|
+
...options.sources !== void 0 ? { sources: options.sources } : {},
|
|
4521
|
+
...options.toolCatalog !== void 0 ? { toolCatalog: options.toolCatalog } : {},
|
|
4522
|
+
// Read-only still lifts question sets into their block, so the outcome shows.
|
|
4523
|
+
...handlers.onAnswer !== void 0 || options.readOnly === true && options.onAnswer !== null ? {
|
|
4524
|
+
elicitation: {
|
|
4525
|
+
picked: (toolCallId, questionId) => picks.get(pickKey(toolCallId, questionId)),
|
|
4526
|
+
pick,
|
|
4527
|
+
canAnswer: handlers.onAnswer !== void 0,
|
|
4528
|
+
canSkip: handlers.onSkip !== void 0,
|
|
4529
|
+
answer,
|
|
4530
|
+
skip,
|
|
4531
|
+
submitting: (toolCallId) => settling.get(toolCallId) ?? null,
|
|
4532
|
+
errorOf: (toolCallId) => settleErrors.get(toolCallId)?.message ?? null,
|
|
4533
|
+
errorCodeOf: (toolCallId) => settleErrors.get(toolCallId)?.code ?? null
|
|
4534
|
+
}
|
|
4535
|
+
} : {},
|
|
4536
|
+
...handlers.onApprove !== void 0 || handlers.onReject !== void 0 ? {
|
|
4537
|
+
approval: {
|
|
4538
|
+
canApprove: handlers.onApprove !== void 0,
|
|
4539
|
+
canReject: handlers.onReject !== void 0,
|
|
4540
|
+
approve,
|
|
4541
|
+
reject,
|
|
4542
|
+
submitting: (toolCallId) => settling.get(toolCallId) ?? null,
|
|
4543
|
+
errorOf: (toolCallId) => settleErrors.get(toolCallId)?.message ?? null,
|
|
4544
|
+
errorCodeOf: (toolCallId) => settleErrors.get(toolCallId)?.code ?? null
|
|
4545
|
+
}
|
|
4546
|
+
} : {}
|
|
4547
|
+
})
|
|
4548
|
+
),
|
|
4495
4549
|
text,
|
|
4496
4550
|
usage: usage ? describeUsage(usage) : null,
|
|
4497
4551
|
timestamp: describeTimestamp((options.getCreatedAt ?? createdAtFromMetadata)(message)),
|
|
@@ -4526,6 +4580,7 @@ function useTranscriptItems({
|
|
|
4526
4580
|
}
|
|
4527
4581
|
});
|
|
4528
4582
|
}
|
|
4583
|
+
uiBlocks.current = keptUi;
|
|
4529
4584
|
return items;
|
|
4530
4585
|
}
|
|
4531
4586
|
function settleHandlers(options, backend) {
|
|
@@ -5719,9 +5774,24 @@ function outcomeId(value) {
|
|
|
5719
5774
|
}
|
|
5720
5775
|
|
|
5721
5776
|
// src/approvals/use-action-proposals.ts
|
|
5777
|
+
var UNSUPPORTED_STATUSES = /* @__PURE__ */ new Set([404, 405, 501]);
|
|
5778
|
+
var UNKNOWN_THREAD = /* @__PURE__ */ new Set(["Thread not found", "Unknown thread"]);
|
|
5779
|
+
var MAX_BACKOFF_MS = 3e4;
|
|
5780
|
+
var unsupportedBackends = /* @__PURE__ */ new WeakSet();
|
|
5781
|
+
function statusOf(cause) {
|
|
5782
|
+
const status = cause?.status;
|
|
5783
|
+
return typeof status === "number" ? status : void 0;
|
|
5784
|
+
}
|
|
5785
|
+
function isProposalsUnsupported(cause) {
|
|
5786
|
+
const status = statusOf(cause);
|
|
5787
|
+
if (status === void 0 || !UNSUPPORTED_STATUSES.has(status)) return false;
|
|
5788
|
+
return !(status === 404 && cause instanceof Error && UNKNOWN_THREAD.has(cause.message));
|
|
5789
|
+
}
|
|
5722
5790
|
function useActionProposals(backend, threadId, setMessages, refreshKey, pollMs = 1e3) {
|
|
5723
5791
|
const [items, setItems] = (0, import_react22.useState)([]);
|
|
5724
5792
|
const [error, setError] = (0, import_react22.useState)(null);
|
|
5793
|
+
const [unsupported, setUnsupported] = (0, import_react22.useState)(() => unsupportedBackends.has(backend));
|
|
5794
|
+
const [failures, setFailures] = (0, import_react22.useState)(0);
|
|
5725
5795
|
const latest = (0, import_react22.useRef)({ threadId, setMessages });
|
|
5726
5796
|
latest.current = { threadId, setMessages };
|
|
5727
5797
|
const mounted = (0, import_react22.useRef)(true);
|
|
@@ -5734,6 +5804,7 @@ function useActionProposals(backend, threadId, setMessages, refreshKey, pollMs =
|
|
|
5734
5804
|
}, []);
|
|
5735
5805
|
const refresh = (0, import_react22.useCallback)(async () => {
|
|
5736
5806
|
if (threadId === void 0 || backend.listActionProposals === void 0) return;
|
|
5807
|
+
if (unsupportedBackends.has(backend)) return;
|
|
5737
5808
|
const pending = requests.current.get(threadId);
|
|
5738
5809
|
if (pending) return pending;
|
|
5739
5810
|
const request = (async () => {
|
|
@@ -5750,12 +5821,23 @@ function useActionProposals(backend, threadId, setMessages, refreshKey, pollMs =
|
|
|
5750
5821
|
if (!mounted.current || latest.current.threadId !== threadId) return;
|
|
5751
5822
|
setItems(proposals);
|
|
5752
5823
|
setError(null);
|
|
5824
|
+
setFailures(0);
|
|
5753
5825
|
latest.current.setMessages(
|
|
5754
5826
|
(current) => reconcileProposalMessages(current, proposals, facts)
|
|
5755
5827
|
);
|
|
5756
5828
|
} catch (cause) {
|
|
5757
|
-
if (
|
|
5829
|
+
if (isProposalsUnsupported(cause)) {
|
|
5830
|
+
unsupportedBackends.add(backend);
|
|
5831
|
+
if (mounted.current) {
|
|
5832
|
+
setUnsupported(true);
|
|
5833
|
+
setError(null);
|
|
5834
|
+
}
|
|
5835
|
+
return;
|
|
5836
|
+
}
|
|
5837
|
+
if (mounted.current && latest.current.threadId === threadId) {
|
|
5758
5838
|
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
5839
|
+
setFailures((count) => count + 1);
|
|
5840
|
+
}
|
|
5759
5841
|
}
|
|
5760
5842
|
})();
|
|
5761
5843
|
requests.current.set(threadId, request);
|
|
@@ -5768,18 +5850,24 @@ function useActionProposals(backend, threadId, setMessages, refreshKey, pollMs =
|
|
|
5768
5850
|
(0, import_react22.useEffect)(() => {
|
|
5769
5851
|
setItems([]);
|
|
5770
5852
|
setError(null);
|
|
5853
|
+
setFailures(0);
|
|
5771
5854
|
}, [threadId]);
|
|
5855
|
+
(0, import_react22.useEffect)(() => {
|
|
5856
|
+
setUnsupported(unsupportedBackends.has(backend));
|
|
5857
|
+
}, [backend]);
|
|
5772
5858
|
(0, import_react22.useEffect)(() => {
|
|
5773
5859
|
void refresh();
|
|
5774
5860
|
}, [refresh, refreshKey]);
|
|
5775
5861
|
(0, import_react22.useEffect)(() => {
|
|
5776
|
-
if (!items.some(proposalNeedsPolling) || pollMs <= 0) return;
|
|
5777
|
-
const
|
|
5862
|
+
if (unsupported || !items.some(proposalNeedsPolling) || pollMs <= 0) return;
|
|
5863
|
+
const wait = failures === 0 ? pollMs : Math.min(pollMs * 2 ** failures, MAX_BACKOFF_MS);
|
|
5864
|
+
const timer = setTimeout(() => {
|
|
5778
5865
|
void refresh();
|
|
5779
|
-
},
|
|
5780
|
-
return () =>
|
|
5781
|
-
}, [items, pollMs, refresh]);
|
|
5866
|
+
}, wait);
|
|
5867
|
+
return () => clearTimeout(timer);
|
|
5868
|
+
}, [items, failures, unsupported, pollMs, refresh]);
|
|
5782
5869
|
(0, import_react22.useEffect)(() => {
|
|
5870
|
+
if (unsupported) return;
|
|
5783
5871
|
const refetch = () => {
|
|
5784
5872
|
void refresh();
|
|
5785
5873
|
};
|
|
@@ -5794,8 +5882,8 @@ function useActionProposals(backend, threadId, setMessages, refreshKey, pollMs =
|
|
|
5794
5882
|
window.removeEventListener("online", refetch);
|
|
5795
5883
|
document.removeEventListener("visibilitychange", visible);
|
|
5796
5884
|
};
|
|
5797
|
-
}, [refresh]);
|
|
5798
|
-
return { items, error, refresh };
|
|
5885
|
+
}, [refresh, unsupported]);
|
|
5886
|
+
return { items, error, unsupported, refresh };
|
|
5799
5887
|
}
|
|
5800
5888
|
|
|
5801
5889
|
// src/use-agent-chat.ts
|