@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.cjs
CHANGED
|
@@ -83,6 +83,7 @@ __export(src_exports, {
|
|
|
83
83
|
toolCatalogFrom: () => toolCatalogFrom,
|
|
84
84
|
useAgentBackend: () => useAgentBackend,
|
|
85
85
|
useAgentChat: () => useAgentChat,
|
|
86
|
+
useAgentConfig: () => useAgentConfig,
|
|
86
87
|
useAgents: () => useAgents,
|
|
87
88
|
useAmbientRenderUi: () => useAmbientRenderUi,
|
|
88
89
|
useApprovalCountdown: () => useApprovalCountdown,
|
|
@@ -305,6 +306,10 @@ var AgentClient = class {
|
|
|
305
306
|
listAgents() {
|
|
306
307
|
return this.request("GET", "/agents");
|
|
307
308
|
}
|
|
309
|
+
/** `GET <path>/config` — attachment limits and upload mode, and which features are on. */
|
|
310
|
+
getConfig() {
|
|
311
|
+
return this.request("GET", "/config");
|
|
312
|
+
}
|
|
308
313
|
/** `GET <path>/quota` — the caller's budget windows and the one blocking sends, if any. */
|
|
309
314
|
getQuota() {
|
|
310
315
|
return this.request("GET", "/quota");
|
|
@@ -962,6 +967,13 @@ var AgentChatTransport = class {
|
|
|
962
967
|
}
|
|
963
968
|
});
|
|
964
969
|
break;
|
|
970
|
+
case "message-metadata":
|
|
971
|
+
ensureStarted();
|
|
972
|
+
controller.enqueue({
|
|
973
|
+
type: "message-metadata",
|
|
974
|
+
messageMetadata: event.metadata
|
|
975
|
+
});
|
|
976
|
+
break;
|
|
965
977
|
case "title":
|
|
966
978
|
case "cancelled":
|
|
967
979
|
forwardAsData(event, true);
|
|
@@ -1215,7 +1227,7 @@ function dragHasFiles(data) {
|
|
|
1215
1227
|
__name(dragHasFiles, "dragHasFiles");
|
|
1216
1228
|
|
|
1217
1229
|
// src/attachments/use-attachments.ts
|
|
1218
|
-
var
|
|
1230
|
+
var import_react7 = require("react");
|
|
1219
1231
|
|
|
1220
1232
|
// src/backend.ts
|
|
1221
1233
|
var AgentBackendUnsupportedError = class extends Error {
|
|
@@ -1237,6 +1249,9 @@ function requireBackendMethod(backend, name) {
|
|
|
1237
1249
|
}
|
|
1238
1250
|
__name(requireBackendMethod, "requireBackendMethod");
|
|
1239
1251
|
|
|
1252
|
+
// src/config/use-agent-config.ts
|
|
1253
|
+
var import_react6 = require("react");
|
|
1254
|
+
|
|
1240
1255
|
// src/provider.tsx
|
|
1241
1256
|
var import_react5 = require("react");
|
|
1242
1257
|
|
|
@@ -1801,6 +1816,59 @@ function useAgentBackend(own) {
|
|
|
1801
1816
|
}
|
|
1802
1817
|
__name(useAgentBackend, "useAgentBackend");
|
|
1803
1818
|
|
|
1819
|
+
// src/config/use-agent-config.ts
|
|
1820
|
+
var shared = /* @__PURE__ */ new WeakMap();
|
|
1821
|
+
function load(backend) {
|
|
1822
|
+
const getConfig = backend.getConfig;
|
|
1823
|
+
if (typeof getConfig !== "function") return void 0;
|
|
1824
|
+
let pending = shared.get(backend);
|
|
1825
|
+
if (pending === void 0) {
|
|
1826
|
+
pending = getConfig.call(backend).catch((error) => {
|
|
1827
|
+
shared.delete(backend);
|
|
1828
|
+
throw error;
|
|
1829
|
+
});
|
|
1830
|
+
shared.set(backend, pending);
|
|
1831
|
+
}
|
|
1832
|
+
return pending;
|
|
1833
|
+
}
|
|
1834
|
+
__name(load, "load");
|
|
1835
|
+
function useAgentConfig(options = {}) {
|
|
1836
|
+
const backend = useAgentBackend(options.backend);
|
|
1837
|
+
const enabled = options.enabled !== false;
|
|
1838
|
+
const [config, setConfig] = (0, import_react6.useState)(void 0);
|
|
1839
|
+
const [isLoading, setLoading] = (0, import_react6.useState)(false);
|
|
1840
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
1841
|
+
(0, import_react6.useEffect)(() => {
|
|
1842
|
+
if (!enabled) return;
|
|
1843
|
+
const pending = load(backend);
|
|
1844
|
+
if (pending === void 0) return;
|
|
1845
|
+
let cancelled = false;
|
|
1846
|
+
setLoading(true);
|
|
1847
|
+
pending.then((loaded) => {
|
|
1848
|
+
if (cancelled) return;
|
|
1849
|
+
setConfig(loaded !== null && typeof loaded === "object" ? loaded : void 0);
|
|
1850
|
+
setError(null);
|
|
1851
|
+
setLoading(false);
|
|
1852
|
+
}, (failure) => {
|
|
1853
|
+
if (cancelled) return;
|
|
1854
|
+
setError(failure instanceof Error ? failure : new Error(String(failure)));
|
|
1855
|
+
setLoading(false);
|
|
1856
|
+
});
|
|
1857
|
+
return () => {
|
|
1858
|
+
cancelled = true;
|
|
1859
|
+
};
|
|
1860
|
+
}, [
|
|
1861
|
+
backend,
|
|
1862
|
+
enabled
|
|
1863
|
+
]);
|
|
1864
|
+
return {
|
|
1865
|
+
config,
|
|
1866
|
+
isLoading,
|
|
1867
|
+
error
|
|
1868
|
+
};
|
|
1869
|
+
}
|
|
1870
|
+
__name(useAgentConfig, "useAgentConfig");
|
|
1871
|
+
|
|
1804
1872
|
// src/attachments/use-attachments.ts
|
|
1805
1873
|
var DEFAULT_REJECTION = {
|
|
1806
1874
|
type: /* @__PURE__ */ __name((file) => `${file.name} is not a supported file type`, "type"),
|
|
@@ -1810,26 +1878,40 @@ var DEFAULT_REJECTION = {
|
|
|
1810
1878
|
var sequence = 0;
|
|
1811
1879
|
function useAttachments(options = {}) {
|
|
1812
1880
|
const backend = useAgentBackend(options.backend);
|
|
1813
|
-
const
|
|
1814
|
-
...options,
|
|
1881
|
+
const { config } = useAgentConfig({
|
|
1815
1882
|
backend
|
|
1816
1883
|
});
|
|
1817
|
-
|
|
1884
|
+
const limits = config?.attachments;
|
|
1885
|
+
const accept = options.accept ?? limits?.allowedContentTypes;
|
|
1886
|
+
const maxBytes = options.maxBytes ?? limits?.maxBytes;
|
|
1887
|
+
const maxFiles = options.maxFiles ?? limits?.maxPerMessage;
|
|
1888
|
+
const effective = {
|
|
1818
1889
|
...options,
|
|
1819
|
-
backend
|
|
1890
|
+
backend,
|
|
1891
|
+
...accept !== void 0 ? {
|
|
1892
|
+
accept
|
|
1893
|
+
} : {},
|
|
1894
|
+
...maxBytes !== void 0 ? {
|
|
1895
|
+
maxBytes
|
|
1896
|
+
} : {},
|
|
1897
|
+
...maxFiles !== void 0 ? {
|
|
1898
|
+
maxFiles
|
|
1899
|
+
} : {}
|
|
1820
1900
|
};
|
|
1821
|
-
const
|
|
1822
|
-
|
|
1901
|
+
const latest = (0, import_react7.useRef)(effective);
|
|
1902
|
+
latest.current = effective;
|
|
1903
|
+
const [items, setItems] = (0, import_react7.useState)([]);
|
|
1904
|
+
const itemsRef = (0, import_react7.useRef)(items);
|
|
1823
1905
|
itemsRef.current = items;
|
|
1824
|
-
const controllers = (0,
|
|
1825
|
-
const [dragDepth, setDragDepth] = (0,
|
|
1826
|
-
const patch = (0,
|
|
1906
|
+
const controllers = (0, import_react7.useRef)(/* @__PURE__ */ new Map());
|
|
1907
|
+
const [dragDepth, setDragDepth] = (0, import_react7.useState)(0);
|
|
1908
|
+
const patch = (0, import_react7.useCallback)((id, change) => {
|
|
1827
1909
|
setItems((current) => current.map((item) => item.id === id ? {
|
|
1828
1910
|
...item,
|
|
1829
1911
|
...change
|
|
1830
1912
|
} : item));
|
|
1831
1913
|
}, []);
|
|
1832
|
-
const start = (0,
|
|
1914
|
+
const start = (0, import_react7.useCallback)((item) => {
|
|
1833
1915
|
const { upload, backend: backend2 } = latest.current;
|
|
1834
1916
|
const run = upload ?? (backend2.uploadAttachment !== void 0 ? backend2.uploadAttachment.bind(backend2) : void 0);
|
|
1835
1917
|
if (run === void 0) {
|
|
@@ -1865,11 +1947,11 @@ function useAttachments(options = {}) {
|
|
|
1865
1947
|
}, [
|
|
1866
1948
|
patch
|
|
1867
1949
|
]);
|
|
1868
|
-
const add = (0,
|
|
1950
|
+
const add = (0, import_react7.useCallback)((files) => {
|
|
1869
1951
|
if (files == null) return;
|
|
1870
|
-
const { accept: accept2, maxBytes, maxFiles, describeRejection } = latest.current;
|
|
1952
|
+
const { accept: accept2, maxBytes: maxBytes2, maxFiles: maxFiles2, describeRejection } = latest.current;
|
|
1871
1953
|
const describe = /* @__PURE__ */ __name((reason, file) => describeRejection?.(reason, file) ?? DEFAULT_REJECTION[reason](file), "describe");
|
|
1872
|
-
let room =
|
|
1954
|
+
let room = maxFiles2 === void 0 ? Number.POSITIVE_INFINITY : maxFiles2 - itemsRef.current.filter((item) => item.status !== "rejected").length;
|
|
1873
1955
|
const staged = [];
|
|
1874
1956
|
for (const file of Array.from(files)) {
|
|
1875
1957
|
sequence += 1;
|
|
@@ -1881,7 +1963,7 @@ function useAttachments(options = {}) {
|
|
|
1881
1963
|
type: file.type,
|
|
1882
1964
|
progress: 0
|
|
1883
1965
|
};
|
|
1884
|
-
const reason = !acceptsFile(accept2, file) ? "type" :
|
|
1966
|
+
const reason = !acceptsFile(accept2, file) ? "type" : maxBytes2 !== void 0 && file.size > maxBytes2 ? "size" : room <= 0 ? "count" : void 0;
|
|
1885
1967
|
if (reason !== void 0) {
|
|
1886
1968
|
staged.push({
|
|
1887
1969
|
...base,
|
|
@@ -1911,7 +1993,7 @@ function useAttachments(options = {}) {
|
|
|
1911
1993
|
}, [
|
|
1912
1994
|
start
|
|
1913
1995
|
]);
|
|
1914
|
-
const release = (0,
|
|
1996
|
+
const release = (0, import_react7.useCallback)((item) => {
|
|
1915
1997
|
if (item === void 0) return;
|
|
1916
1998
|
controllers.current.get(item.id)?.abort();
|
|
1917
1999
|
controllers.current.delete(item.id);
|
|
@@ -1919,19 +2001,19 @@ function useAttachments(options = {}) {
|
|
|
1919
2001
|
URL.revokeObjectURL(item.previewUrl);
|
|
1920
2002
|
}
|
|
1921
2003
|
}, []);
|
|
1922
|
-
const remove = (0,
|
|
2004
|
+
const remove = (0, import_react7.useCallback)((id) => {
|
|
1923
2005
|
release(itemsRef.current.find((item) => item.id === id));
|
|
1924
2006
|
setItems((current) => current.filter((item) => item.id !== id));
|
|
1925
2007
|
}, [
|
|
1926
2008
|
release
|
|
1927
2009
|
]);
|
|
1928
|
-
const clear = (0,
|
|
2010
|
+
const clear = (0, import_react7.useCallback)(() => {
|
|
1929
2011
|
for (const item of itemsRef.current) release(item);
|
|
1930
2012
|
setItems([]);
|
|
1931
2013
|
}, [
|
|
1932
2014
|
release
|
|
1933
2015
|
]);
|
|
1934
|
-
const retry = (0,
|
|
2016
|
+
const retry = (0, import_react7.useCallback)((id) => {
|
|
1935
2017
|
const item = itemsRef.current.find((candidate) => candidate.id === id);
|
|
1936
2018
|
if (item === void 0 || item.status !== "error") return;
|
|
1937
2019
|
const { error: _previous, ...rest } = item;
|
|
@@ -1945,12 +2027,12 @@ function useAttachments(options = {}) {
|
|
|
1945
2027
|
}, [
|
|
1946
2028
|
start
|
|
1947
2029
|
]);
|
|
1948
|
-
(0,
|
|
2030
|
+
(0, import_react7.useEffect)(() => () => {
|
|
1949
2031
|
for (const item of itemsRef.current) release(item);
|
|
1950
2032
|
}, [
|
|
1951
2033
|
release
|
|
1952
2034
|
]);
|
|
1953
|
-
const onPaste = (0,
|
|
2035
|
+
const onPaste = (0, import_react7.useCallback)((event) => {
|
|
1954
2036
|
const files = filesFromClipboard(event.clipboardData);
|
|
1955
2037
|
if (files.length === 0) return;
|
|
1956
2038
|
event.preventDefault();
|
|
@@ -1958,7 +2040,7 @@ function useAttachments(options = {}) {
|
|
|
1958
2040
|
}, [
|
|
1959
2041
|
add
|
|
1960
2042
|
]);
|
|
1961
|
-
const dropZoneProps = (0,
|
|
2043
|
+
const dropZoneProps = (0, import_react7.useMemo)(() => ({
|
|
1962
2044
|
onDragEnter: /* @__PURE__ */ __name((event) => {
|
|
1963
2045
|
if (!dragHasFiles(event.dataTransfer)) return;
|
|
1964
2046
|
event.preventDefault();
|
|
@@ -1980,11 +2062,10 @@ function useAttachments(options = {}) {
|
|
|
1980
2062
|
}), [
|
|
1981
2063
|
add
|
|
1982
2064
|
]);
|
|
1983
|
-
const
|
|
1984
|
-
const inputProps = (0, import_react6.useMemo)(() => ({
|
|
2065
|
+
const inputProps = (0, import_react7.useMemo)(() => ({
|
|
1985
2066
|
type: "file",
|
|
1986
2067
|
accept: typeof accept === "string" ? accept : accept?.join(","),
|
|
1987
|
-
multiple:
|
|
2068
|
+
multiple: maxFiles === void 0 || maxFiles > 1,
|
|
1988
2069
|
onChange: /* @__PURE__ */ __name((event) => {
|
|
1989
2070
|
const input = event.currentTarget;
|
|
1990
2071
|
add(input.files);
|
|
@@ -1992,12 +2073,11 @@ function useAttachments(options = {}) {
|
|
|
1992
2073
|
}, "onChange")
|
|
1993
2074
|
}), [
|
|
1994
2075
|
accept,
|
|
1995
|
-
|
|
2076
|
+
maxFiles,
|
|
1996
2077
|
add
|
|
1997
2078
|
]);
|
|
1998
|
-
return (0,
|
|
2079
|
+
return (0, import_react7.useMemo)(() => {
|
|
1999
2080
|
const ready = items.filter((item) => item.status === "ready" && item.attachment !== void 0);
|
|
2000
|
-
const attachments = ready.map((item) => item.attachment);
|
|
2001
2081
|
return {
|
|
2002
2082
|
items,
|
|
2003
2083
|
add,
|
|
@@ -2005,9 +2085,8 @@ function useAttachments(options = {}) {
|
|
|
2005
2085
|
retry,
|
|
2006
2086
|
clear,
|
|
2007
2087
|
isUploading: items.some((item) => item.status === "uploading"),
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
mediaId: attachment.mediaId
|
|
2088
|
+
refs: ready.map((item) => ({
|
|
2089
|
+
mediaId: item.attachment.mediaId
|
|
2011
2090
|
})),
|
|
2012
2091
|
inputProps,
|
|
2013
2092
|
dropZoneProps,
|
|
@@ -2029,18 +2108,18 @@ function useAttachments(options = {}) {
|
|
|
2029
2108
|
__name(useAttachments, "useAttachments");
|
|
2030
2109
|
|
|
2031
2110
|
// src/catalog/use-agents.ts
|
|
2032
|
-
var
|
|
2111
|
+
var import_react9 = require("react");
|
|
2033
2112
|
|
|
2034
2113
|
// src/catalog/use-resource.ts
|
|
2035
|
-
var
|
|
2036
|
-
function useResource(
|
|
2037
|
-
const [data, setData] = (0,
|
|
2038
|
-
const [isLoading, setIsLoading] = (0,
|
|
2039
|
-
const [error, setError] = (0,
|
|
2040
|
-
const loadRef = (0,
|
|
2041
|
-
loadRef.current =
|
|
2042
|
-
const generation = (0,
|
|
2043
|
-
const refresh = (0,
|
|
2114
|
+
var import_react8 = require("react");
|
|
2115
|
+
function useResource(load3, key, enabled) {
|
|
2116
|
+
const [data, setData] = (0, import_react8.useState)(void 0);
|
|
2117
|
+
const [isLoading, setIsLoading] = (0, import_react8.useState)(enabled);
|
|
2118
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
2119
|
+
const loadRef = (0, import_react8.useRef)(load3);
|
|
2120
|
+
loadRef.current = load3;
|
|
2121
|
+
const generation = (0, import_react8.useRef)(0);
|
|
2122
|
+
const refresh = (0, import_react8.useCallback)(async () => {
|
|
2044
2123
|
const mine = ++generation.current;
|
|
2045
2124
|
setIsLoading(true);
|
|
2046
2125
|
try {
|
|
@@ -2055,7 +2134,7 @@ function useResource(load2, key, enabled) {
|
|
|
2055
2134
|
if (mine === generation.current) setIsLoading(false);
|
|
2056
2135
|
}
|
|
2057
2136
|
}, []);
|
|
2058
|
-
(0,
|
|
2137
|
+
(0, import_react8.useEffect)(() => {
|
|
2059
2138
|
if (!enabled) return;
|
|
2060
2139
|
void refresh();
|
|
2061
2140
|
}, [
|
|
@@ -2077,7 +2156,7 @@ function useAgents(options = {}) {
|
|
|
2077
2156
|
const { enabled = true } = options;
|
|
2078
2157
|
const backend = useAgentBackend(options.backend);
|
|
2079
2158
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listAgents")(), "", enabled);
|
|
2080
|
-
return (0,
|
|
2159
|
+
return (0, import_react9.useMemo)(() => {
|
|
2081
2160
|
const agents = data ?? [];
|
|
2082
2161
|
return {
|
|
2083
2162
|
agents,
|
|
@@ -2096,12 +2175,12 @@ function useAgents(options = {}) {
|
|
|
2096
2175
|
__name(useAgents, "useAgents");
|
|
2097
2176
|
|
|
2098
2177
|
// src/catalog/use-models.ts
|
|
2099
|
-
var
|
|
2178
|
+
var import_react10 = require("react");
|
|
2100
2179
|
function useModels(options = {}) {
|
|
2101
2180
|
const { agent, enabled = true } = options;
|
|
2102
2181
|
const backend = useAgentBackend(options.backend);
|
|
2103
2182
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listModels")(agent), `${agent ?? ""}`, enabled);
|
|
2104
|
-
return (0,
|
|
2183
|
+
return (0, import_react10.useMemo)(() => {
|
|
2105
2184
|
const providers = data?.providers ?? [];
|
|
2106
2185
|
const models = providers.flatMap((provider) => provider.models.map((model) => ({
|
|
2107
2186
|
...model,
|
|
@@ -2131,7 +2210,7 @@ function useModels(options = {}) {
|
|
|
2131
2210
|
__name(useModels, "useModels");
|
|
2132
2211
|
|
|
2133
2212
|
// src/quota/use-quota.ts
|
|
2134
|
-
var
|
|
2213
|
+
var import_react11 = require("react");
|
|
2135
2214
|
|
|
2136
2215
|
// src/threads/threads-events.ts
|
|
2137
2216
|
var listeners = /* @__PURE__ */ new WeakMap();
|
|
@@ -2159,7 +2238,7 @@ function useQuota(options = {}) {
|
|
|
2159
2238
|
const { enabled = true, pollMs } = options;
|
|
2160
2239
|
const backend = useAgentBackend(options.backend);
|
|
2161
2240
|
const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "getQuota")(), "", enabled);
|
|
2162
|
-
(0,
|
|
2241
|
+
(0, import_react11.useEffect)(() => {
|
|
2163
2242
|
if (!enabled) return;
|
|
2164
2243
|
return onThreadsEvent(backend, (event) => {
|
|
2165
2244
|
if (event.type === "changed") void refresh();
|
|
@@ -2169,7 +2248,7 @@ function useQuota(options = {}) {
|
|
|
2169
2248
|
enabled,
|
|
2170
2249
|
refresh
|
|
2171
2250
|
]);
|
|
2172
|
-
(0,
|
|
2251
|
+
(0, import_react11.useEffect)(() => {
|
|
2173
2252
|
if (!enabled || pollMs === void 0 || pollMs <= 0) return;
|
|
2174
2253
|
const timer = setInterval(() => void refresh(), pollMs);
|
|
2175
2254
|
return () => clearInterval(timer);
|
|
@@ -2178,7 +2257,7 @@ function useQuota(options = {}) {
|
|
|
2178
2257
|
pollMs,
|
|
2179
2258
|
refresh
|
|
2180
2259
|
]);
|
|
2181
|
-
return (0,
|
|
2260
|
+
return (0, import_react11.useMemo)(() => {
|
|
2182
2261
|
const windows = data?.windows ?? [];
|
|
2183
2262
|
return {
|
|
2184
2263
|
report: data,
|
|
@@ -2200,10 +2279,10 @@ function useQuota(options = {}) {
|
|
|
2200
2279
|
__name(useQuota, "useQuota");
|
|
2201
2280
|
|
|
2202
2281
|
// src/feedback/use-message-feedback.ts
|
|
2203
|
-
var
|
|
2282
|
+
var import_react12 = require("react");
|
|
2204
2283
|
function useMessageFeedback(options = {}) {
|
|
2205
2284
|
const backend = useAgentBackend(options.backend);
|
|
2206
|
-
const latest = (0,
|
|
2285
|
+
const latest = (0, import_react12.useRef)({
|
|
2207
2286
|
...options,
|
|
2208
2287
|
backend
|
|
2209
2288
|
});
|
|
@@ -2211,23 +2290,23 @@ function useMessageFeedback(options = {}) {
|
|
|
2211
2290
|
...options,
|
|
2212
2291
|
backend
|
|
2213
2292
|
};
|
|
2214
|
-
const [local, setLocal] = (0,
|
|
2215
|
-
const [pending, setPending] = (0,
|
|
2216
|
-
const [error, setError] = (0,
|
|
2217
|
-
const localRef = (0,
|
|
2293
|
+
const [local, setLocal] = (0, import_react12.useState)(/* @__PURE__ */ new Map());
|
|
2294
|
+
const [pending, setPending] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
|
|
2295
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
2296
|
+
const localRef = (0, import_react12.useRef)(local);
|
|
2218
2297
|
localRef.current = local;
|
|
2219
|
-
const resolved = (0,
|
|
2220
|
-
const feedbackOf = (0,
|
|
2298
|
+
const resolved = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
|
|
2299
|
+
const feedbackOf = (0, import_react12.useCallback)((message) => {
|
|
2221
2300
|
const mine = local.get(message.id);
|
|
2222
2301
|
if (mine !== void 0) return mine.feedback;
|
|
2223
2302
|
return metadataOf(message).feedback ?? null;
|
|
2224
2303
|
}, [
|
|
2225
2304
|
local
|
|
2226
2305
|
]);
|
|
2227
|
-
const isPending = (0,
|
|
2306
|
+
const isPending = (0, import_react12.useCallback)((message) => pending.has(message.id), [
|
|
2228
2307
|
pending
|
|
2229
2308
|
]);
|
|
2230
|
-
const storedIdFor = (0,
|
|
2309
|
+
const storedIdFor = (0, import_react12.useCallback)(async (message) => {
|
|
2231
2310
|
const runId = metadataOf(message).runId;
|
|
2232
2311
|
if (runId === void 0) return message.id;
|
|
2233
2312
|
const known = resolved.current.get(message.id);
|
|
@@ -2247,7 +2326,7 @@ function useMessageFeedback(options = {}) {
|
|
|
2247
2326
|
resolved.current.set(message.id, row.id);
|
|
2248
2327
|
return row.id;
|
|
2249
2328
|
}, []);
|
|
2250
|
-
const rate = (0,
|
|
2329
|
+
const rate = (0, import_react12.useCallback)(async (message, value, comment) => {
|
|
2251
2330
|
const setFeedback = requireBackendMethod(latest.current.backend, "setMessageFeedback");
|
|
2252
2331
|
const had = localRef.current.get(message.id);
|
|
2253
2332
|
const optimistic = value === null ? null : {
|
|
@@ -2293,7 +2372,7 @@ function useMessageFeedback(options = {}) {
|
|
|
2293
2372
|
}, [
|
|
2294
2373
|
storedIdFor
|
|
2295
2374
|
]);
|
|
2296
|
-
const toggle = (0,
|
|
2375
|
+
const toggle = (0, import_react12.useCallback)((message, value) => {
|
|
2297
2376
|
const mine = localRef.current.get(message.id);
|
|
2298
2377
|
const current = mine !== void 0 ? mine.feedback : metadataOf(message).feedback ?? null;
|
|
2299
2378
|
return rate(message, current?.value === value ? null : value);
|
|
@@ -2316,17 +2395,17 @@ function metadataOf(message) {
|
|
|
2316
2395
|
__name(metadataOf, "metadataOf");
|
|
2317
2396
|
|
|
2318
2397
|
// src/threads/use-threads.ts
|
|
2319
|
-
var
|
|
2398
|
+
var import_react13 = require("react");
|
|
2320
2399
|
function useThreads(options = {}) {
|
|
2321
2400
|
const { enabled = true } = options;
|
|
2322
2401
|
const backend = useAgentBackend(options.backend);
|
|
2323
|
-
const [threads, setThreads] = (0,
|
|
2324
|
-
const [isLoading, setIsLoading] = (0,
|
|
2325
|
-
const [error, setError] = (0,
|
|
2326
|
-
const threadsRef = (0,
|
|
2402
|
+
const [threads, setThreads] = (0, import_react13.useState)([]);
|
|
2403
|
+
const [isLoading, setIsLoading] = (0, import_react13.useState)(enabled);
|
|
2404
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
2405
|
+
const threadsRef = (0, import_react13.useRef)(threads);
|
|
2327
2406
|
threadsRef.current = threads;
|
|
2328
|
-
const generation = (0,
|
|
2329
|
-
const refresh = (0,
|
|
2407
|
+
const generation = (0, import_react13.useRef)(0);
|
|
2408
|
+
const refresh = (0, import_react13.useCallback)(async () => {
|
|
2330
2409
|
const mine = ++generation.current;
|
|
2331
2410
|
setIsLoading(true);
|
|
2332
2411
|
try {
|
|
@@ -2343,7 +2422,7 @@ function useThreads(options = {}) {
|
|
|
2343
2422
|
}, [
|
|
2344
2423
|
backend
|
|
2345
2424
|
]);
|
|
2346
|
-
(0,
|
|
2425
|
+
(0, import_react13.useEffect)(() => {
|
|
2347
2426
|
if (!enabled) return;
|
|
2348
2427
|
void refresh();
|
|
2349
2428
|
return onThreadsEvent(backend, (event) => {
|
|
@@ -2363,7 +2442,7 @@ function useThreads(options = {}) {
|
|
|
2363
2442
|
enabled,
|
|
2364
2443
|
refresh
|
|
2365
2444
|
]);
|
|
2366
|
-
const rename = (0,
|
|
2445
|
+
const rename = (0, import_react13.useCallback)(async (id, title) => {
|
|
2367
2446
|
const before = threadsRef.current;
|
|
2368
2447
|
setThreads((current) => current.map((thread) => thread.id === id ? {
|
|
2369
2448
|
...thread,
|
|
@@ -2385,7 +2464,7 @@ function useThreads(options = {}) {
|
|
|
2385
2464
|
}, [
|
|
2386
2465
|
backend
|
|
2387
2466
|
]);
|
|
2388
|
-
const remove = (0,
|
|
2467
|
+
const remove = (0, import_react13.useCallback)(async (id) => {
|
|
2389
2468
|
const before = threadsRef.current;
|
|
2390
2469
|
setThreads((current) => current.filter((thread) => thread.id !== id));
|
|
2391
2470
|
try {
|
|
@@ -2460,10 +2539,10 @@ function backgroundRunsFromThread(messages) {
|
|
|
2460
2539
|
__name(backgroundRunsFromThread, "backgroundRunsFromThread");
|
|
2461
2540
|
|
|
2462
2541
|
// src/components/chat-input.tsx
|
|
2463
|
-
var
|
|
2542
|
+
var import_react15 = __toESM(require("react"), 1);
|
|
2464
2543
|
|
|
2465
2544
|
// src/components/use-speech-recognition.ts
|
|
2466
|
-
var
|
|
2545
|
+
var import_react14 = require("react");
|
|
2467
2546
|
function getRecognitionCtor() {
|
|
2468
2547
|
if (typeof window === "undefined") return null;
|
|
2469
2548
|
const scope = window;
|
|
@@ -2471,15 +2550,15 @@ function getRecognitionCtor() {
|
|
|
2471
2550
|
}
|
|
2472
2551
|
__name(getRecognitionCtor, "getRecognitionCtor");
|
|
2473
2552
|
function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
|
|
2474
|
-
const recognitionRef = (0,
|
|
2475
|
-
const [isListening, setIsListening] = (0,
|
|
2476
|
-
const ctor = (0,
|
|
2553
|
+
const recognitionRef = (0, import_react14.useRef)(null);
|
|
2554
|
+
const [isListening, setIsListening] = (0, import_react14.useState)(false);
|
|
2555
|
+
const ctor = (0, import_react14.useMemo)(() => getRecognitionCtor(), []);
|
|
2477
2556
|
const isSupported = ctor !== null;
|
|
2478
|
-
const finalRef = (0,
|
|
2479
|
-
const interimRef = (0,
|
|
2557
|
+
const finalRef = (0, import_react14.useRef)(onFinalTranscript);
|
|
2558
|
+
const interimRef = (0, import_react14.useRef)(onInterimTranscript);
|
|
2480
2559
|
finalRef.current = onFinalTranscript;
|
|
2481
2560
|
interimRef.current = onInterimTranscript;
|
|
2482
|
-
(0,
|
|
2561
|
+
(0, import_react14.useEffect)(() => {
|
|
2483
2562
|
if (!ctor) return;
|
|
2484
2563
|
const recognition = new ctor();
|
|
2485
2564
|
recognition.lang = lang;
|
|
@@ -2518,7 +2597,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
2518
2597
|
ctor,
|
|
2519
2598
|
lang
|
|
2520
2599
|
]);
|
|
2521
|
-
const start = (0,
|
|
2600
|
+
const start = (0, import_react14.useCallback)(() => {
|
|
2522
2601
|
const recognition = recognitionRef.current;
|
|
2523
2602
|
if (!recognition) return;
|
|
2524
2603
|
try {
|
|
@@ -2528,7 +2607,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
|
|
|
2528
2607
|
console.warn("SpeechRecognition start failed", error);
|
|
2529
2608
|
}
|
|
2530
2609
|
}, []);
|
|
2531
|
-
const stop = (0,
|
|
2610
|
+
const stop = (0, import_react14.useCallback)(() => {
|
|
2532
2611
|
const recognition = recognitionRef.current;
|
|
2533
2612
|
if (!recognition) return;
|
|
2534
2613
|
try {
|
|
@@ -2547,8 +2626,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
|
|
|
2547
2626
|
|
|
2548
2627
|
// src/components/chat-input.tsx
|
|
2549
2628
|
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 }) {
|
|
2550
|
-
const [value, setValue] = (0,
|
|
2551
|
-
const [interim, setInterim] = (0,
|
|
2629
|
+
const [value, setValue] = (0, import_react15.useState)("");
|
|
2630
|
+
const [interim, setInterim] = (0, import_react15.useState)("");
|
|
2552
2631
|
const speech = useSpeechRecognition({
|
|
2553
2632
|
lang: speechLang,
|
|
2554
2633
|
onFinalTranscript: /* @__PURE__ */ __name((text) => {
|
|
@@ -2559,7 +2638,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
2559
2638
|
}, "onFinalTranscript"),
|
|
2560
2639
|
onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
|
|
2561
2640
|
});
|
|
2562
|
-
(0,
|
|
2641
|
+
(0, import_react15.useEffect)(() => {
|
|
2563
2642
|
if (!speech.isListening) setInterim("");
|
|
2564
2643
|
}, [
|
|
2565
2644
|
speech.isListening
|
|
@@ -2587,9 +2666,9 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
2587
2666
|
const displayValue = speech.isListening && interim ? `${value}${value && !value.endsWith(" ") ? " " : ""}${interim}` : value;
|
|
2588
2667
|
const showMic = enableSpeech && speech.isSupported;
|
|
2589
2668
|
const showStop = isStreaming && onStop !== void 0;
|
|
2590
|
-
return /* @__PURE__ */
|
|
2669
|
+
return /* @__PURE__ */ import_react15.default.createElement("div", {
|
|
2591
2670
|
className
|
|
2592
|
-
}, /* @__PURE__ */
|
|
2671
|
+
}, /* @__PURE__ */ import_react15.default.createElement("textarea", {
|
|
2593
2672
|
className: textareaClassName,
|
|
2594
2673
|
rows,
|
|
2595
2674
|
value: displayValue,
|
|
@@ -2600,17 +2679,17 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
2600
2679
|
}, "onChange"),
|
|
2601
2680
|
onKeyDown: handleKeyDown,
|
|
2602
2681
|
placeholder: placeholder ?? "Ask something (Enter to send, Shift+Enter for newline)"
|
|
2603
|
-
}), /* @__PURE__ */
|
|
2682
|
+
}), /* @__PURE__ */ import_react15.default.createElement("button", {
|
|
2604
2683
|
type: "button",
|
|
2605
2684
|
className: sendButtonClassName,
|
|
2606
2685
|
onClick: submit,
|
|
2607
2686
|
disabled: disabled || !value.trim()
|
|
2608
|
-
}, sendLabel), showStop ? /* @__PURE__ */
|
|
2687
|
+
}, sendLabel), showStop ? /* @__PURE__ */ import_react15.default.createElement("button", {
|
|
2609
2688
|
type: "button",
|
|
2610
2689
|
className: stopButtonClassName,
|
|
2611
2690
|
onClick: /* @__PURE__ */ __name(() => void onStop(), "onClick"),
|
|
2612
2691
|
"aria-label": "Stop generating"
|
|
2613
|
-
}, stopLabel) : null, showMic ? /* @__PURE__ */
|
|
2692
|
+
}, stopLabel) : null, showMic ? /* @__PURE__ */ import_react15.default.createElement("button", {
|
|
2614
2693
|
type: "button",
|
|
2615
2694
|
className: micButtonClassName,
|
|
2616
2695
|
onClick: toggleMic,
|
|
@@ -2623,10 +2702,10 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
2623
2702
|
__name(ChatInput, "ChatInput");
|
|
2624
2703
|
|
|
2625
2704
|
// src/components/message-item.tsx
|
|
2626
|
-
var
|
|
2705
|
+
var import_react18 = __toESM(require("react"), 1);
|
|
2627
2706
|
|
|
2628
2707
|
// src/transcript/use-chat-transcript.ts
|
|
2629
|
-
var
|
|
2708
|
+
var import_react17 = require("react");
|
|
2630
2709
|
|
|
2631
2710
|
// src/transcript/model.ts
|
|
2632
2711
|
var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
|
|
@@ -3603,11 +3682,11 @@ function formatCostUsd(cost) {
|
|
|
3603
3682
|
__name(formatCostUsd, "formatCostUsd");
|
|
3604
3683
|
|
|
3605
3684
|
// src/transcript/use-stick-to-bottom.ts
|
|
3606
|
-
var
|
|
3685
|
+
var import_react16 = require("react");
|
|
3607
3686
|
function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
3608
|
-
const containerRef = (0,
|
|
3609
|
-
const [isAtBottom, setIsAtBottom] = (0,
|
|
3610
|
-
const measure = (0,
|
|
3687
|
+
const containerRef = (0, import_react16.useRef)(null);
|
|
3688
|
+
const [isAtBottom, setIsAtBottom] = (0, import_react16.useState)(true);
|
|
3689
|
+
const measure = (0, import_react16.useCallback)(() => {
|
|
3611
3690
|
const element = containerRef.current;
|
|
3612
3691
|
if (!element) {
|
|
3613
3692
|
return;
|
|
@@ -3617,7 +3696,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
3617
3696
|
}, [
|
|
3618
3697
|
threshold
|
|
3619
3698
|
]);
|
|
3620
|
-
const scrollToBottom = (0,
|
|
3699
|
+
const scrollToBottom = (0, import_react16.useCallback)(() => {
|
|
3621
3700
|
const element = containerRef.current;
|
|
3622
3701
|
if (!element) {
|
|
3623
3702
|
return;
|
|
@@ -3625,7 +3704,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
3625
3704
|
element.scrollTop = element.scrollHeight;
|
|
3626
3705
|
setIsAtBottom(true);
|
|
3627
3706
|
}, []);
|
|
3628
|
-
const setContainer = (0,
|
|
3707
|
+
const setContainer = (0, import_react16.useCallback)((element) => {
|
|
3629
3708
|
containerRef.current = element;
|
|
3630
3709
|
if (element) {
|
|
3631
3710
|
measure();
|
|
@@ -3633,7 +3712,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
3633
3712
|
}, [
|
|
3634
3713
|
measure
|
|
3635
3714
|
]);
|
|
3636
|
-
(0,
|
|
3715
|
+
(0, import_react16.useEffect)(() => {
|
|
3637
3716
|
if (isAtBottom) {
|
|
3638
3717
|
scrollToBottom();
|
|
3639
3718
|
}
|
|
@@ -3642,7 +3721,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
3642
3721
|
isAtBottom,
|
|
3643
3722
|
scrollToBottom
|
|
3644
3723
|
]);
|
|
3645
|
-
const getContainerProps = (0,
|
|
3724
|
+
const getContainerProps = (0, import_react16.useCallback)(() => ({
|
|
3646
3725
|
ref: setContainer,
|
|
3647
3726
|
onScroll: measure
|
|
3648
3727
|
}), [
|
|
@@ -3664,14 +3743,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
|
|
|
3664
3743
|
var DEFAULT_COPY_RESET_MS = 1500;
|
|
3665
3744
|
function useChatTranscript(options) {
|
|
3666
3745
|
const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
|
|
3667
|
-
const latest = (0,
|
|
3746
|
+
const latest = (0, import_react17.useRef)(options);
|
|
3668
3747
|
latest.current = options;
|
|
3669
|
-
const [visibleCount, setVisibleCount] = (0,
|
|
3670
|
-
const [stopRequested, setStopRequested] = (0,
|
|
3748
|
+
const [visibleCount, setVisibleCount] = (0, import_react17.useState)(initialVisibleCount);
|
|
3749
|
+
const [stopRequested, setStopRequested] = (0, import_react17.useState)(false);
|
|
3671
3750
|
const isStreaming = status === "streaming" || status === "reconnecting";
|
|
3672
3751
|
const isBusy = status === "submitted" || isStreaming;
|
|
3673
3752
|
const isEmpty = messages.length === 0;
|
|
3674
|
-
(0,
|
|
3753
|
+
(0, import_react17.useEffect)(() => {
|
|
3675
3754
|
if (!isBusy) {
|
|
3676
3755
|
setStopRequested(false);
|
|
3677
3756
|
}
|
|
@@ -3688,7 +3767,7 @@ function useChatTranscript(options) {
|
|
|
3688
3767
|
streamingMessageId,
|
|
3689
3768
|
options
|
|
3690
3769
|
});
|
|
3691
|
-
const stop = (0,
|
|
3770
|
+
const stop = (0, import_react17.useCallback)(() => {
|
|
3692
3771
|
const current = latest.current;
|
|
3693
3772
|
if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
|
|
3694
3773
|
return;
|
|
@@ -3696,8 +3775,8 @@ function useChatTranscript(options) {
|
|
|
3696
3775
|
setStopRequested(true);
|
|
3697
3776
|
void current.onStop?.();
|
|
3698
3777
|
}, []);
|
|
3699
|
-
const loadEarlier = (0,
|
|
3700
|
-
const showAll = (0,
|
|
3778
|
+
const loadEarlier = (0, import_react17.useCallback)(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
|
|
3779
|
+
const showAll = (0, import_react17.useCallback)(() => setVisibleCount(latest.current.messages.length), []);
|
|
3701
3780
|
const scroll = useStickToBottom({
|
|
3702
3781
|
contentKey: contentSignature(messages),
|
|
3703
3782
|
...stickToBottomThreshold !== void 0 ? {
|
|
@@ -3733,7 +3812,7 @@ function useChatTranscript(options) {
|
|
|
3733
3812
|
__name(useChatTranscript, "useChatTranscript");
|
|
3734
3813
|
function useTranscriptItem(options) {
|
|
3735
3814
|
const { message, isStreaming = false } = options;
|
|
3736
|
-
const messagesRef = (0,
|
|
3815
|
+
const messagesRef = (0, import_react17.useRef)([
|
|
3737
3816
|
message
|
|
3738
3817
|
]);
|
|
3739
3818
|
if (messagesRef.current[0] !== message) {
|
|
@@ -3751,15 +3830,15 @@ function useTranscriptItem(options) {
|
|
|
3751
3830
|
}
|
|
3752
3831
|
__name(useTranscriptItem, "useTranscriptItem");
|
|
3753
3832
|
function useTranscriptItems({ messages, visibleStart, streamingMessageId, options }) {
|
|
3754
|
-
const [drafts, setDrafts] = (0,
|
|
3755
|
-
const [copied, setCopied] = (0,
|
|
3756
|
-
const [openReasoning, setOpenReasoning] = (0,
|
|
3757
|
-
const [picks, setPicks] = (0,
|
|
3758
|
-
const [settling, setSettling] = (0,
|
|
3759
|
-
const [settleErrors, setSettleErrors] = (0,
|
|
3833
|
+
const [drafts, setDrafts] = (0, import_react17.useState)(() => /* @__PURE__ */ new Map());
|
|
3834
|
+
const [copied, setCopied] = (0, import_react17.useState)(() => /* @__PURE__ */ new Set());
|
|
3835
|
+
const [openReasoning, setOpenReasoning] = (0, import_react17.useState)(() => /* @__PURE__ */ new Map());
|
|
3836
|
+
const [picks, setPicks] = (0, import_react17.useState)(() => /* @__PURE__ */ new Map());
|
|
3837
|
+
const [settling, setSettling] = (0, import_react17.useState)(() => /* @__PURE__ */ new Map());
|
|
3838
|
+
const [settleErrors, setSettleErrors] = (0, import_react17.useState)(() => /* @__PURE__ */ new Map());
|
|
3760
3839
|
const backend = useAgentBackend();
|
|
3761
3840
|
const handlers = settleHandlers(options, backend);
|
|
3762
|
-
const latest = (0,
|
|
3841
|
+
const latest = (0, import_react17.useRef)({
|
|
3763
3842
|
options,
|
|
3764
3843
|
handlers,
|
|
3765
3844
|
drafts,
|
|
@@ -3773,23 +3852,23 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3773
3852
|
picks,
|
|
3774
3853
|
messages
|
|
3775
3854
|
};
|
|
3776
|
-
const copyTimers = (0,
|
|
3777
|
-
(0,
|
|
3855
|
+
const copyTimers = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
|
|
3856
|
+
(0, import_react17.useEffect)(() => () => {
|
|
3778
3857
|
for (const timer of copyTimers.current.values()) {
|
|
3779
3858
|
clearTimeout(timer);
|
|
3780
3859
|
}
|
|
3781
3860
|
copyTimers.current.clear();
|
|
3782
3861
|
}, []);
|
|
3783
|
-
const callbackCache = (0,
|
|
3784
|
-
const reasoningToggleCache = (0,
|
|
3785
|
-
const toggleReasoning = (0,
|
|
3862
|
+
const callbackCache = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
|
|
3863
|
+
const reasoningToggleCache = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
|
|
3864
|
+
const toggleReasoning = (0, import_react17.useCallback)((key, open) => {
|
|
3786
3865
|
setOpenReasoning((current) => {
|
|
3787
3866
|
const next = new Map(current);
|
|
3788
3867
|
next.set(key, open ?? !(current.get(key) ?? false));
|
|
3789
3868
|
return next;
|
|
3790
3869
|
});
|
|
3791
3870
|
}, []);
|
|
3792
|
-
const stableToggle = (0,
|
|
3871
|
+
const stableToggle = (0, import_react17.useCallback)((key) => {
|
|
3793
3872
|
let cached = reasoningToggleCache.current.get(key);
|
|
3794
3873
|
if (!cached) {
|
|
3795
3874
|
cached = /* @__PURE__ */ __name((open) => toggleReasoning(key, open), "cached");
|
|
@@ -3799,10 +3878,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3799
3878
|
}, [
|
|
3800
3879
|
toggleReasoning
|
|
3801
3880
|
]);
|
|
3802
|
-
const pick = (0,
|
|
3881
|
+
const pick = (0, import_react17.useCallback)((toolCallId, questionId, values) => {
|
|
3803
3882
|
setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
|
|
3804
3883
|
}, []);
|
|
3805
|
-
const settle = (0,
|
|
3884
|
+
const settle = (0, import_react17.useCallback)((toolCallId, action, send) => {
|
|
3806
3885
|
setSettleErrors((current) => {
|
|
3807
3886
|
if (!current.has(toolCallId)) {
|
|
3808
3887
|
return current;
|
|
@@ -3826,7 +3905,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3826
3905
|
failed(error);
|
|
3827
3906
|
}
|
|
3828
3907
|
}, []);
|
|
3829
|
-
const answer = (0,
|
|
3908
|
+
const answer = (0, import_react17.useCallback)((toolCallId) => {
|
|
3830
3909
|
const current = latest.current;
|
|
3831
3910
|
const onAnswer = current.handlers.onAnswer;
|
|
3832
3911
|
if (!onAnswer) {
|
|
@@ -3839,7 +3918,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3839
3918
|
}, [
|
|
3840
3919
|
settle
|
|
3841
3920
|
]);
|
|
3842
|
-
const skip = (0,
|
|
3921
|
+
const skip = (0, import_react17.useCallback)((toolCallId) => {
|
|
3843
3922
|
const onSkip = latest.current.handlers.onSkip;
|
|
3844
3923
|
if (onSkip) {
|
|
3845
3924
|
settle(toolCallId, "skip", () => onSkip({
|
|
@@ -3849,7 +3928,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3849
3928
|
}, [
|
|
3850
3929
|
settle
|
|
3851
3930
|
]);
|
|
3852
|
-
const approve = (0,
|
|
3931
|
+
const approve = (0, import_react17.useCallback)((toolCallId, options2) => {
|
|
3853
3932
|
const onApprove = latest.current.handlers.onApprove;
|
|
3854
3933
|
if (onApprove) {
|
|
3855
3934
|
settle(toolCallId, "approve", () => onApprove({
|
|
@@ -3862,7 +3941,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3862
3941
|
}, [
|
|
3863
3942
|
settle
|
|
3864
3943
|
]);
|
|
3865
|
-
const reject = (0,
|
|
3944
|
+
const reject = (0, import_react17.useCallback)((toolCallId) => {
|
|
3866
3945
|
const onReject = latest.current.handlers.onReject;
|
|
3867
3946
|
if (onReject) {
|
|
3868
3947
|
settle(toolCallId, "reject", () => onReject({
|
|
@@ -3872,7 +3951,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
3872
3951
|
}, [
|
|
3873
3952
|
settle
|
|
3874
3953
|
]);
|
|
3875
|
-
const callbacksFor = (0,
|
|
3954
|
+
const callbacksFor = (0, import_react17.useCallback)((id) => {
|
|
3876
3955
|
const cached = callbackCache.current.get(id);
|
|
3877
3956
|
if (cached) {
|
|
3878
3957
|
return cached;
|
|
@@ -4158,7 +4237,7 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
|
|
|
4158
4237
|
getCreatedAt: /* @__PURE__ */ __name(() => createdAt, "getCreatedAt")
|
|
4159
4238
|
} : {}
|
|
4160
4239
|
});
|
|
4161
|
-
return /* @__PURE__ */
|
|
4240
|
+
return /* @__PURE__ */ import_react18.default.createElement(MessageItemView, {
|
|
4162
4241
|
item,
|
|
4163
4242
|
...slots
|
|
4164
4243
|
});
|
|
@@ -4171,51 +4250,51 @@ function MessageItemView({ item, ...given }) {
|
|
|
4171
4250
|
renderUi: ambientRenderUi
|
|
4172
4251
|
} : given;
|
|
4173
4252
|
const { classNames } = slots;
|
|
4174
|
-
const actionRow = /* @__PURE__ */
|
|
4253
|
+
const actionRow = /* @__PURE__ */ import_react18.default.createElement("div", {
|
|
4175
4254
|
className: classNames?.actions,
|
|
4176
4255
|
"data-actions-for": item.role
|
|
4177
|
-
}, item.copy.available ? /* @__PURE__ */
|
|
4256
|
+
}, item.copy.available ? /* @__PURE__ */ import_react18.default.createElement("button", {
|
|
4178
4257
|
type: "button",
|
|
4179
4258
|
onClick: item.copy.copy,
|
|
4180
4259
|
className: classNames?.actionButton,
|
|
4181
4260
|
title: item.copy.copied ? "Copied!" : "Copy message text"
|
|
4182
|
-
}, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */
|
|
4261
|
+
}, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */ import_react18.default.createElement("button", {
|
|
4183
4262
|
type: "button",
|
|
4184
4263
|
onClick: item.fork.run,
|
|
4185
4264
|
className: classNames?.actionButton,
|
|
4186
4265
|
title: "Fork thread from this message"
|
|
4187
|
-
}, "Fork") : null, item.regenerate.available ? /* @__PURE__ */
|
|
4266
|
+
}, "Fork") : null, item.regenerate.available ? /* @__PURE__ */ import_react18.default.createElement("button", {
|
|
4188
4267
|
type: "button",
|
|
4189
4268
|
onClick: item.regenerate.run,
|
|
4190
4269
|
className: classNames?.actionButton,
|
|
4191
4270
|
title: "Regenerate response"
|
|
4192
|
-
}, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */
|
|
4271
|
+
}, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */ import_react18.default.createElement("span", {
|
|
4193
4272
|
className: classNames?.usage,
|
|
4194
4273
|
title: `Input ${item.usage.inputTokens.toLocaleString()} \xB7 Output ${item.usage.outputTokens.toLocaleString()} tokens`
|
|
4195
|
-
}, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */
|
|
4274
|
+
}, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */ import_react18.default.createElement("span", {
|
|
4196
4275
|
className: classNames?.timestamp,
|
|
4197
4276
|
title: item.timestamp.absolute
|
|
4198
4277
|
}, item.timestamp.relative) : null);
|
|
4199
4278
|
if (item.edit.available) {
|
|
4200
|
-
return /* @__PURE__ */
|
|
4279
|
+
return /* @__PURE__ */ import_react18.default.createElement(EditableUserBubble, {
|
|
4201
4280
|
item,
|
|
4202
4281
|
slots,
|
|
4203
4282
|
actions: actionRow
|
|
4204
4283
|
});
|
|
4205
4284
|
}
|
|
4206
4285
|
const className = joinClasses(classNames?.root, classNames?.byRole?.[item.role]);
|
|
4207
|
-
return /* @__PURE__ */
|
|
4286
|
+
return /* @__PURE__ */ import_react18.default.createElement("div", {
|
|
4208
4287
|
className,
|
|
4209
4288
|
"data-role": item.role,
|
|
4210
4289
|
"data-streaming": item.isStreaming ? "true" : void 0
|
|
4211
|
-
}, /* @__PURE__ */
|
|
4290
|
+
}, /* @__PURE__ */ import_react18.default.createElement("div", null, renderBlocks(item, slots)), actionRow);
|
|
4212
4291
|
}
|
|
4213
4292
|
__name(MessageItemView, "MessageItemView");
|
|
4214
4293
|
function renderBlocks(item, slots) {
|
|
4215
4294
|
const nodes = [];
|
|
4216
4295
|
for (const block of item.blocks) {
|
|
4217
4296
|
if (block.kind === "text") {
|
|
4218
|
-
nodes.push(/* @__PURE__ */
|
|
4297
|
+
nodes.push(/* @__PURE__ */ import_react18.default.createElement("div", {
|
|
4219
4298
|
key: block.key,
|
|
4220
4299
|
className: slots.classNames?.text
|
|
4221
4300
|
}, slots.renderText ? slots.renderText(block.text, {
|
|
@@ -4236,7 +4315,7 @@ function renderBlocks(item, slots) {
|
|
|
4236
4315
|
continue;
|
|
4237
4316
|
}
|
|
4238
4317
|
if (block.kind === "ui" && slots.renderUi) {
|
|
4239
|
-
nodes.push(/* @__PURE__ */
|
|
4318
|
+
nodes.push(/* @__PURE__ */ import_react18.default.createElement("div", {
|
|
4240
4319
|
key: block.key,
|
|
4241
4320
|
"data-slot": "ui",
|
|
4242
4321
|
"data-component": block.component
|
|
@@ -4247,18 +4326,18 @@ function renderBlocks(item, slots) {
|
|
|
4247
4326
|
}
|
|
4248
4327
|
__name(renderBlocks, "renderBlocks");
|
|
4249
4328
|
function renderFilesBlock(block, slots) {
|
|
4250
|
-
return /* @__PURE__ */
|
|
4329
|
+
return /* @__PURE__ */ import_react18.default.createElement("div", {
|
|
4251
4330
|
key: block.key,
|
|
4252
4331
|
className: slots.classNames?.files,
|
|
4253
4332
|
"data-files": "true"
|
|
4254
|
-
}, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */
|
|
4333
|
+
}, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */ import_react18.default.createElement("a", {
|
|
4255
4334
|
key: file.url,
|
|
4256
4335
|
href: file.url,
|
|
4257
4336
|
target: "_blank",
|
|
4258
4337
|
rel: "noreferrer",
|
|
4259
4338
|
className: slots.classNames?.file,
|
|
4260
4339
|
title: file.filename ?? file.mediaType
|
|
4261
|
-
}, file.isImage ? /* @__PURE__ */
|
|
4340
|
+
}, file.isImage ? /* @__PURE__ */ import_react18.default.createElement("img", {
|
|
4262
4341
|
src: file.url,
|
|
4263
4342
|
alt: file.filename ?? "image",
|
|
4264
4343
|
className: slots.classNames?.fileImage
|
|
@@ -4266,17 +4345,17 @@ function renderFilesBlock(block, slots) {
|
|
|
4266
4345
|
}
|
|
4267
4346
|
__name(renderFilesBlock, "renderFilesBlock");
|
|
4268
4347
|
function renderReasoningBlock(block, slots) {
|
|
4269
|
-
return /* @__PURE__ */
|
|
4348
|
+
return /* @__PURE__ */ import_react18.default.createElement("div", {
|
|
4270
4349
|
key: block.key,
|
|
4271
4350
|
className: slots.classNames?.reasoning,
|
|
4272
4351
|
"data-reasoning": "true",
|
|
4273
4352
|
"data-streaming": block.isStreaming ? "true" : void 0
|
|
4274
|
-
}, /* @__PURE__ */
|
|
4353
|
+
}, /* @__PURE__ */ import_react18.default.createElement("button", {
|
|
4275
4354
|
type: "button",
|
|
4276
4355
|
className: slots.classNames?.reasoningToggle,
|
|
4277
4356
|
onClick: /* @__PURE__ */ __name(() => block.toggle(), "onClick"),
|
|
4278
4357
|
"aria-expanded": block.isOpen
|
|
4279
|
-
}, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */
|
|
4358
|
+
}, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */ import_react18.default.createElement("div", {
|
|
4280
4359
|
className: slots.classNames?.reasoningText
|
|
4281
4360
|
}, slots.renderReasoning ? slots.renderReasoning(block.text, {
|
|
4282
4361
|
isStreaming: block.isStreaming,
|
|
@@ -4287,7 +4366,7 @@ __name(renderReasoningBlock, "renderReasoningBlock");
|
|
|
4287
4366
|
function renderToolBlock(item, block, slots) {
|
|
4288
4367
|
if (slots.renderToolGroup) {
|
|
4289
4368
|
return [
|
|
4290
|
-
/* @__PURE__ */
|
|
4369
|
+
/* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, {
|
|
4291
4370
|
key: block.key
|
|
4292
4371
|
}, slots.renderToolGroup(block.parts, block.key))
|
|
4293
4372
|
];
|
|
@@ -4298,7 +4377,7 @@ function renderToolBlock(item, block, slots) {
|
|
|
4298
4377
|
const renderToolPart = slots.renderToolPart;
|
|
4299
4378
|
return block.parts.map((part) => {
|
|
4300
4379
|
const partKey = `${item.id}-${part.toolCallId}`;
|
|
4301
|
-
return /* @__PURE__ */
|
|
4380
|
+
return /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, {
|
|
4302
4381
|
key: partKey
|
|
4303
4382
|
}, renderToolPart(part, partKey));
|
|
4304
4383
|
});
|
|
@@ -4308,14 +4387,14 @@ function EditableUserBubble({ item, slots, actions }) {
|
|
|
4308
4387
|
const { classNames } = slots;
|
|
4309
4388
|
const { edit } = item;
|
|
4310
4389
|
if (!edit.isEditing) {
|
|
4311
|
-
return /* @__PURE__ */
|
|
4390
|
+
return /* @__PURE__ */ import_react18.default.createElement("div", {
|
|
4312
4391
|
className: joinClasses(classNames?.root, classNames?.byRole?.user),
|
|
4313
4392
|
"data-role": "user"
|
|
4314
|
-
}, /* @__PURE__ */
|
|
4393
|
+
}, /* @__PURE__ */ import_react18.default.createElement("div", {
|
|
4315
4394
|
className: classNames?.text
|
|
4316
4395
|
}, slots.renderText ? slots.renderText(item.text, {
|
|
4317
4396
|
isStreaming: false
|
|
4318
|
-
}) : item.text), /* @__PURE__ */
|
|
4397
|
+
}) : item.text), /* @__PURE__ */ import_react18.default.createElement("button", {
|
|
4319
4398
|
type: "button",
|
|
4320
4399
|
onClick: edit.start,
|
|
4321
4400
|
className: classNames?.actionButton,
|
|
@@ -4323,18 +4402,18 @@ function EditableUserBubble({ item, slots, actions }) {
|
|
|
4323
4402
|
}, "Edit"), actions);
|
|
4324
4403
|
}
|
|
4325
4404
|
const textareaProps = edit.getTextareaProps();
|
|
4326
|
-
return /* @__PURE__ */
|
|
4405
|
+
return /* @__PURE__ */ import_react18.default.createElement("div", {
|
|
4327
4406
|
"data-editing": "true"
|
|
4328
|
-
}, /* @__PURE__ */
|
|
4407
|
+
}, /* @__PURE__ */ import_react18.default.createElement("textarea", {
|
|
4329
4408
|
...textareaProps,
|
|
4330
4409
|
rows: Math.min(8, edit.draft.split("\n").length + 1),
|
|
4331
4410
|
className: classNames?.editTextarea
|
|
4332
|
-
}), /* @__PURE__ */
|
|
4411
|
+
}), /* @__PURE__ */ import_react18.default.createElement("div", {
|
|
4333
4412
|
className: classNames?.editActions
|
|
4334
|
-
}, /* @__PURE__ */
|
|
4413
|
+
}, /* @__PURE__ */ import_react18.default.createElement("button", {
|
|
4335
4414
|
type: "button",
|
|
4336
4415
|
onClick: edit.cancel
|
|
4337
|
-
}, "Cancel"), /* @__PURE__ */
|
|
4416
|
+
}, "Cancel"), /* @__PURE__ */ import_react18.default.createElement("button", {
|
|
4338
4417
|
type: "button",
|
|
4339
4418
|
onClick: edit.save,
|
|
4340
4419
|
disabled: !edit.canSave
|
|
@@ -4578,35 +4657,35 @@ function toItem(entry) {
|
|
|
4578
4657
|
__name(toItem, "toItem");
|
|
4579
4658
|
|
|
4580
4659
|
// src/composer/use-composer-autocomplete.ts
|
|
4581
|
-
var
|
|
4660
|
+
var import_react19 = require("react");
|
|
4582
4661
|
function useComposerAutocomplete(options) {
|
|
4583
4662
|
const { value, sources, acceptOnTab = true } = options;
|
|
4584
|
-
const latest = (0,
|
|
4663
|
+
const latest = (0, import_react19.useRef)(options);
|
|
4585
4664
|
latest.current = options;
|
|
4586
|
-
const inputRef = (0,
|
|
4587
|
-
const [caret, setCaret] = (0,
|
|
4588
|
-
const [items, setItems] = (0,
|
|
4589
|
-
const [isLoading, setLoading] = (0,
|
|
4590
|
-
const [error, setError] = (0,
|
|
4591
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
4592
|
-
const [dismissedIndex, setDismissedIndex] = (0,
|
|
4665
|
+
const inputRef = (0, import_react19.useRef)(null);
|
|
4666
|
+
const [caret, setCaret] = (0, import_react19.useState)(value.length);
|
|
4667
|
+
const [items, setItems] = (0, import_react19.useState)([]);
|
|
4668
|
+
const [isLoading, setLoading] = (0, import_react19.useState)(false);
|
|
4669
|
+
const [error, setError] = (0, import_react19.useState)(null);
|
|
4670
|
+
const [activeIndex, setActiveIndex] = (0, import_react19.useState)(0);
|
|
4671
|
+
const [dismissedIndex, setDismissedIndex] = (0, import_react19.useState)(null);
|
|
4593
4672
|
const safeCaret = Math.min(caret, value.length);
|
|
4594
|
-
const match = (0,
|
|
4673
|
+
const match = (0, import_react19.useMemo)(() => findActiveTrigger(value, safeCaret, sources), [
|
|
4595
4674
|
value,
|
|
4596
4675
|
safeCaret,
|
|
4597
4676
|
sources
|
|
4598
4677
|
]);
|
|
4599
4678
|
const isActive = match !== null && dismissedIndex !== match.index;
|
|
4600
|
-
const matchRef = (0,
|
|
4679
|
+
const matchRef = (0, import_react19.useRef)(match);
|
|
4601
4680
|
matchRef.current = match;
|
|
4602
|
-
const caretRef = (0,
|
|
4681
|
+
const caretRef = (0, import_react19.useRef)(safeCaret);
|
|
4603
4682
|
caretRef.current = safeCaret;
|
|
4604
|
-
const itemsRef = (0,
|
|
4683
|
+
const itemsRef = (0, import_react19.useRef)(items);
|
|
4605
4684
|
itemsRef.current = items;
|
|
4606
|
-
const activeIndexRef = (0,
|
|
4685
|
+
const activeIndexRef = (0, import_react19.useRef)(activeIndex);
|
|
4607
4686
|
activeIndexRef.current = activeIndex;
|
|
4608
4687
|
const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
|
|
4609
|
-
(0,
|
|
4688
|
+
(0, import_react19.useEffect)(() => {
|
|
4610
4689
|
const current = matchRef.current;
|
|
4611
4690
|
if (requestKey === null || current === null) {
|
|
4612
4691
|
setItems([]);
|
|
@@ -4654,25 +4733,25 @@ function useComposerAutocomplete(options) {
|
|
|
4654
4733
|
]);
|
|
4655
4734
|
const isOpen = isActive;
|
|
4656
4735
|
const activeItem = isOpen ? items[activeIndex] ?? null : null;
|
|
4657
|
-
const reactId = (0,
|
|
4736
|
+
const reactId = (0, import_react19.useId)();
|
|
4658
4737
|
const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
|
|
4659
|
-
const optionId = (0,
|
|
4738
|
+
const optionId = (0, import_react19.useCallback)((index) => `${listboxId}-option-${index}`, [
|
|
4660
4739
|
listboxId
|
|
4661
4740
|
]);
|
|
4662
|
-
const highlight = (0,
|
|
4741
|
+
const highlight = (0, import_react19.useCallback)((index) => {
|
|
4663
4742
|
const total = itemsRef.current.length;
|
|
4664
4743
|
if (total === 0) return;
|
|
4665
4744
|
setActiveIndex((index % total + total) % total);
|
|
4666
4745
|
}, []);
|
|
4667
|
-
const moveHighlight = (0,
|
|
4746
|
+
const moveHighlight = (0, import_react19.useCallback)((delta) => highlight(activeIndexRef.current + delta), [
|
|
4668
4747
|
highlight
|
|
4669
4748
|
]);
|
|
4670
|
-
const dismiss = (0,
|
|
4749
|
+
const dismiss = (0, import_react19.useCallback)(() => {
|
|
4671
4750
|
const current = matchRef.current;
|
|
4672
4751
|
if (current) setDismissedIndex(current.index);
|
|
4673
4752
|
}, []);
|
|
4674
|
-
const pendingCaret = (0,
|
|
4675
|
-
const accept = (0,
|
|
4753
|
+
const pendingCaret = (0, import_react19.useRef)(null);
|
|
4754
|
+
const accept = (0, import_react19.useCallback)((item) => {
|
|
4676
4755
|
const current = matchRef.current;
|
|
4677
4756
|
if (!current) return;
|
|
4678
4757
|
const chosen = item ?? itemsRef.current[activeIndexRef.current];
|
|
@@ -4683,16 +4762,16 @@ function useComposerAutocomplete(options) {
|
|
|
4683
4762
|
setDismissedIndex(null);
|
|
4684
4763
|
pendingCaret.current = edit.caret;
|
|
4685
4764
|
}, []);
|
|
4686
|
-
(0,
|
|
4765
|
+
(0, import_react19.useLayoutEffect)(() => {
|
|
4687
4766
|
const position = pendingCaret.current;
|
|
4688
4767
|
if (position === null) return;
|
|
4689
4768
|
pendingCaret.current = null;
|
|
4690
4769
|
inputRef.current?.setSelectionRange(position, position);
|
|
4691
4770
|
});
|
|
4692
|
-
const readCaret = (0,
|
|
4771
|
+
const readCaret = (0, import_react19.useCallback)((element) => {
|
|
4693
4772
|
setCaret(element.selectionStart ?? element.value.length);
|
|
4694
4773
|
}, []);
|
|
4695
|
-
const onKeyDown = (0,
|
|
4774
|
+
const onKeyDown = (0, import_react19.useCallback)((event) => {
|
|
4696
4775
|
if (!isOpen) return;
|
|
4697
4776
|
const hasItems = itemsRef.current.length > 0;
|
|
4698
4777
|
switch (event.key) {
|
|
@@ -4730,23 +4809,23 @@ function useComposerAutocomplete(options) {
|
|
|
4730
4809
|
dismiss,
|
|
4731
4810
|
moveHighlight
|
|
4732
4811
|
]);
|
|
4733
|
-
const onChange = (0,
|
|
4812
|
+
const onChange = (0, import_react19.useCallback)((event) => {
|
|
4734
4813
|
readCaret(event.target);
|
|
4735
4814
|
const next = findActiveTrigger(event.target.value, event.target.selectionStart ?? event.target.value.length, latest.current.sources);
|
|
4736
4815
|
setDismissedIndex((current) => current !== null && next?.index === current ? current : null);
|
|
4737
4816
|
}, [
|
|
4738
4817
|
readCaret
|
|
4739
4818
|
]);
|
|
4740
|
-
const onSelect = (0,
|
|
4819
|
+
const onSelect = (0, import_react19.useCallback)((event) => readCaret(event.currentTarget), [
|
|
4741
4820
|
readCaret
|
|
4742
4821
|
]);
|
|
4743
|
-
const onClick = (0,
|
|
4822
|
+
const onClick = (0, import_react19.useCallback)((event) => readCaret(event.currentTarget), [
|
|
4744
4823
|
readCaret
|
|
4745
4824
|
]);
|
|
4746
|
-
const setInput = (0,
|
|
4825
|
+
const setInput = (0, import_react19.useCallback)((element) => {
|
|
4747
4826
|
inputRef.current = element;
|
|
4748
4827
|
}, []);
|
|
4749
|
-
const getInputProps = (0,
|
|
4828
|
+
const getInputProps = (0, import_react19.useCallback)(() => ({
|
|
4750
4829
|
ref: setInput,
|
|
4751
4830
|
onChange,
|
|
4752
4831
|
onKeyDown,
|
|
@@ -4774,7 +4853,7 @@ function useComposerAutocomplete(options) {
|
|
|
4774
4853
|
activeIndex,
|
|
4775
4854
|
optionId
|
|
4776
4855
|
]);
|
|
4777
|
-
const getListboxProps = (0,
|
|
4856
|
+
const getListboxProps = (0, import_react19.useCallback)(() => ({
|
|
4778
4857
|
id: listboxId,
|
|
4779
4858
|
role: "listbox",
|
|
4780
4859
|
"aria-label": match?.source.label ?? match?.source.id ?? "Suggestions"
|
|
@@ -4782,7 +4861,7 @@ function useComposerAutocomplete(options) {
|
|
|
4782
4861
|
listboxId,
|
|
4783
4862
|
match
|
|
4784
4863
|
]);
|
|
4785
|
-
const getOptionProps = (0,
|
|
4864
|
+
const getOptionProps = (0, import_react19.useCallback)((index) => ({
|
|
4786
4865
|
id: optionId(index),
|
|
4787
4866
|
role: "option",
|
|
4788
4867
|
"aria-selected": index === activeIndex
|
|
@@ -4816,13 +4895,13 @@ function isPromise(value) {
|
|
|
4816
4895
|
__name(isPromise, "isPromise");
|
|
4817
4896
|
|
|
4818
4897
|
// src/presentation/use-tool-catalog.ts
|
|
4819
|
-
var
|
|
4820
|
-
var
|
|
4821
|
-
function
|
|
4822
|
-
let byAgent =
|
|
4898
|
+
var import_react20 = require("react");
|
|
4899
|
+
var shared2 = /* @__PURE__ */ new WeakMap();
|
|
4900
|
+
function load2(client, agent) {
|
|
4901
|
+
let byAgent = shared2.get(client);
|
|
4823
4902
|
if (byAgent === void 0) {
|
|
4824
4903
|
byAgent = /* @__PURE__ */ new Map();
|
|
4825
|
-
|
|
4904
|
+
shared2.set(client, byAgent);
|
|
4826
4905
|
}
|
|
4827
4906
|
const key = agent ?? "";
|
|
4828
4907
|
const cached = byAgent.get(key);
|
|
@@ -4837,22 +4916,22 @@ function load(client, agent) {
|
|
|
4837
4916
|
byAgent.set(key, request);
|
|
4838
4917
|
return request;
|
|
4839
4918
|
}
|
|
4840
|
-
__name(
|
|
4919
|
+
__name(load2, "load");
|
|
4841
4920
|
function useToolCatalog(options = {}) {
|
|
4842
4921
|
const { agent, enabled = true } = options;
|
|
4843
4922
|
const client = useAgentBackend(options.backend);
|
|
4844
|
-
const [entries, setEntries] = (0,
|
|
4845
|
-
const [isLoading, setLoading] = (0,
|
|
4846
|
-
const [error, setError] = (0,
|
|
4847
|
-
const [generation, setGeneration] = (0,
|
|
4848
|
-
(0,
|
|
4923
|
+
const [entries, setEntries] = (0, import_react20.useState)([]);
|
|
4924
|
+
const [isLoading, setLoading] = (0, import_react20.useState)(enabled);
|
|
4925
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
4926
|
+
const [generation, setGeneration] = (0, import_react20.useState)(0);
|
|
4927
|
+
(0, import_react20.useEffect)(() => {
|
|
4849
4928
|
if (!enabled) {
|
|
4850
4929
|
setLoading(false);
|
|
4851
4930
|
return;
|
|
4852
4931
|
}
|
|
4853
4932
|
let cancelled = false;
|
|
4854
4933
|
setLoading(true);
|
|
4855
|
-
|
|
4934
|
+
load2(client, agent).then((loaded) => {
|
|
4856
4935
|
if (cancelled) return;
|
|
4857
4936
|
setEntries(Array.isArray(loaded) ? loaded : []);
|
|
4858
4937
|
setError(null);
|
|
@@ -4871,14 +4950,14 @@ function useToolCatalog(options = {}) {
|
|
|
4871
4950
|
enabled,
|
|
4872
4951
|
generation
|
|
4873
4952
|
]);
|
|
4874
|
-
const refresh = (0,
|
|
4875
|
-
|
|
4953
|
+
const refresh = (0, import_react20.useCallback)(() => {
|
|
4954
|
+
shared2.get(client)?.delete(agent ?? "");
|
|
4876
4955
|
setGeneration((current) => current + 1);
|
|
4877
4956
|
}, [
|
|
4878
4957
|
client,
|
|
4879
4958
|
agent
|
|
4880
4959
|
]);
|
|
4881
|
-
const catalog = (0,
|
|
4960
|
+
const catalog = (0, import_react20.useMemo)(() => toolCatalogFrom(entries), [
|
|
4882
4961
|
entries
|
|
4883
4962
|
]);
|
|
4884
4963
|
return {
|
|
@@ -4892,7 +4971,7 @@ function useToolCatalog(options = {}) {
|
|
|
4892
4971
|
__name(useToolCatalog, "useToolCatalog");
|
|
4893
4972
|
|
|
4894
4973
|
// src/approvals/countdown.ts
|
|
4895
|
-
var
|
|
4974
|
+
var import_react21 = require("react");
|
|
4896
4975
|
function approvalCountdown(expiresAt, now = Date.now()) {
|
|
4897
4976
|
const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
|
|
4898
4977
|
if (!Number.isFinite(deadline)) {
|
|
@@ -4910,10 +4989,10 @@ function approvalCountdown(expiresAt, now = Date.now()) {
|
|
|
4910
4989
|
__name(approvalCountdown, "approvalCountdown");
|
|
4911
4990
|
function useApprovalCountdown(expiresAt, options = {}) {
|
|
4912
4991
|
const { intervalMs = 1e3 } = options;
|
|
4913
|
-
const nowRef = (0,
|
|
4992
|
+
const nowRef = (0, import_react21.useRef)(options.now ?? Date.now);
|
|
4914
4993
|
nowRef.current = options.now ?? Date.now;
|
|
4915
|
-
const [state, setState] = (0,
|
|
4916
|
-
(0,
|
|
4994
|
+
const [state, setState] = (0, import_react21.useState)(() => approvalCountdown(expiresAt, nowRef.current()));
|
|
4995
|
+
(0, import_react21.useEffect)(() => {
|
|
4917
4996
|
const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
|
|
4918
4997
|
const first = read();
|
|
4919
4998
|
setState(first);
|
|
@@ -5049,13 +5128,19 @@ function storedMessageToUiMessage(message) {
|
|
|
5049
5128
|
for (const call of message.toolCalls ?? []) {
|
|
5050
5129
|
const result = message.toolResults?.find((candidate) => candidate.id === call.id);
|
|
5051
5130
|
const toolKind2 = call.kind;
|
|
5131
|
+
const toolMetadata = {
|
|
5132
|
+
...toolKind2 !== void 0 ? {
|
|
5133
|
+
toolKind: toolKind2
|
|
5134
|
+
} : {},
|
|
5135
|
+
...call.parentId !== void 0 ? {
|
|
5136
|
+
parentId: call.parentId
|
|
5137
|
+
} : {}
|
|
5138
|
+
};
|
|
5052
5139
|
parts.push({
|
|
5053
5140
|
type: `tool-${call.name}`,
|
|
5054
5141
|
toolCallId: call.id,
|
|
5055
|
-
...
|
|
5056
|
-
toolMetadata
|
|
5057
|
-
toolKind: toolKind2
|
|
5058
|
-
}
|
|
5142
|
+
...Object.keys(toolMetadata).length > 0 ? {
|
|
5143
|
+
toolMetadata
|
|
5059
5144
|
} : {},
|
|
5060
5145
|
...result !== void 0 ? isRefusal(result) ? {
|
|
5061
5146
|
// A declined action is NOT an available output. Reloading a thread used to bring one
|
|
@@ -5083,6 +5168,8 @@ function storedMessageToUiMessage(message) {
|
|
|
5083
5168
|
parts.push(...pushedByCall.get(call.id) ?? []);
|
|
5084
5169
|
}
|
|
5085
5170
|
const metadata = {
|
|
5171
|
+
// The host's own facts first: the library's keys win on a clash.
|
|
5172
|
+
...message.metadata,
|
|
5086
5173
|
...message.feedback !== void 0 ? {
|
|
5087
5174
|
feedback: message.feedback
|
|
5088
5175
|
} : {},
|
|
@@ -5142,6 +5229,8 @@ function mergeTurn(rows) {
|
|
|
5142
5229
|
const feedback = lastRow.feedback;
|
|
5143
5230
|
const createdAt = rows[0]?.createdAt;
|
|
5144
5231
|
const metadata = {
|
|
5232
|
+
// Host facts of every row, a later row's winning (the turn's final state), under the library's.
|
|
5233
|
+
...Object.assign({}, ...rows.map((row) => row.metadata ?? {})),
|
|
5145
5234
|
...usage !== void 0 ? {
|
|
5146
5235
|
usage
|
|
5147
5236
|
} : {},
|
|
@@ -5177,8 +5266,8 @@ function sumUsage(rows) {
|
|
|
5177
5266
|
__name(sumUsage, "sumUsage");
|
|
5178
5267
|
|
|
5179
5268
|
// src/use-agent-chat.ts
|
|
5180
|
-
var
|
|
5181
|
-
var
|
|
5269
|
+
var import_react22 = require("@ai-sdk/react");
|
|
5270
|
+
var import_react23 = require("react");
|
|
5182
5271
|
var localChatSequence = 0;
|
|
5183
5272
|
function localChatId() {
|
|
5184
5273
|
localChatSequence += 1;
|
|
@@ -5186,13 +5275,13 @@ function localChatId() {
|
|
|
5186
5275
|
}
|
|
5187
5276
|
__name(localChatId, "localChatId");
|
|
5188
5277
|
function useAgentChat(options = {}) {
|
|
5189
|
-
const latest = (0,
|
|
5278
|
+
const latest = (0, import_react23.useRef)(options);
|
|
5190
5279
|
latest.current = options;
|
|
5191
5280
|
const resolved = useAgentBackend(options.backend);
|
|
5192
|
-
const client = (0,
|
|
5193
|
-
const createdThreadId = (0,
|
|
5194
|
-
const chatIdRef = (0,
|
|
5195
|
-
const boundThreadRef = (0,
|
|
5281
|
+
const client = (0, import_react23.useRef)(resolved).current;
|
|
5282
|
+
const createdThreadId = (0, import_react23.useRef)(void 0);
|
|
5283
|
+
const chatIdRef = (0, import_react23.useRef)(options.threadId ?? localChatId());
|
|
5284
|
+
const boundThreadRef = (0, import_react23.useRef)(options.threadId);
|
|
5196
5285
|
if (options.threadId !== boundThreadRef.current) {
|
|
5197
5286
|
boundThreadRef.current = options.threadId;
|
|
5198
5287
|
const adopting = options.threadId !== void 0 && options.threadId === createdThreadId.current;
|
|
@@ -5202,26 +5291,26 @@ function useAgentChat(options = {}) {
|
|
|
5202
5291
|
}
|
|
5203
5292
|
}
|
|
5204
5293
|
const chatId = chatIdRef.current;
|
|
5205
|
-
const [runId, setRunId] = (0,
|
|
5206
|
-
const runIdRef = (0,
|
|
5294
|
+
const [runId, setRunId] = (0, import_react23.useState)(options.resumeRunId);
|
|
5295
|
+
const runIdRef = (0, import_react23.useRef)(runId);
|
|
5207
5296
|
runIdRef.current = runId;
|
|
5208
|
-
const settlingRunIdRef = (0,
|
|
5209
|
-
const autoResumeRunIdRef = (0,
|
|
5210
|
-
const [activeRunId, setActiveRunId] = (0,
|
|
5211
|
-
const [isLoadingHistory, setIsLoadingHistory] = (0,
|
|
5212
|
-
const [historyError, setHistoryError] = (0,
|
|
5213
|
-
const [threadModel, setThreadModel] = (0,
|
|
5214
|
-
const [pickedModel, setPickedModel] = (0,
|
|
5215
|
-
const pickedModelRef = (0,
|
|
5297
|
+
const settlingRunIdRef = (0, import_react23.useRef)(void 0);
|
|
5298
|
+
const autoResumeRunIdRef = (0, import_react23.useRef)(void 0);
|
|
5299
|
+
const [activeRunId, setActiveRunId] = (0, import_react23.useState)(null);
|
|
5300
|
+
const [isLoadingHistory, setIsLoadingHistory] = (0, import_react23.useState)(false);
|
|
5301
|
+
const [historyError, setHistoryError] = (0, import_react23.useState)(null);
|
|
5302
|
+
const [threadModel, setThreadModel] = (0, import_react23.useState)(null);
|
|
5303
|
+
const [pickedModel, setPickedModel] = (0, import_react23.useState)(void 0);
|
|
5304
|
+
const pickedModelRef = (0, import_react23.useRef)(pickedModel);
|
|
5216
5305
|
pickedModelRef.current = pickedModel;
|
|
5217
|
-
const pendingPin = (0,
|
|
5218
|
-
const regenerateNext = (0,
|
|
5219
|
-
const currentThreadId = (0,
|
|
5220
|
-
const [connection, setConnection] = (0,
|
|
5306
|
+
const pendingPin = (0, import_react23.useRef)(void 0);
|
|
5307
|
+
const regenerateNext = (0, import_react23.useRef)(false);
|
|
5308
|
+
const currentThreadId = (0, import_react23.useCallback)(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
5309
|
+
const [connection, setConnection] = (0, import_react23.useState)({
|
|
5221
5310
|
status: "live"
|
|
5222
5311
|
});
|
|
5223
|
-
const resyncAfterSettle = (0,
|
|
5224
|
-
const transport = (0,
|
|
5312
|
+
const resyncAfterSettle = (0, import_react23.useRef)(false);
|
|
5313
|
+
const transport = (0, import_react23.useMemo)(() => {
|
|
5225
5314
|
function onMeta(meta) {
|
|
5226
5315
|
settlingRunIdRef.current = meta.runId;
|
|
5227
5316
|
setRunId(meta.runId);
|
|
@@ -5263,6 +5352,11 @@ function useAgentChat(options = {}) {
|
|
|
5263
5352
|
const threadId = currentThreadId();
|
|
5264
5353
|
const model = current.model ?? pickedModelRef.current;
|
|
5265
5354
|
return {
|
|
5355
|
+
// Read per send: a host that switches agents before the first message (a picker on a
|
|
5356
|
+
// new chat) sends the one picked now, not the one this chat mounted with.
|
|
5357
|
+
...current.agent !== void 0 ? {
|
|
5358
|
+
agent: current.agent
|
|
5359
|
+
} : {},
|
|
5266
5360
|
...threadId !== void 0 ? {
|
|
5267
5361
|
threadId
|
|
5268
5362
|
} : {},
|
|
@@ -5284,8 +5378,8 @@ function useAgentChat(options = {}) {
|
|
|
5284
5378
|
}, "onAttemptStart")
|
|
5285
5379
|
});
|
|
5286
5380
|
}, []);
|
|
5287
|
-
const backgroundRef = (0,
|
|
5288
|
-
const chat = (0,
|
|
5381
|
+
const backgroundRef = (0, import_react23.useRef)(() => Promise.resolve());
|
|
5382
|
+
const chat = (0, import_react22.useChat)({
|
|
5289
5383
|
transport,
|
|
5290
5384
|
id: chatId,
|
|
5291
5385
|
resume: options.resumeRunId !== void 0,
|
|
@@ -5331,7 +5425,7 @@ function useAgentChat(options = {}) {
|
|
|
5331
5425
|
}
|
|
5332
5426
|
}, "onFinish")
|
|
5333
5427
|
});
|
|
5334
|
-
const chatRef = (0,
|
|
5428
|
+
const chatRef = (0, import_react23.useRef)(chat);
|
|
5335
5429
|
chatRef.current = chat;
|
|
5336
5430
|
async function resyncFromThread() {
|
|
5337
5431
|
const threadId = currentThreadId();
|
|
@@ -5343,8 +5437,8 @@ function useAgentChat(options = {}) {
|
|
|
5343
5437
|
}
|
|
5344
5438
|
}
|
|
5345
5439
|
__name(resyncFromThread, "resyncFromThread");
|
|
5346
|
-
const firstChatId = (0,
|
|
5347
|
-
(0,
|
|
5440
|
+
const firstChatId = (0, import_react23.useRef)(chatId);
|
|
5441
|
+
(0, import_react23.useEffect)(() => {
|
|
5348
5442
|
if (chatId === firstChatId.current) return;
|
|
5349
5443
|
firstChatId.current = chatId;
|
|
5350
5444
|
setRunId(void 0);
|
|
@@ -5357,7 +5451,7 @@ function useAgentChat(options = {}) {
|
|
|
5357
5451
|
}, [
|
|
5358
5452
|
chatId
|
|
5359
5453
|
]);
|
|
5360
|
-
(0,
|
|
5454
|
+
(0, import_react23.useEffect)(() => {
|
|
5361
5455
|
const threadId = options.threadId;
|
|
5362
5456
|
if (threadId === void 0) return;
|
|
5363
5457
|
if (threadId === createdThreadId.current) return;
|
|
@@ -5398,8 +5492,8 @@ function useAgentChat(options = {}) {
|
|
|
5398
5492
|
chatId,
|
|
5399
5493
|
options.threadId
|
|
5400
5494
|
]);
|
|
5401
|
-
const turnInFlight = (0,
|
|
5402
|
-
const isTurnInFlight = (0,
|
|
5495
|
+
const turnInFlight = (0, import_react23.useRef)(false);
|
|
5496
|
+
const isTurnInFlight = (0, import_react23.useCallback)(() => turnInFlight.current || transport.isAttemptLive, [
|
|
5403
5497
|
transport
|
|
5404
5498
|
]);
|
|
5405
5499
|
const quota = useQuota({
|
|
@@ -5407,9 +5501,9 @@ function useAgentChat(options = {}) {
|
|
|
5407
5501
|
enabled: options.quota !== false && typeof client.getQuota === "function"
|
|
5408
5502
|
});
|
|
5409
5503
|
const blocked = options.blocked !== void 0 ? options.blocked : quota.blocked;
|
|
5410
|
-
const blockedRef = (0,
|
|
5504
|
+
const blockedRef = (0, import_react23.useRef)(blocked);
|
|
5411
5505
|
blockedRef.current = blocked;
|
|
5412
|
-
const sendMessage = (0,
|
|
5506
|
+
const sendMessage = (0, import_react23.useCallback)(async (...args) => {
|
|
5413
5507
|
const block = blockedRef.current;
|
|
5414
5508
|
if (block != null) throw new QuotaBlockedError(block);
|
|
5415
5509
|
if (isTurnInFlight()) return;
|
|
@@ -5422,13 +5516,13 @@ function useAgentChat(options = {}) {
|
|
|
5422
5516
|
}, [
|
|
5423
5517
|
isTurnInFlight
|
|
5424
5518
|
]);
|
|
5425
|
-
const addToolResult = (0,
|
|
5519
|
+
const addToolResult = (0, import_react23.useCallback)(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
|
|
5426
5520
|
tool,
|
|
5427
5521
|
toolCallId,
|
|
5428
5522
|
output
|
|
5429
5523
|
}), []);
|
|
5430
|
-
const [backgroundRuns, setBackgroundRuns] = (0,
|
|
5431
|
-
const refreshBackground = (0,
|
|
5524
|
+
const [backgroundRuns, setBackgroundRuns] = (0, import_react23.useState)([]);
|
|
5525
|
+
const refreshBackground = (0, import_react23.useCallback)(async () => {
|
|
5432
5526
|
const threadId = currentThreadId();
|
|
5433
5527
|
if (threadId === void 0) {
|
|
5434
5528
|
return;
|
|
@@ -5454,7 +5548,7 @@ function useAgentChat(options = {}) {
|
|
|
5454
5548
|
]);
|
|
5455
5549
|
backgroundRef.current = refreshBackground;
|
|
5456
5550
|
const isWorking = backgroundRuns.some((run) => run.status === "running");
|
|
5457
|
-
(0,
|
|
5551
|
+
(0, import_react23.useEffect)(() => {
|
|
5458
5552
|
if (options.background !== true || options.threadId === void 0) {
|
|
5459
5553
|
return;
|
|
5460
5554
|
}
|
|
@@ -5465,7 +5559,7 @@ function useAgentChat(options = {}) {
|
|
|
5465
5559
|
chatId,
|
|
5466
5560
|
refreshBackground
|
|
5467
5561
|
]);
|
|
5468
|
-
(0,
|
|
5562
|
+
(0, import_react23.useEffect)(() => {
|
|
5469
5563
|
const every = latest.current.backgroundPollMs ?? 5e3;
|
|
5470
5564
|
if (latest.current.background !== true || !isWorking || every <= 0) {
|
|
5471
5565
|
return;
|
|
@@ -5476,7 +5570,7 @@ function useAgentChat(options = {}) {
|
|
|
5476
5570
|
isWorking,
|
|
5477
5571
|
refreshBackground
|
|
5478
5572
|
]);
|
|
5479
|
-
const cancel = (0,
|
|
5573
|
+
const cancel = (0, import_react23.useCallback)(async () => {
|
|
5480
5574
|
chatRef.current.stop();
|
|
5481
5575
|
const active = runIdRef.current;
|
|
5482
5576
|
if (active) {
|
|
@@ -5488,7 +5582,7 @@ function useAgentChat(options = {}) {
|
|
|
5488
5582
|
}, [
|
|
5489
5583
|
client
|
|
5490
5584
|
]);
|
|
5491
|
-
const approve = (0,
|
|
5585
|
+
const approve = (0, import_react23.useCallback)(async ({ toolCallId, remember, via }) => {
|
|
5492
5586
|
await requireBackendMethod(client, "approveToolCall")({
|
|
5493
5587
|
toolCallId,
|
|
5494
5588
|
...remember === true ? {
|
|
@@ -5501,7 +5595,7 @@ function useAgentChat(options = {}) {
|
|
|
5501
5595
|
}, [
|
|
5502
5596
|
client
|
|
5503
5597
|
]);
|
|
5504
|
-
const reject = (0,
|
|
5598
|
+
const reject = (0, import_react23.useCallback)(async ({ toolCallId, reason, via }) => {
|
|
5505
5599
|
await requireBackendMethod(client, "rejectToolCall")({
|
|
5506
5600
|
toolCallId,
|
|
5507
5601
|
...reason !== void 0 ? {
|
|
@@ -5514,7 +5608,7 @@ function useAgentChat(options = {}) {
|
|
|
5514
5608
|
}, [
|
|
5515
5609
|
client
|
|
5516
5610
|
]);
|
|
5517
|
-
const answer = (0,
|
|
5611
|
+
const answer = (0, import_react23.useCallback)(async ({ toolCallId, answers }) => {
|
|
5518
5612
|
await requireBackendMethod(client, "answerToolCall")({
|
|
5519
5613
|
toolCallId,
|
|
5520
5614
|
...answers !== void 0 ? {
|
|
@@ -5524,14 +5618,14 @@ function useAgentChat(options = {}) {
|
|
|
5524
5618
|
}, [
|
|
5525
5619
|
client
|
|
5526
5620
|
]);
|
|
5527
|
-
const skip = (0,
|
|
5621
|
+
const skip = (0, import_react23.useCallback)(async ({ toolCallId }) => {
|
|
5528
5622
|
await requireBackendMethod(client, "skipToolCall")({
|
|
5529
5623
|
toolCallId
|
|
5530
5624
|
});
|
|
5531
5625
|
}, [
|
|
5532
5626
|
client
|
|
5533
5627
|
]);
|
|
5534
|
-
const regenerate = (0,
|
|
5628
|
+
const regenerate = (0, import_react23.useCallback)((_input) => {
|
|
5535
5629
|
const block = blockedRef.current;
|
|
5536
5630
|
if (block != null) throw new QuotaBlockedError(block);
|
|
5537
5631
|
if (isTurnInFlight()) return;
|
|
@@ -5543,7 +5637,7 @@ function useAgentChat(options = {}) {
|
|
|
5543
5637
|
}, [
|
|
5544
5638
|
isTurnInFlight
|
|
5545
5639
|
]);
|
|
5546
|
-
const storedIdOf = (0,
|
|
5640
|
+
const storedIdOf = (0, import_react23.useCallback)(async (messageId, threadId) => {
|
|
5547
5641
|
const message = chatRef.current.messages.find((candidate) => candidate.id === messageId);
|
|
5548
5642
|
const runOf = message?.metadata?.runId;
|
|
5549
5643
|
if (runOf === void 0) return messageId;
|
|
@@ -5555,7 +5649,7 @@ function useAgentChat(options = {}) {
|
|
|
5555
5649
|
}, [
|
|
5556
5650
|
client
|
|
5557
5651
|
]);
|
|
5558
|
-
const fork = (0,
|
|
5652
|
+
const fork = (0, import_react23.useCallback)(async ({ messageId, threadId }) => {
|
|
5559
5653
|
const source = threadId ?? currentThreadId();
|
|
5560
5654
|
if (source === void 0) throw new Error("fork: this chat has no thread yet");
|
|
5561
5655
|
const stored = await storedIdOf(messageId, source);
|
|
@@ -5570,7 +5664,7 @@ function useAgentChat(options = {}) {
|
|
|
5570
5664
|
currentThreadId,
|
|
5571
5665
|
storedIdOf
|
|
5572
5666
|
]);
|
|
5573
|
-
const truncateFrom = (0,
|
|
5667
|
+
const truncateFrom = (0, import_react23.useCallback)(async ({ messageId, threadId }) => {
|
|
5574
5668
|
const target = threadId ?? currentThreadId();
|
|
5575
5669
|
if (target === void 0) throw new Error("truncateFrom: this chat has no thread yet");
|
|
5576
5670
|
const stored = await storedIdOf(messageId, target);
|
|
@@ -5580,7 +5674,7 @@ function useAgentChat(options = {}) {
|
|
|
5580
5674
|
currentThreadId,
|
|
5581
5675
|
storedIdOf
|
|
5582
5676
|
]);
|
|
5583
|
-
const promote = (0,
|
|
5677
|
+
const promote = (0, import_react23.useCallback)(async ({ threadId } = {}) => {
|
|
5584
5678
|
const target = threadId ?? currentThreadId();
|
|
5585
5679
|
if (target === void 0) throw new Error("promote: this chat has no thread yet");
|
|
5586
5680
|
await requireBackendMethod(client, "promoteThread")(target);
|
|
@@ -5591,8 +5685,8 @@ function useAgentChat(options = {}) {
|
|
|
5591
5685
|
client,
|
|
5592
5686
|
currentThreadId
|
|
5593
5687
|
]);
|
|
5594
|
-
const [modelsWanted, setModelsWanted] = (0,
|
|
5595
|
-
const modelsWantedRef = (0,
|
|
5688
|
+
const [modelsWanted, setModelsWanted] = (0, import_react23.useState)(false);
|
|
5689
|
+
const modelsWantedRef = (0, import_react23.useRef)(modelsWanted);
|
|
5596
5690
|
modelsWantedRef.current = modelsWanted;
|
|
5597
5691
|
const catalog = useModels({
|
|
5598
5692
|
backend: client,
|
|
@@ -5601,13 +5695,13 @@ function useAgentChat(options = {}) {
|
|
|
5601
5695
|
} : {},
|
|
5602
5696
|
enabled: modelsWanted && typeof client.listModels === "function"
|
|
5603
5697
|
});
|
|
5604
|
-
const wantModels = (0,
|
|
5698
|
+
const wantModels = (0, import_react23.useCallback)(() => {
|
|
5605
5699
|
if (modelsWantedRef.current) return;
|
|
5606
5700
|
modelsWantedRef.current = true;
|
|
5607
5701
|
queueMicrotask(() => setModelsWanted(true));
|
|
5608
5702
|
}, []);
|
|
5609
|
-
const selectModel = (0,
|
|
5610
|
-
const pinToThread = (0,
|
|
5703
|
+
const selectModel = (0, import_react23.useCallback)((id) => setPickedModel(id), []);
|
|
5704
|
+
const pinToThread = (0, import_react23.useCallback)(async (model) => {
|
|
5611
5705
|
const threadId = currentThreadId();
|
|
5612
5706
|
setThreadModel(model);
|
|
5613
5707
|
if (threadId === void 0) {
|
|
@@ -5636,6 +5730,10 @@ function useAgentChat(options = {}) {
|
|
|
5636
5730
|
return catalog.providers;
|
|
5637
5731
|
},
|
|
5638
5732
|
selected: options.model ?? pickedModel ?? threadModel ?? catalog.defaultModel ?? null,
|
|
5733
|
+
get defaultModel() {
|
|
5734
|
+
wantModels();
|
|
5735
|
+
return catalog.defaultModel;
|
|
5736
|
+
},
|
|
5639
5737
|
select: selectModel,
|
|
5640
5738
|
pinToThread,
|
|
5641
5739
|
isLoading: modelsWanted && catalog.isLoading,
|
|
@@ -5647,9 +5745,9 @@ function useAgentChat(options = {}) {
|
|
|
5647
5745
|
...options.composer,
|
|
5648
5746
|
backend: client
|
|
5649
5747
|
});
|
|
5650
|
-
const [text, setText] = (0,
|
|
5651
|
-
const blockedBy = blocked != null ? "quota" : files.isUploading ? "uploading" : isBusy ? "busy" : text.trim().length === 0 && files.
|
|
5652
|
-
const composerRef = (0,
|
|
5748
|
+
const [text, setText] = (0, import_react23.useState)("");
|
|
5749
|
+
const blockedBy = blocked != null ? "quota" : files.isUploading ? "uploading" : isBusy ? "busy" : text.trim().length === 0 && files.refs.length === 0 ? "empty" : null;
|
|
5750
|
+
const composerRef = (0, import_react23.useRef)({
|
|
5653
5751
|
text,
|
|
5654
5752
|
files,
|
|
5655
5753
|
blockedBy
|
|
@@ -5659,14 +5757,30 @@ function useAgentChat(options = {}) {
|
|
|
5659
5757
|
files,
|
|
5660
5758
|
blockedBy
|
|
5661
5759
|
};
|
|
5662
|
-
const submit = (0,
|
|
5760
|
+
const submit = (0, import_react23.useCallback)(async () => {
|
|
5663
5761
|
const current = composerRef.current;
|
|
5664
5762
|
if (current.blockedBy !== null) return;
|
|
5665
5763
|
const refs = current.files.refs;
|
|
5764
|
+
const files2 = current.files.items.flatMap((item) => item.status === "ready" && item.attachment !== void 0 ? [
|
|
5765
|
+
{
|
|
5766
|
+
type: "file",
|
|
5767
|
+
mediaType: item.attachment.contentType,
|
|
5768
|
+
filename: item.attachment.name,
|
|
5769
|
+
url: item.attachment.url,
|
|
5770
|
+
providerMetadata: {
|
|
5771
|
+
agent: {
|
|
5772
|
+
mediaId: item.attachment.mediaId
|
|
5773
|
+
}
|
|
5774
|
+
}
|
|
5775
|
+
}
|
|
5776
|
+
] : []);
|
|
5666
5777
|
const draft = current.text.trim();
|
|
5667
5778
|
setText("");
|
|
5668
5779
|
current.files.clear();
|
|
5669
|
-
await sendMessage({
|
|
5780
|
+
await sendMessage(files2.length > 0 ? {
|
|
5781
|
+
text: draft,
|
|
5782
|
+
files: files2
|
|
5783
|
+
} : {
|
|
5670
5784
|
text: draft
|
|
5671
5785
|
}, refs.length > 0 ? {
|
|
5672
5786
|
body: {
|
|
@@ -5825,6 +5939,7 @@ var QuotaBlockedError = class extends Error {
|
|
|
5825
5939
|
toolCatalogFrom,
|
|
5826
5940
|
useAgentBackend,
|
|
5827
5941
|
useAgentChat,
|
|
5942
|
+
useAgentConfig,
|
|
5828
5943
|
useAgents,
|
|
5829
5944
|
useAmbientRenderUi,
|
|
5830
5945
|
useApprovalCountdown,
|