@dudousxd/nestjs-agent-react 0.22.1 → 0.24.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 +5 -0
- package/dist/{client-CYlhK7XD.d.cts → client-ioKDyV2q.d.cts} +5 -1
- package/dist/{client-CYlhK7XD.d.ts → client-ioKDyV2q.d.ts} +5 -1
- package/dist/index.cjs +383 -268
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -12
- package/dist/index.d.ts +39 -12
- package/dist/index.js +218 -104
- 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 +2 -2
package/dist/index.js
CHANGED
|
@@ -203,6 +203,10 @@ var AgentClient = class {
|
|
|
203
203
|
listAgents() {
|
|
204
204
|
return this.request("GET", "/agents");
|
|
205
205
|
}
|
|
206
|
+
/** `GET <path>/config` — attachment limits and upload mode, and which features are on. */
|
|
207
|
+
getConfig() {
|
|
208
|
+
return this.request("GET", "/config");
|
|
209
|
+
}
|
|
206
210
|
/** `GET <path>/quota` — the caller's budget windows and the one blocking sends, if any. */
|
|
207
211
|
getQuota() {
|
|
208
212
|
return this.request("GET", "/quota");
|
|
@@ -860,6 +864,13 @@ var AgentChatTransport = class {
|
|
|
860
864
|
}
|
|
861
865
|
});
|
|
862
866
|
break;
|
|
867
|
+
case "message-metadata":
|
|
868
|
+
ensureStarted();
|
|
869
|
+
controller.enqueue({
|
|
870
|
+
type: "message-metadata",
|
|
871
|
+
messageMetadata: event.metadata
|
|
872
|
+
});
|
|
873
|
+
break;
|
|
863
874
|
case "title":
|
|
864
875
|
case "cancelled":
|
|
865
876
|
forwardAsData(event, true);
|
|
@@ -1113,7 +1124,7 @@ function dragHasFiles(data) {
|
|
|
1113
1124
|
__name(dragHasFiles, "dragHasFiles");
|
|
1114
1125
|
|
|
1115
1126
|
// src/attachments/use-attachments.ts
|
|
1116
|
-
import { useCallback as useCallback2, useEffect as
|
|
1127
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo4, useRef as useRef3, useState as useState4 } from "react";
|
|
1117
1128
|
|
|
1118
1129
|
// src/backend.ts
|
|
1119
1130
|
var AgentBackendUnsupportedError = class extends Error {
|
|
@@ -1135,6 +1146,9 @@ function requireBackendMethod(backend, name) {
|
|
|
1135
1146
|
}
|
|
1136
1147
|
__name(requireBackendMethod, "requireBackendMethod");
|
|
1137
1148
|
|
|
1149
|
+
// src/config/use-agent-config.ts
|
|
1150
|
+
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
1151
|
+
|
|
1138
1152
|
// src/provider.tsx
|
|
1139
1153
|
import { useContext as useContext3, useMemo as useMemo3, useRef as useRef2 } from "react";
|
|
1140
1154
|
|
|
@@ -1699,6 +1713,59 @@ function useAgentBackend(own) {
|
|
|
1699
1713
|
}
|
|
1700
1714
|
__name(useAgentBackend, "useAgentBackend");
|
|
1701
1715
|
|
|
1716
|
+
// src/config/use-agent-config.ts
|
|
1717
|
+
var shared = /* @__PURE__ */ new WeakMap();
|
|
1718
|
+
function load(backend) {
|
|
1719
|
+
const getConfig = backend.getConfig;
|
|
1720
|
+
if (typeof getConfig !== "function") return void 0;
|
|
1721
|
+
let pending = shared.get(backend);
|
|
1722
|
+
if (pending === void 0) {
|
|
1723
|
+
pending = getConfig.call(backend).catch((error) => {
|
|
1724
|
+
shared.delete(backend);
|
|
1725
|
+
throw error;
|
|
1726
|
+
});
|
|
1727
|
+
shared.set(backend, pending);
|
|
1728
|
+
}
|
|
1729
|
+
return pending;
|
|
1730
|
+
}
|
|
1731
|
+
__name(load, "load");
|
|
1732
|
+
function useAgentConfig(options = {}) {
|
|
1733
|
+
const backend = useAgentBackend(options.backend);
|
|
1734
|
+
const enabled = options.enabled !== false;
|
|
1735
|
+
const [config, setConfig] = useState3(void 0);
|
|
1736
|
+
const [isLoading, setLoading] = useState3(false);
|
|
1737
|
+
const [error, setError] = useState3(null);
|
|
1738
|
+
useEffect3(() => {
|
|
1739
|
+
if (!enabled) return;
|
|
1740
|
+
const pending = load(backend);
|
|
1741
|
+
if (pending === void 0) return;
|
|
1742
|
+
let cancelled = false;
|
|
1743
|
+
setLoading(true);
|
|
1744
|
+
pending.then((loaded) => {
|
|
1745
|
+
if (cancelled) return;
|
|
1746
|
+
setConfig(loaded !== null && typeof loaded === "object" ? loaded : void 0);
|
|
1747
|
+
setError(null);
|
|
1748
|
+
setLoading(false);
|
|
1749
|
+
}, (failure) => {
|
|
1750
|
+
if (cancelled) return;
|
|
1751
|
+
setError(failure instanceof Error ? failure : new Error(String(failure)));
|
|
1752
|
+
setLoading(false);
|
|
1753
|
+
});
|
|
1754
|
+
return () => {
|
|
1755
|
+
cancelled = true;
|
|
1756
|
+
};
|
|
1757
|
+
}, [
|
|
1758
|
+
backend,
|
|
1759
|
+
enabled
|
|
1760
|
+
]);
|
|
1761
|
+
return {
|
|
1762
|
+
config,
|
|
1763
|
+
isLoading,
|
|
1764
|
+
error
|
|
1765
|
+
};
|
|
1766
|
+
}
|
|
1767
|
+
__name(useAgentConfig, "useAgentConfig");
|
|
1768
|
+
|
|
1702
1769
|
// src/attachments/use-attachments.ts
|
|
1703
1770
|
var DEFAULT_REJECTION = {
|
|
1704
1771
|
type: /* @__PURE__ */ __name((file) => `${file.name} is not a supported file type`, "type"),
|
|
@@ -1708,19 +1775,33 @@ var DEFAULT_REJECTION = {
|
|
|
1708
1775
|
var sequence = 0;
|
|
1709
1776
|
function useAttachments(options = {}) {
|
|
1710
1777
|
const backend = useAgentBackend(options.backend);
|
|
1711
|
-
const
|
|
1712
|
-
...options,
|
|
1778
|
+
const { config } = useAgentConfig({
|
|
1713
1779
|
backend
|
|
1714
1780
|
});
|
|
1715
|
-
|
|
1781
|
+
const limits = config?.attachments;
|
|
1782
|
+
const accept = options.accept ?? limits?.allowedContentTypes;
|
|
1783
|
+
const maxBytes = options.maxBytes ?? limits?.maxBytes;
|
|
1784
|
+
const maxFiles = options.maxFiles ?? limits?.maxPerMessage;
|
|
1785
|
+
const effective = {
|
|
1716
1786
|
...options,
|
|
1717
|
-
backend
|
|
1787
|
+
backend,
|
|
1788
|
+
...accept !== void 0 ? {
|
|
1789
|
+
accept
|
|
1790
|
+
} : {},
|
|
1791
|
+
...maxBytes !== void 0 ? {
|
|
1792
|
+
maxBytes
|
|
1793
|
+
} : {},
|
|
1794
|
+
...maxFiles !== void 0 ? {
|
|
1795
|
+
maxFiles
|
|
1796
|
+
} : {}
|
|
1718
1797
|
};
|
|
1719
|
-
const
|
|
1798
|
+
const latest = useRef3(effective);
|
|
1799
|
+
latest.current = effective;
|
|
1800
|
+
const [items, setItems] = useState4([]);
|
|
1720
1801
|
const itemsRef = useRef3(items);
|
|
1721
1802
|
itemsRef.current = items;
|
|
1722
1803
|
const controllers = useRef3(/* @__PURE__ */ new Map());
|
|
1723
|
-
const [dragDepth, setDragDepth] =
|
|
1804
|
+
const [dragDepth, setDragDepth] = useState4(0);
|
|
1724
1805
|
const patch = useCallback2((id, change) => {
|
|
1725
1806
|
setItems((current) => current.map((item) => item.id === id ? {
|
|
1726
1807
|
...item,
|
|
@@ -1765,9 +1846,9 @@ function useAttachments(options = {}) {
|
|
|
1765
1846
|
]);
|
|
1766
1847
|
const add = useCallback2((files) => {
|
|
1767
1848
|
if (files == null) return;
|
|
1768
|
-
const { accept: accept2, maxBytes, maxFiles, describeRejection } = latest.current;
|
|
1849
|
+
const { accept: accept2, maxBytes: maxBytes2, maxFiles: maxFiles2, describeRejection } = latest.current;
|
|
1769
1850
|
const describe = /* @__PURE__ */ __name((reason, file) => describeRejection?.(reason, file) ?? DEFAULT_REJECTION[reason](file), "describe");
|
|
1770
|
-
let room =
|
|
1851
|
+
let room = maxFiles2 === void 0 ? Number.POSITIVE_INFINITY : maxFiles2 - itemsRef.current.filter((item) => item.status !== "rejected").length;
|
|
1771
1852
|
const staged = [];
|
|
1772
1853
|
for (const file of Array.from(files)) {
|
|
1773
1854
|
sequence += 1;
|
|
@@ -1779,7 +1860,7 @@ function useAttachments(options = {}) {
|
|
|
1779
1860
|
type: file.type,
|
|
1780
1861
|
progress: 0
|
|
1781
1862
|
};
|
|
1782
|
-
const reason = !acceptsFile(accept2, file) ? "type" :
|
|
1863
|
+
const reason = !acceptsFile(accept2, file) ? "type" : maxBytes2 !== void 0 && file.size > maxBytes2 ? "size" : room <= 0 ? "count" : void 0;
|
|
1783
1864
|
if (reason !== void 0) {
|
|
1784
1865
|
staged.push({
|
|
1785
1866
|
...base,
|
|
@@ -1843,7 +1924,7 @@ function useAttachments(options = {}) {
|
|
|
1843
1924
|
}, [
|
|
1844
1925
|
start
|
|
1845
1926
|
]);
|
|
1846
|
-
|
|
1927
|
+
useEffect4(() => () => {
|
|
1847
1928
|
for (const item of itemsRef.current) release(item);
|
|
1848
1929
|
}, [
|
|
1849
1930
|
release
|
|
@@ -1878,11 +1959,10 @@ function useAttachments(options = {}) {
|
|
|
1878
1959
|
}), [
|
|
1879
1960
|
add
|
|
1880
1961
|
]);
|
|
1881
|
-
const accept = options.accept;
|
|
1882
1962
|
const inputProps = useMemo4(() => ({
|
|
1883
1963
|
type: "file",
|
|
1884
1964
|
accept: typeof accept === "string" ? accept : accept?.join(","),
|
|
1885
|
-
multiple:
|
|
1965
|
+
multiple: maxFiles === void 0 || maxFiles > 1,
|
|
1886
1966
|
onChange: /* @__PURE__ */ __name((event) => {
|
|
1887
1967
|
const input = event.currentTarget;
|
|
1888
1968
|
add(input.files);
|
|
@@ -1890,12 +1970,11 @@ function useAttachments(options = {}) {
|
|
|
1890
1970
|
}, "onChange")
|
|
1891
1971
|
}), [
|
|
1892
1972
|
accept,
|
|
1893
|
-
|
|
1973
|
+
maxFiles,
|
|
1894
1974
|
add
|
|
1895
1975
|
]);
|
|
1896
1976
|
return useMemo4(() => {
|
|
1897
1977
|
const ready = items.filter((item) => item.status === "ready" && item.attachment !== void 0);
|
|
1898
|
-
const attachments = ready.map((item) => item.attachment);
|
|
1899
1978
|
return {
|
|
1900
1979
|
items,
|
|
1901
1980
|
add,
|
|
@@ -1903,9 +1982,8 @@ function useAttachments(options = {}) {
|
|
|
1903
1982
|
retry,
|
|
1904
1983
|
clear,
|
|
1905
1984
|
isUploading: items.some((item) => item.status === "uploading"),
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
mediaId: attachment.mediaId
|
|
1985
|
+
refs: ready.map((item) => ({
|
|
1986
|
+
mediaId: item.attachment.mediaId
|
|
1909
1987
|
})),
|
|
1910
1988
|
inputProps,
|
|
1911
1989
|
dropZoneProps,
|
|
@@ -1930,13 +2008,13 @@ __name(useAttachments, "useAttachments");
|
|
|
1930
2008
|
import { useMemo as useMemo5 } from "react";
|
|
1931
2009
|
|
|
1932
2010
|
// src/catalog/use-resource.ts
|
|
1933
|
-
import { useCallback as useCallback3, useEffect as
|
|
1934
|
-
function useResource(
|
|
1935
|
-
const [data, setData] =
|
|
1936
|
-
const [isLoading, setIsLoading] =
|
|
1937
|
-
const [error, setError] =
|
|
1938
|
-
const loadRef = useRef4(
|
|
1939
|
-
loadRef.current =
|
|
2011
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef4, useState as useState5 } from "react";
|
|
2012
|
+
function useResource(load3, key, enabled) {
|
|
2013
|
+
const [data, setData] = useState5(void 0);
|
|
2014
|
+
const [isLoading, setIsLoading] = useState5(enabled);
|
|
2015
|
+
const [error, setError] = useState5(null);
|
|
2016
|
+
const loadRef = useRef4(load3);
|
|
2017
|
+
loadRef.current = load3;
|
|
1940
2018
|
const generation = useRef4(0);
|
|
1941
2019
|
const refresh = useCallback3(async () => {
|
|
1942
2020
|
const mine = ++generation.current;
|
|
@@ -1953,7 +2031,7 @@ function useResource(load2, key, enabled) {
|
|
|
1953
2031
|
if (mine === generation.current) setIsLoading(false);
|
|
1954
2032
|
}
|
|
1955
2033
|
}, []);
|
|
1956
|
-
|
|
2034
|
+
useEffect5(() => {
|
|
1957
2035
|
if (!enabled) return;
|
|
1958
2036
|
void refresh();
|
|
1959
2037
|
}, [
|
|
@@ -2029,7 +2107,7 @@ function useModels(options = {}) {
|
|
|
2029
2107
|
__name(useModels, "useModels");
|
|
2030
2108
|
|
|
2031
2109
|
// src/quota/use-quota.ts
|
|
2032
|
-
import { useEffect as
|
|
2110
|
+
import { useEffect as useEffect6, useMemo as useMemo7 } from "react";
|
|
2033
2111
|
|
|
2034
2112
|
// src/threads/threads-events.ts
|
|
2035
2113
|
var listeners = /* @__PURE__ */ new WeakMap();
|
|
@@ -2057,7 +2135,7 @@ function useQuota(options = {}) {
|
|
|
2057
2135
|
const { enabled = true, pollMs } = options;
|
|
2058
2136
|
const backend = useAgentBackend(options.backend);
|
|
2059
2137
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "getQuota")(), "", enabled);
|
|
2060
|
-
|
|
2138
|
+
useEffect6(() => {
|
|
2061
2139
|
if (!enabled) return;
|
|
2062
2140
|
return onThreadsEvent(backend, (event) => {
|
|
2063
2141
|
if (event.type === "changed") void refresh();
|
|
@@ -2067,7 +2145,7 @@ function useQuota(options = {}) {
|
|
|
2067
2145
|
enabled,
|
|
2068
2146
|
refresh
|
|
2069
2147
|
]);
|
|
2070
|
-
|
|
2148
|
+
useEffect6(() => {
|
|
2071
2149
|
if (!enabled || pollMs === void 0 || pollMs <= 0) return;
|
|
2072
2150
|
const timer = setInterval(() => void refresh(), pollMs);
|
|
2073
2151
|
return () => clearInterval(timer);
|
|
@@ -2098,7 +2176,7 @@ function useQuota(options = {}) {
|
|
|
2098
2176
|
__name(useQuota, "useQuota");
|
|
2099
2177
|
|
|
2100
2178
|
// src/feedback/use-message-feedback.ts
|
|
2101
|
-
import { useCallback as useCallback4, useRef as useRef5, useState as
|
|
2179
|
+
import { useCallback as useCallback4, useRef as useRef5, useState as useState6 } from "react";
|
|
2102
2180
|
function useMessageFeedback(options = {}) {
|
|
2103
2181
|
const backend = useAgentBackend(options.backend);
|
|
2104
2182
|
const latest = useRef5({
|
|
@@ -2109,9 +2187,9 @@ function useMessageFeedback(options = {}) {
|
|
|
2109
2187
|
...options,
|
|
2110
2188
|
backend
|
|
2111
2189
|
};
|
|
2112
|
-
const [local, setLocal] =
|
|
2113
|
-
const [pending, setPending] =
|
|
2114
|
-
const [error, setError] =
|
|
2190
|
+
const [local, setLocal] = useState6(/* @__PURE__ */ new Map());
|
|
2191
|
+
const [pending, setPending] = useState6(/* @__PURE__ */ new Set());
|
|
2192
|
+
const [error, setError] = useState6(null);
|
|
2115
2193
|
const localRef = useRef5(local);
|
|
2116
2194
|
localRef.current = local;
|
|
2117
2195
|
const resolved = useRef5(/* @__PURE__ */ new Map());
|
|
@@ -2214,13 +2292,13 @@ function metadataOf(message) {
|
|
|
2214
2292
|
__name(metadataOf, "metadataOf");
|
|
2215
2293
|
|
|
2216
2294
|
// src/threads/use-threads.ts
|
|
2217
|
-
import { useCallback as useCallback5, useEffect as
|
|
2295
|
+
import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef6, useState as useState7 } from "react";
|
|
2218
2296
|
function useThreads(options = {}) {
|
|
2219
2297
|
const { enabled = true } = options;
|
|
2220
2298
|
const backend = useAgentBackend(options.backend);
|
|
2221
|
-
const [threads, setThreads] =
|
|
2222
|
-
const [isLoading, setIsLoading] =
|
|
2223
|
-
const [error, setError] =
|
|
2299
|
+
const [threads, setThreads] = useState7([]);
|
|
2300
|
+
const [isLoading, setIsLoading] = useState7(enabled);
|
|
2301
|
+
const [error, setError] = useState7(null);
|
|
2224
2302
|
const threadsRef = useRef6(threads);
|
|
2225
2303
|
threadsRef.current = threads;
|
|
2226
2304
|
const generation = useRef6(0);
|
|
@@ -2241,7 +2319,7 @@ function useThreads(options = {}) {
|
|
|
2241
2319
|
}, [
|
|
2242
2320
|
backend
|
|
2243
2321
|
]);
|
|
2244
|
-
|
|
2322
|
+
useEffect7(() => {
|
|
2245
2323
|
if (!enabled) return;
|
|
2246
2324
|
void refresh();
|
|
2247
2325
|
return onThreadsEvent(backend, (event) => {
|
|
@@ -2358,10 +2436,10 @@ function backgroundRunsFromThread(messages) {
|
|
|
2358
2436
|
__name(backgroundRunsFromThread, "backgroundRunsFromThread");
|
|
2359
2437
|
|
|
2360
2438
|
// src/components/chat-input.tsx
|
|
2361
|
-
import React2, { useEffect as
|
|
2439
|
+
import React2, { useEffect as useEffect9, useState as useState9 } from "react";
|
|
2362
2440
|
|
|
2363
2441
|
// src/components/use-speech-recognition.ts
|
|
2364
|
-
import { useCallback as useCallback6, useEffect as
|
|
2442
|
+
import { useCallback as useCallback6, useEffect as useEffect8, useMemo as useMemo8, useRef as useRef7, useState as useState8 } from "react";
|
|
2365
2443
|
function getRecognitionCtor() {
|
|
2366
2444
|
if (typeof window === "undefined") return null;
|
|
2367
2445
|
const scope = window;
|
|
@@ -2370,14 +2448,14 @@ function getRecognitionCtor() {
|
|
|
2370
2448
|
__name(getRecognitionCtor, "getRecognitionCtor");
|
|
2371
2449
|
function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
|
|
2372
2450
|
const recognitionRef = useRef7(null);
|
|
2373
|
-
const [isListening, setIsListening] =
|
|
2451
|
+
const [isListening, setIsListening] = useState8(false);
|
|
2374
2452
|
const ctor = useMemo8(() => getRecognitionCtor(), []);
|
|
2375
2453
|
const isSupported = ctor !== null;
|
|
2376
2454
|
const finalRef = useRef7(onFinalTranscript);
|
|
2377
2455
|
const interimRef = useRef7(onInterimTranscript);
|
|
2378
2456
|
finalRef.current = onFinalTranscript;
|
|
2379
2457
|
interimRef.current = onInterimTranscript;
|
|
2380
|
-
|
|
2458
|
+
useEffect8(() => {
|
|
2381
2459
|
if (!ctor) return;
|
|
2382
2460
|
const recognition = new ctor();
|
|
2383
2461
|
recognition.lang = lang;
|
|
@@ -2445,8 +2523,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
|
|
|
2445
2523
|
|
|
2446
2524
|
// src/components/chat-input.tsx
|
|
2447
2525
|
function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = true, speechLang = "en-US", sendLabel = "Send", onStop, isStreaming = false, stopLabel = "Stop generating", className, textareaClassName, sendButtonClassName, micButtonClassName, stopButtonClassName, renderMic }) {
|
|
2448
|
-
const [value, setValue] =
|
|
2449
|
-
const [interim, setInterim] =
|
|
2526
|
+
const [value, setValue] = useState9("");
|
|
2527
|
+
const [interim, setInterim] = useState9("");
|
|
2450
2528
|
const speech = useSpeechRecognition({
|
|
2451
2529
|
lang: speechLang,
|
|
2452
2530
|
onFinalTranscript: /* @__PURE__ */ __name((text) => {
|
|
@@ -2457,7 +2535,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
2457
2535
|
}, "onFinalTranscript"),
|
|
2458
2536
|
onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
|
|
2459
2537
|
});
|
|
2460
|
-
|
|
2538
|
+
useEffect9(() => {
|
|
2461
2539
|
if (!speech.isListening) setInterim("");
|
|
2462
2540
|
}, [
|
|
2463
2541
|
speech.isListening
|
|
@@ -2524,7 +2602,7 @@ __name(ChatInput, "ChatInput");
|
|
|
2524
2602
|
import React3 from "react";
|
|
2525
2603
|
|
|
2526
2604
|
// src/transcript/use-chat-transcript.ts
|
|
2527
|
-
import { useCallback as useCallback8, useEffect as
|
|
2605
|
+
import { useCallback as useCallback8, useEffect as useEffect11, useRef as useRef9, useState as useState11 } from "react";
|
|
2528
2606
|
|
|
2529
2607
|
// src/transcript/model.ts
|
|
2530
2608
|
import { readElicitationInput, validateElicitationAnswer as validateElicitationAnswer2 } from "@dudousxd/nestjs-agent-core";
|
|
@@ -3501,10 +3579,10 @@ function formatCostUsd(cost) {
|
|
|
3501
3579
|
__name(formatCostUsd, "formatCostUsd");
|
|
3502
3580
|
|
|
3503
3581
|
// src/transcript/use-stick-to-bottom.ts
|
|
3504
|
-
import { useCallback as useCallback7, useEffect as
|
|
3582
|
+
import { useCallback as useCallback7, useEffect as useEffect10, useRef as useRef8, useState as useState10 } from "react";
|
|
3505
3583
|
function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
3506
3584
|
const containerRef = useRef8(null);
|
|
3507
|
-
const [isAtBottom, setIsAtBottom] =
|
|
3585
|
+
const [isAtBottom, setIsAtBottom] = useState10(true);
|
|
3508
3586
|
const measure = useCallback7(() => {
|
|
3509
3587
|
const element = containerRef.current;
|
|
3510
3588
|
if (!element) {
|
|
@@ -3531,7 +3609,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
3531
3609
|
}, [
|
|
3532
3610
|
measure
|
|
3533
3611
|
]);
|
|
3534
|
-
|
|
3612
|
+
useEffect10(() => {
|
|
3535
3613
|
if (isAtBottom) {
|
|
3536
3614
|
scrollToBottom();
|
|
3537
3615
|
}
|
|
@@ -3564,12 +3642,12 @@ function useChatTranscript(options) {
|
|
|
3564
3642
|
const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
|
|
3565
3643
|
const latest = useRef9(options);
|
|
3566
3644
|
latest.current = options;
|
|
3567
|
-
const [visibleCount, setVisibleCount] =
|
|
3568
|
-
const [stopRequested, setStopRequested] =
|
|
3645
|
+
const [visibleCount, setVisibleCount] = useState11(initialVisibleCount);
|
|
3646
|
+
const [stopRequested, setStopRequested] = useState11(false);
|
|
3569
3647
|
const isStreaming = status === "streaming" || status === "reconnecting";
|
|
3570
3648
|
const isBusy = status === "submitted" || isStreaming;
|
|
3571
3649
|
const isEmpty = messages.length === 0;
|
|
3572
|
-
|
|
3650
|
+
useEffect11(() => {
|
|
3573
3651
|
if (!isBusy) {
|
|
3574
3652
|
setStopRequested(false);
|
|
3575
3653
|
}
|
|
@@ -3649,12 +3727,12 @@ function useTranscriptItem(options) {
|
|
|
3649
3727
|
}
|
|
3650
3728
|
__name(useTranscriptItem, "useTranscriptItem");
|
|
3651
3729
|
function useTranscriptItems({ messages, visibleStart, streamingMessageId, options }) {
|
|
3652
|
-
const [drafts, setDrafts] =
|
|
3653
|
-
const [copied, setCopied] =
|
|
3654
|
-
const [openReasoning, setOpenReasoning] =
|
|
3655
|
-
const [picks, setPicks] =
|
|
3656
|
-
const [settling, setSettling] =
|
|
3657
|
-
const [settleErrors, setSettleErrors] =
|
|
3730
|
+
const [drafts, setDrafts] = useState11(() => /* @__PURE__ */ new Map());
|
|
3731
|
+
const [copied, setCopied] = useState11(() => /* @__PURE__ */ new Set());
|
|
3732
|
+
const [openReasoning, setOpenReasoning] = useState11(() => /* @__PURE__ */ new Map());
|
|
3733
|
+
const [picks, setPicks] = useState11(() => /* @__PURE__ */ new Map());
|
|
3734
|
+
const [settling, setSettling] = useState11(() => /* @__PURE__ */ new Map());
|
|
3735
|
+
const [settleErrors, setSettleErrors] = useState11(() => /* @__PURE__ */ new Map());
|
|
3658
3736
|
const backend = useAgentBackend();
|
|
3659
3737
|
const handlers = settleHandlers(options, backend);
|
|
3660
3738
|
const latest = useRef9({
|
|
@@ -3672,7 +3750,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3672
3750
|
messages
|
|
3673
3751
|
};
|
|
3674
3752
|
const copyTimers = useRef9(/* @__PURE__ */ new Map());
|
|
3675
|
-
|
|
3753
|
+
useEffect11(() => () => {
|
|
3676
3754
|
for (const timer of copyTimers.current.values()) {
|
|
3677
3755
|
clearTimeout(timer);
|
|
3678
3756
|
}
|
|
@@ -4476,18 +4554,18 @@ function toItem(entry) {
|
|
|
4476
4554
|
__name(toItem, "toItem");
|
|
4477
4555
|
|
|
4478
4556
|
// src/composer/use-composer-autocomplete.ts
|
|
4479
|
-
import { useCallback as useCallback9, useEffect as
|
|
4557
|
+
import { useCallback as useCallback9, useEffect as useEffect12, useId, useLayoutEffect, useMemo as useMemo9, useRef as useRef10, useState as useState12 } from "react";
|
|
4480
4558
|
function useComposerAutocomplete(options) {
|
|
4481
4559
|
const { value, sources, acceptOnTab = true } = options;
|
|
4482
4560
|
const latest = useRef10(options);
|
|
4483
4561
|
latest.current = options;
|
|
4484
4562
|
const inputRef = useRef10(null);
|
|
4485
|
-
const [caret, setCaret] =
|
|
4486
|
-
const [items, setItems] =
|
|
4487
|
-
const [isLoading, setLoading] =
|
|
4488
|
-
const [error, setError] =
|
|
4489
|
-
const [activeIndex, setActiveIndex] =
|
|
4490
|
-
const [dismissedIndex, setDismissedIndex] =
|
|
4563
|
+
const [caret, setCaret] = useState12(value.length);
|
|
4564
|
+
const [items, setItems] = useState12([]);
|
|
4565
|
+
const [isLoading, setLoading] = useState12(false);
|
|
4566
|
+
const [error, setError] = useState12(null);
|
|
4567
|
+
const [activeIndex, setActiveIndex] = useState12(0);
|
|
4568
|
+
const [dismissedIndex, setDismissedIndex] = useState12(null);
|
|
4491
4569
|
const safeCaret = Math.min(caret, value.length);
|
|
4492
4570
|
const match = useMemo9(() => findActiveTrigger(value, safeCaret, sources), [
|
|
4493
4571
|
value,
|
|
@@ -4504,7 +4582,7 @@ function useComposerAutocomplete(options) {
|
|
|
4504
4582
|
const activeIndexRef = useRef10(activeIndex);
|
|
4505
4583
|
activeIndexRef.current = activeIndex;
|
|
4506
4584
|
const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
|
|
4507
|
-
|
|
4585
|
+
useEffect12(() => {
|
|
4508
4586
|
const current = matchRef.current;
|
|
4509
4587
|
if (requestKey === null || current === null) {
|
|
4510
4588
|
setItems([]);
|
|
@@ -4714,13 +4792,13 @@ function isPromise(value) {
|
|
|
4714
4792
|
__name(isPromise, "isPromise");
|
|
4715
4793
|
|
|
4716
4794
|
// src/presentation/use-tool-catalog.ts
|
|
4717
|
-
import { useCallback as useCallback10, useEffect as
|
|
4718
|
-
var
|
|
4719
|
-
function
|
|
4720
|
-
let byAgent =
|
|
4795
|
+
import { useCallback as useCallback10, useEffect as useEffect13, useMemo as useMemo10, useState as useState13 } from "react";
|
|
4796
|
+
var shared2 = /* @__PURE__ */ new WeakMap();
|
|
4797
|
+
function load2(client, agent) {
|
|
4798
|
+
let byAgent = shared2.get(client);
|
|
4721
4799
|
if (byAgent === void 0) {
|
|
4722
4800
|
byAgent = /* @__PURE__ */ new Map();
|
|
4723
|
-
|
|
4801
|
+
shared2.set(client, byAgent);
|
|
4724
4802
|
}
|
|
4725
4803
|
const key = agent ?? "";
|
|
4726
4804
|
const cached = byAgent.get(key);
|
|
@@ -4735,22 +4813,22 @@ function load(client, agent) {
|
|
|
4735
4813
|
byAgent.set(key, request);
|
|
4736
4814
|
return request;
|
|
4737
4815
|
}
|
|
4738
|
-
__name(
|
|
4816
|
+
__name(load2, "load");
|
|
4739
4817
|
function useToolCatalog(options = {}) {
|
|
4740
4818
|
const { agent, enabled = true } = options;
|
|
4741
4819
|
const client = useAgentBackend(options.backend);
|
|
4742
|
-
const [entries, setEntries] =
|
|
4743
|
-
const [isLoading, setLoading] =
|
|
4744
|
-
const [error, setError] =
|
|
4745
|
-
const [generation, setGeneration] =
|
|
4746
|
-
|
|
4820
|
+
const [entries, setEntries] = useState13([]);
|
|
4821
|
+
const [isLoading, setLoading] = useState13(enabled);
|
|
4822
|
+
const [error, setError] = useState13(null);
|
|
4823
|
+
const [generation, setGeneration] = useState13(0);
|
|
4824
|
+
useEffect13(() => {
|
|
4747
4825
|
if (!enabled) {
|
|
4748
4826
|
setLoading(false);
|
|
4749
4827
|
return;
|
|
4750
4828
|
}
|
|
4751
4829
|
let cancelled = false;
|
|
4752
4830
|
setLoading(true);
|
|
4753
|
-
|
|
4831
|
+
load2(client, agent).then((loaded) => {
|
|
4754
4832
|
if (cancelled) return;
|
|
4755
4833
|
setEntries(Array.isArray(loaded) ? loaded : []);
|
|
4756
4834
|
setError(null);
|
|
@@ -4770,7 +4848,7 @@ function useToolCatalog(options = {}) {
|
|
|
4770
4848
|
generation
|
|
4771
4849
|
]);
|
|
4772
4850
|
const refresh = useCallback10(() => {
|
|
4773
|
-
|
|
4851
|
+
shared2.get(client)?.delete(agent ?? "");
|
|
4774
4852
|
setGeneration((current) => current + 1);
|
|
4775
4853
|
}, [
|
|
4776
4854
|
client,
|
|
@@ -4790,7 +4868,7 @@ function useToolCatalog(options = {}) {
|
|
|
4790
4868
|
__name(useToolCatalog, "useToolCatalog");
|
|
4791
4869
|
|
|
4792
4870
|
// src/approvals/countdown.ts
|
|
4793
|
-
import { useEffect as
|
|
4871
|
+
import { useEffect as useEffect14, useRef as useRef11, useState as useState14 } from "react";
|
|
4794
4872
|
function approvalCountdown(expiresAt, now = Date.now()) {
|
|
4795
4873
|
const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
|
|
4796
4874
|
if (!Number.isFinite(deadline)) {
|
|
@@ -4810,8 +4888,8 @@ function useApprovalCountdown(expiresAt, options = {}) {
|
|
|
4810
4888
|
const { intervalMs = 1e3 } = options;
|
|
4811
4889
|
const nowRef = useRef11(options.now ?? Date.now);
|
|
4812
4890
|
nowRef.current = options.now ?? Date.now;
|
|
4813
|
-
const [state, setState] =
|
|
4814
|
-
|
|
4891
|
+
const [state, setState] = useState14(() => approvalCountdown(expiresAt, nowRef.current()));
|
|
4892
|
+
useEffect14(() => {
|
|
4815
4893
|
const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
|
|
4816
4894
|
const first = read();
|
|
4817
4895
|
setState(first);
|
|
@@ -4947,13 +5025,19 @@ function storedMessageToUiMessage(message) {
|
|
|
4947
5025
|
for (const call of message.toolCalls ?? []) {
|
|
4948
5026
|
const result = message.toolResults?.find((candidate) => candidate.id === call.id);
|
|
4949
5027
|
const toolKind2 = call.kind;
|
|
5028
|
+
const toolMetadata = {
|
|
5029
|
+
...toolKind2 !== void 0 ? {
|
|
5030
|
+
toolKind: toolKind2
|
|
5031
|
+
} : {},
|
|
5032
|
+
...call.parentId !== void 0 ? {
|
|
5033
|
+
parentId: call.parentId
|
|
5034
|
+
} : {}
|
|
5035
|
+
};
|
|
4950
5036
|
parts.push({
|
|
4951
5037
|
type: `tool-${call.name}`,
|
|
4952
5038
|
toolCallId: call.id,
|
|
4953
|
-
...
|
|
4954
|
-
toolMetadata
|
|
4955
|
-
toolKind: toolKind2
|
|
4956
|
-
}
|
|
5039
|
+
...Object.keys(toolMetadata).length > 0 ? {
|
|
5040
|
+
toolMetadata
|
|
4957
5041
|
} : {},
|
|
4958
5042
|
...result !== void 0 ? isRefusal(result) ? {
|
|
4959
5043
|
// A declined action is NOT an available output. Reloading a thread used to bring one
|
|
@@ -4981,6 +5065,8 @@ function storedMessageToUiMessage(message) {
|
|
|
4981
5065
|
parts.push(...pushedByCall.get(call.id) ?? []);
|
|
4982
5066
|
}
|
|
4983
5067
|
const metadata = {
|
|
5068
|
+
// The host's own facts first: the library's keys win on a clash.
|
|
5069
|
+
...message.metadata,
|
|
4984
5070
|
...message.feedback !== void 0 ? {
|
|
4985
5071
|
feedback: message.feedback
|
|
4986
5072
|
} : {},
|
|
@@ -5040,6 +5126,8 @@ function mergeTurn(rows) {
|
|
|
5040
5126
|
const feedback = lastRow.feedback;
|
|
5041
5127
|
const createdAt = rows[0]?.createdAt;
|
|
5042
5128
|
const metadata = {
|
|
5129
|
+
// Host facts of every row, a later row's winning (the turn's final state), under the library's.
|
|
5130
|
+
...Object.assign({}, ...rows.map((row) => row.metadata ?? {})),
|
|
5043
5131
|
...usage !== void 0 ? {
|
|
5044
5132
|
usage
|
|
5045
5133
|
} : {},
|
|
@@ -5076,7 +5164,7 @@ __name(sumUsage, "sumUsage");
|
|
|
5076
5164
|
|
|
5077
5165
|
// src/use-agent-chat.ts
|
|
5078
5166
|
import { useChat } from "@ai-sdk/react";
|
|
5079
|
-
import { useCallback as useCallback11, useEffect as
|
|
5167
|
+
import { useCallback as useCallback11, useEffect as useEffect15, useMemo as useMemo11, useRef as useRef12, useState as useState15 } from "react";
|
|
5080
5168
|
var localChatSequence = 0;
|
|
5081
5169
|
function localChatId() {
|
|
5082
5170
|
localChatSequence += 1;
|
|
@@ -5100,22 +5188,22 @@ function useAgentChat(options = {}) {
|
|
|
5100
5188
|
}
|
|
5101
5189
|
}
|
|
5102
5190
|
const chatId = chatIdRef.current;
|
|
5103
|
-
const [runId, setRunId] =
|
|
5191
|
+
const [runId, setRunId] = useState15(options.resumeRunId);
|
|
5104
5192
|
const runIdRef = useRef12(runId);
|
|
5105
5193
|
runIdRef.current = runId;
|
|
5106
5194
|
const settlingRunIdRef = useRef12(void 0);
|
|
5107
5195
|
const autoResumeRunIdRef = useRef12(void 0);
|
|
5108
|
-
const [activeRunId, setActiveRunId] =
|
|
5109
|
-
const [isLoadingHistory, setIsLoadingHistory] =
|
|
5110
|
-
const [historyError, setHistoryError] =
|
|
5111
|
-
const [threadModel, setThreadModel] =
|
|
5112
|
-
const [pickedModel, setPickedModel] =
|
|
5196
|
+
const [activeRunId, setActiveRunId] = useState15(null);
|
|
5197
|
+
const [isLoadingHistory, setIsLoadingHistory] = useState15(false);
|
|
5198
|
+
const [historyError, setHistoryError] = useState15(null);
|
|
5199
|
+
const [threadModel, setThreadModel] = useState15(null);
|
|
5200
|
+
const [pickedModel, setPickedModel] = useState15(void 0);
|
|
5113
5201
|
const pickedModelRef = useRef12(pickedModel);
|
|
5114
5202
|
pickedModelRef.current = pickedModel;
|
|
5115
5203
|
const pendingPin = useRef12(void 0);
|
|
5116
5204
|
const regenerateNext = useRef12(false);
|
|
5117
5205
|
const currentThreadId = useCallback11(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
5118
|
-
const [connection, setConnection] =
|
|
5206
|
+
const [connection, setConnection] = useState15({
|
|
5119
5207
|
status: "live"
|
|
5120
5208
|
});
|
|
5121
5209
|
const resyncAfterSettle = useRef12(false);
|
|
@@ -5161,6 +5249,11 @@ function useAgentChat(options = {}) {
|
|
|
5161
5249
|
const threadId = currentThreadId();
|
|
5162
5250
|
const model = current.model ?? pickedModelRef.current;
|
|
5163
5251
|
return {
|
|
5252
|
+
// Read per send: a host that switches agents before the first message (a picker on a
|
|
5253
|
+
// new chat) sends the one picked now, not the one this chat mounted with.
|
|
5254
|
+
...current.agent !== void 0 ? {
|
|
5255
|
+
agent: current.agent
|
|
5256
|
+
} : {},
|
|
5164
5257
|
...threadId !== void 0 ? {
|
|
5165
5258
|
threadId
|
|
5166
5259
|
} : {},
|
|
@@ -5242,7 +5335,7 @@ function useAgentChat(options = {}) {
|
|
|
5242
5335
|
}
|
|
5243
5336
|
__name(resyncFromThread, "resyncFromThread");
|
|
5244
5337
|
const firstChatId = useRef12(chatId);
|
|
5245
|
-
|
|
5338
|
+
useEffect15(() => {
|
|
5246
5339
|
if (chatId === firstChatId.current) return;
|
|
5247
5340
|
firstChatId.current = chatId;
|
|
5248
5341
|
setRunId(void 0);
|
|
@@ -5255,7 +5348,7 @@ function useAgentChat(options = {}) {
|
|
|
5255
5348
|
}, [
|
|
5256
5349
|
chatId
|
|
5257
5350
|
]);
|
|
5258
|
-
|
|
5351
|
+
useEffect15(() => {
|
|
5259
5352
|
const threadId = options.threadId;
|
|
5260
5353
|
if (threadId === void 0) return;
|
|
5261
5354
|
if (threadId === createdThreadId.current) return;
|
|
@@ -5325,7 +5418,7 @@ function useAgentChat(options = {}) {
|
|
|
5325
5418
|
toolCallId,
|
|
5326
5419
|
output
|
|
5327
5420
|
}), []);
|
|
5328
|
-
const [backgroundRuns, setBackgroundRuns] =
|
|
5421
|
+
const [backgroundRuns, setBackgroundRuns] = useState15([]);
|
|
5329
5422
|
const refreshBackground = useCallback11(async () => {
|
|
5330
5423
|
const threadId = currentThreadId();
|
|
5331
5424
|
if (threadId === void 0) {
|
|
@@ -5352,7 +5445,7 @@ function useAgentChat(options = {}) {
|
|
|
5352
5445
|
]);
|
|
5353
5446
|
backgroundRef.current = refreshBackground;
|
|
5354
5447
|
const isWorking = backgroundRuns.some((run) => run.status === "running");
|
|
5355
|
-
|
|
5448
|
+
useEffect15(() => {
|
|
5356
5449
|
if (options.background !== true || options.threadId === void 0) {
|
|
5357
5450
|
return;
|
|
5358
5451
|
}
|
|
@@ -5363,7 +5456,7 @@ function useAgentChat(options = {}) {
|
|
|
5363
5456
|
chatId,
|
|
5364
5457
|
refreshBackground
|
|
5365
5458
|
]);
|
|
5366
|
-
|
|
5459
|
+
useEffect15(() => {
|
|
5367
5460
|
const every = latest.current.backgroundPollMs ?? 5e3;
|
|
5368
5461
|
if (latest.current.background !== true || !isWorking || every <= 0) {
|
|
5369
5462
|
return;
|
|
@@ -5489,7 +5582,7 @@ function useAgentChat(options = {}) {
|
|
|
5489
5582
|
client,
|
|
5490
5583
|
currentThreadId
|
|
5491
5584
|
]);
|
|
5492
|
-
const [modelsWanted, setModelsWanted] =
|
|
5585
|
+
const [modelsWanted, setModelsWanted] = useState15(false);
|
|
5493
5586
|
const modelsWantedRef = useRef12(modelsWanted);
|
|
5494
5587
|
modelsWantedRef.current = modelsWanted;
|
|
5495
5588
|
const catalog = useModels({
|
|
@@ -5534,6 +5627,10 @@ function useAgentChat(options = {}) {
|
|
|
5534
5627
|
return catalog.providers;
|
|
5535
5628
|
},
|
|
5536
5629
|
selected: options.model ?? pickedModel ?? threadModel ?? catalog.defaultModel ?? null,
|
|
5630
|
+
get defaultModel() {
|
|
5631
|
+
wantModels();
|
|
5632
|
+
return catalog.defaultModel;
|
|
5633
|
+
},
|
|
5537
5634
|
select: selectModel,
|
|
5538
5635
|
pinToThread,
|
|
5539
5636
|
isLoading: modelsWanted && catalog.isLoading,
|
|
@@ -5545,8 +5642,8 @@ function useAgentChat(options = {}) {
|
|
|
5545
5642
|
...options.composer,
|
|
5546
5643
|
backend: client
|
|
5547
5644
|
});
|
|
5548
|
-
const [text, setText] =
|
|
5549
|
-
const blockedBy = blocked != null ? "quota" : files.isUploading ? "uploading" : isBusy ? "busy" : text.trim().length === 0 && files.
|
|
5645
|
+
const [text, setText] = useState15("");
|
|
5646
|
+
const blockedBy = blocked != null ? "quota" : files.isUploading ? "uploading" : isBusy ? "busy" : text.trim().length === 0 && files.refs.length === 0 ? "empty" : null;
|
|
5550
5647
|
const composerRef = useRef12({
|
|
5551
5648
|
text,
|
|
5552
5649
|
files,
|
|
@@ -5561,10 +5658,26 @@ function useAgentChat(options = {}) {
|
|
|
5561
5658
|
const current = composerRef.current;
|
|
5562
5659
|
if (current.blockedBy !== null) return;
|
|
5563
5660
|
const refs = current.files.refs;
|
|
5661
|
+
const files2 = current.files.items.flatMap((item) => item.status === "ready" && item.attachment !== void 0 ? [
|
|
5662
|
+
{
|
|
5663
|
+
type: "file",
|
|
5664
|
+
mediaType: item.attachment.contentType,
|
|
5665
|
+
filename: item.attachment.name,
|
|
5666
|
+
url: item.attachment.url,
|
|
5667
|
+
providerMetadata: {
|
|
5668
|
+
agent: {
|
|
5669
|
+
mediaId: item.attachment.mediaId
|
|
5670
|
+
}
|
|
5671
|
+
}
|
|
5672
|
+
}
|
|
5673
|
+
] : []);
|
|
5564
5674
|
const draft = current.text.trim();
|
|
5565
5675
|
setText("");
|
|
5566
5676
|
current.files.clear();
|
|
5567
|
-
await sendMessage({
|
|
5677
|
+
await sendMessage(files2.length > 0 ? {
|
|
5678
|
+
text: draft,
|
|
5679
|
+
files: files2
|
|
5680
|
+
} : {
|
|
5568
5681
|
text: draft
|
|
5569
5682
|
}, refs.length > 0 ? {
|
|
5570
5683
|
body: {
|
|
@@ -5722,6 +5835,7 @@ export {
|
|
|
5722
5835
|
toolCatalogFrom,
|
|
5723
5836
|
useAgentBackend,
|
|
5724
5837
|
useAgentChat,
|
|
5838
|
+
useAgentConfig,
|
|
5725
5839
|
useAgents,
|
|
5726
5840
|
useAmbientRenderUi,
|
|
5727
5841
|
useApprovalCountdown,
|