@dudousxd/nestjs-agent-react 0.22.0 → 0.23.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/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");
@@ -1113,7 +1117,7 @@ function dragHasFiles(data) {
1113
1117
  __name(dragHasFiles, "dragHasFiles");
1114
1118
 
1115
1119
  // src/attachments/use-attachments.ts
1116
- import { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3, useState as useState3 } from "react";
1120
+ import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo4, useRef as useRef3, useState as useState4 } from "react";
1117
1121
 
1118
1122
  // src/backend.ts
1119
1123
  var AgentBackendUnsupportedError = class extends Error {
@@ -1135,6 +1139,9 @@ function requireBackendMethod(backend, name) {
1135
1139
  }
1136
1140
  __name(requireBackendMethod, "requireBackendMethod");
1137
1141
 
1142
+ // src/config/use-agent-config.ts
1143
+ import { useEffect as useEffect3, useState as useState3 } from "react";
1144
+
1138
1145
  // src/provider.tsx
1139
1146
  import { useContext as useContext3, useMemo as useMemo3, useRef as useRef2 } from "react";
1140
1147
 
@@ -1699,6 +1706,59 @@ function useAgentBackend(own) {
1699
1706
  }
1700
1707
  __name(useAgentBackend, "useAgentBackend");
1701
1708
 
1709
+ // src/config/use-agent-config.ts
1710
+ var shared = /* @__PURE__ */ new WeakMap();
1711
+ function load(backend) {
1712
+ const getConfig = backend.getConfig;
1713
+ if (typeof getConfig !== "function") return void 0;
1714
+ let pending = shared.get(backend);
1715
+ if (pending === void 0) {
1716
+ pending = getConfig.call(backend).catch((error) => {
1717
+ shared.delete(backend);
1718
+ throw error;
1719
+ });
1720
+ shared.set(backend, pending);
1721
+ }
1722
+ return pending;
1723
+ }
1724
+ __name(load, "load");
1725
+ function useAgentConfig(options = {}) {
1726
+ const backend = useAgentBackend(options.backend);
1727
+ const enabled = options.enabled !== false;
1728
+ const [config, setConfig] = useState3(void 0);
1729
+ const [isLoading, setLoading] = useState3(false);
1730
+ const [error, setError] = useState3(null);
1731
+ useEffect3(() => {
1732
+ if (!enabled) return;
1733
+ const pending = load(backend);
1734
+ if (pending === void 0) return;
1735
+ let cancelled = false;
1736
+ setLoading(true);
1737
+ pending.then((loaded) => {
1738
+ if (cancelled) return;
1739
+ setConfig(loaded !== null && typeof loaded === "object" ? loaded : void 0);
1740
+ setError(null);
1741
+ setLoading(false);
1742
+ }, (failure) => {
1743
+ if (cancelled) return;
1744
+ setError(failure instanceof Error ? failure : new Error(String(failure)));
1745
+ setLoading(false);
1746
+ });
1747
+ return () => {
1748
+ cancelled = true;
1749
+ };
1750
+ }, [
1751
+ backend,
1752
+ enabled
1753
+ ]);
1754
+ return {
1755
+ config,
1756
+ isLoading,
1757
+ error
1758
+ };
1759
+ }
1760
+ __name(useAgentConfig, "useAgentConfig");
1761
+
1702
1762
  // src/attachments/use-attachments.ts
1703
1763
  var DEFAULT_REJECTION = {
1704
1764
  type: /* @__PURE__ */ __name((file) => `${file.name} is not a supported file type`, "type"),
@@ -1708,19 +1768,33 @@ var DEFAULT_REJECTION = {
1708
1768
  var sequence = 0;
1709
1769
  function useAttachments(options = {}) {
1710
1770
  const backend = useAgentBackend(options.backend);
1711
- const latest = useRef3({
1712
- ...options,
1771
+ const { config } = useAgentConfig({
1713
1772
  backend
1714
1773
  });
1715
- latest.current = {
1774
+ const limits = config?.attachments;
1775
+ const accept = options.accept ?? limits?.allowedContentTypes;
1776
+ const maxBytes = options.maxBytes ?? limits?.maxBytes;
1777
+ const maxFiles = options.maxFiles ?? limits?.maxPerMessage;
1778
+ const effective = {
1716
1779
  ...options,
1717
- backend
1780
+ backend,
1781
+ ...accept !== void 0 ? {
1782
+ accept
1783
+ } : {},
1784
+ ...maxBytes !== void 0 ? {
1785
+ maxBytes
1786
+ } : {},
1787
+ ...maxFiles !== void 0 ? {
1788
+ maxFiles
1789
+ } : {}
1718
1790
  };
1719
- const [items, setItems] = useState3([]);
1791
+ const latest = useRef3(effective);
1792
+ latest.current = effective;
1793
+ const [items, setItems] = useState4([]);
1720
1794
  const itemsRef = useRef3(items);
1721
1795
  itemsRef.current = items;
1722
1796
  const controllers = useRef3(/* @__PURE__ */ new Map());
1723
- const [dragDepth, setDragDepth] = useState3(0);
1797
+ const [dragDepth, setDragDepth] = useState4(0);
1724
1798
  const patch = useCallback2((id, change) => {
1725
1799
  setItems((current) => current.map((item) => item.id === id ? {
1726
1800
  ...item,
@@ -1765,9 +1839,9 @@ function useAttachments(options = {}) {
1765
1839
  ]);
1766
1840
  const add = useCallback2((files) => {
1767
1841
  if (files == null) return;
1768
- const { accept: accept2, maxBytes, maxFiles, describeRejection } = latest.current;
1842
+ const { accept: accept2, maxBytes: maxBytes2, maxFiles: maxFiles2, describeRejection } = latest.current;
1769
1843
  const describe = /* @__PURE__ */ __name((reason, file) => describeRejection?.(reason, file) ?? DEFAULT_REJECTION[reason](file), "describe");
1770
- let room = maxFiles === void 0 ? Number.POSITIVE_INFINITY : maxFiles - itemsRef.current.filter((item) => item.status !== "rejected").length;
1844
+ let room = maxFiles2 === void 0 ? Number.POSITIVE_INFINITY : maxFiles2 - itemsRef.current.filter((item) => item.status !== "rejected").length;
1771
1845
  const staged = [];
1772
1846
  for (const file of Array.from(files)) {
1773
1847
  sequence += 1;
@@ -1779,7 +1853,7 @@ function useAttachments(options = {}) {
1779
1853
  type: file.type,
1780
1854
  progress: 0
1781
1855
  };
1782
- const reason = !acceptsFile(accept2, file) ? "type" : maxBytes !== void 0 && file.size > maxBytes ? "size" : room <= 0 ? "count" : void 0;
1856
+ const reason = !acceptsFile(accept2, file) ? "type" : maxBytes2 !== void 0 && file.size > maxBytes2 ? "size" : room <= 0 ? "count" : void 0;
1783
1857
  if (reason !== void 0) {
1784
1858
  staged.push({
1785
1859
  ...base,
@@ -1843,7 +1917,7 @@ function useAttachments(options = {}) {
1843
1917
  }, [
1844
1918
  start
1845
1919
  ]);
1846
- useEffect3(() => () => {
1920
+ useEffect4(() => () => {
1847
1921
  for (const item of itemsRef.current) release(item);
1848
1922
  }, [
1849
1923
  release
@@ -1878,11 +1952,10 @@ function useAttachments(options = {}) {
1878
1952
  }), [
1879
1953
  add
1880
1954
  ]);
1881
- const accept = options.accept;
1882
1955
  const inputProps = useMemo4(() => ({
1883
1956
  type: "file",
1884
1957
  accept: typeof accept === "string" ? accept : accept?.join(","),
1885
- multiple: options.maxFiles === void 0 || options.maxFiles > 1,
1958
+ multiple: maxFiles === void 0 || maxFiles > 1,
1886
1959
  onChange: /* @__PURE__ */ __name((event) => {
1887
1960
  const input = event.currentTarget;
1888
1961
  add(input.files);
@@ -1890,12 +1963,11 @@ function useAttachments(options = {}) {
1890
1963
  }, "onChange")
1891
1964
  }), [
1892
1965
  accept,
1893
- options.maxFiles,
1966
+ maxFiles,
1894
1967
  add
1895
1968
  ]);
1896
1969
  return useMemo4(() => {
1897
1970
  const ready = items.filter((item) => item.status === "ready" && item.attachment !== void 0);
1898
- const attachments = ready.map((item) => item.attachment);
1899
1971
  return {
1900
1972
  items,
1901
1973
  add,
@@ -1903,9 +1975,8 @@ function useAttachments(options = {}) {
1903
1975
  retry,
1904
1976
  clear,
1905
1977
  isUploading: items.some((item) => item.status === "uploading"),
1906
- attachments,
1907
- refs: attachments.map((attachment) => ({
1908
- mediaId: attachment.mediaId
1978
+ refs: ready.map((item) => ({
1979
+ mediaId: item.attachment.mediaId
1909
1980
  })),
1910
1981
  inputProps,
1911
1982
  dropZoneProps,
@@ -1930,13 +2001,13 @@ __name(useAttachments, "useAttachments");
1930
2001
  import { useMemo as useMemo5 } from "react";
1931
2002
 
1932
2003
  // src/catalog/use-resource.ts
1933
- import { useCallback as useCallback3, useEffect as useEffect4, useRef as useRef4, useState as useState4 } from "react";
1934
- function useResource(load2, key, enabled) {
1935
- const [data, setData] = useState4(void 0);
1936
- const [isLoading, setIsLoading] = useState4(enabled);
1937
- const [error, setError] = useState4(null);
1938
- const loadRef = useRef4(load2);
1939
- loadRef.current = load2;
2004
+ import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef4, useState as useState5 } from "react";
2005
+ function useResource(load3, key, enabled) {
2006
+ const [data, setData] = useState5(void 0);
2007
+ const [isLoading, setIsLoading] = useState5(enabled);
2008
+ const [error, setError] = useState5(null);
2009
+ const loadRef = useRef4(load3);
2010
+ loadRef.current = load3;
1940
2011
  const generation = useRef4(0);
1941
2012
  const refresh = useCallback3(async () => {
1942
2013
  const mine = ++generation.current;
@@ -1953,7 +2024,7 @@ function useResource(load2, key, enabled) {
1953
2024
  if (mine === generation.current) setIsLoading(false);
1954
2025
  }
1955
2026
  }, []);
1956
- useEffect4(() => {
2027
+ useEffect5(() => {
1957
2028
  if (!enabled) return;
1958
2029
  void refresh();
1959
2030
  }, [
@@ -2029,7 +2100,7 @@ function useModels(options = {}) {
2029
2100
  __name(useModels, "useModels");
2030
2101
 
2031
2102
  // src/quota/use-quota.ts
2032
- import { useEffect as useEffect5, useMemo as useMemo7 } from "react";
2103
+ import { useEffect as useEffect6, useMemo as useMemo7 } from "react";
2033
2104
 
2034
2105
  // src/threads/threads-events.ts
2035
2106
  var listeners = /* @__PURE__ */ new WeakMap();
@@ -2057,7 +2128,7 @@ function useQuota(options = {}) {
2057
2128
  const { enabled = true, pollMs } = options;
2058
2129
  const backend = useAgentBackend(options.backend);
2059
2130
  const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "getQuota")(), "", enabled);
2060
- useEffect5(() => {
2131
+ useEffect6(() => {
2061
2132
  if (!enabled) return;
2062
2133
  return onThreadsEvent(backend, (event) => {
2063
2134
  if (event.type === "changed") void refresh();
@@ -2067,7 +2138,7 @@ function useQuota(options = {}) {
2067
2138
  enabled,
2068
2139
  refresh
2069
2140
  ]);
2070
- useEffect5(() => {
2141
+ useEffect6(() => {
2071
2142
  if (!enabled || pollMs === void 0 || pollMs <= 0) return;
2072
2143
  const timer = setInterval(() => void refresh(), pollMs);
2073
2144
  return () => clearInterval(timer);
@@ -2098,7 +2169,7 @@ function useQuota(options = {}) {
2098
2169
  __name(useQuota, "useQuota");
2099
2170
 
2100
2171
  // src/feedback/use-message-feedback.ts
2101
- import { useCallback as useCallback4, useRef as useRef5, useState as useState5 } from "react";
2172
+ import { useCallback as useCallback4, useRef as useRef5, useState as useState6 } from "react";
2102
2173
  function useMessageFeedback(options = {}) {
2103
2174
  const backend = useAgentBackend(options.backend);
2104
2175
  const latest = useRef5({
@@ -2109,9 +2180,9 @@ function useMessageFeedback(options = {}) {
2109
2180
  ...options,
2110
2181
  backend
2111
2182
  };
2112
- const [local, setLocal] = useState5(/* @__PURE__ */ new Map());
2113
- const [pending, setPending] = useState5(/* @__PURE__ */ new Set());
2114
- const [error, setError] = useState5(null);
2183
+ const [local, setLocal] = useState6(/* @__PURE__ */ new Map());
2184
+ const [pending, setPending] = useState6(/* @__PURE__ */ new Set());
2185
+ const [error, setError] = useState6(null);
2115
2186
  const localRef = useRef5(local);
2116
2187
  localRef.current = local;
2117
2188
  const resolved = useRef5(/* @__PURE__ */ new Map());
@@ -2214,13 +2285,13 @@ function metadataOf(message) {
2214
2285
  __name(metadataOf, "metadataOf");
2215
2286
 
2216
2287
  // src/threads/use-threads.ts
2217
- import { useCallback as useCallback5, useEffect as useEffect6, useRef as useRef6, useState as useState6 } from "react";
2288
+ import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef6, useState as useState7 } from "react";
2218
2289
  function useThreads(options = {}) {
2219
2290
  const { enabled = true } = options;
2220
2291
  const backend = useAgentBackend(options.backend);
2221
- const [threads, setThreads] = useState6([]);
2222
- const [isLoading, setIsLoading] = useState6(enabled);
2223
- const [error, setError] = useState6(null);
2292
+ const [threads, setThreads] = useState7([]);
2293
+ const [isLoading, setIsLoading] = useState7(enabled);
2294
+ const [error, setError] = useState7(null);
2224
2295
  const threadsRef = useRef6(threads);
2225
2296
  threadsRef.current = threads;
2226
2297
  const generation = useRef6(0);
@@ -2241,7 +2312,7 @@ function useThreads(options = {}) {
2241
2312
  }, [
2242
2313
  backend
2243
2314
  ]);
2244
- useEffect6(() => {
2315
+ useEffect7(() => {
2245
2316
  if (!enabled) return;
2246
2317
  void refresh();
2247
2318
  return onThreadsEvent(backend, (event) => {
@@ -2358,10 +2429,10 @@ function backgroundRunsFromThread(messages) {
2358
2429
  __name(backgroundRunsFromThread, "backgroundRunsFromThread");
2359
2430
 
2360
2431
  // src/components/chat-input.tsx
2361
- import React2, { useEffect as useEffect8, useState as useState8 } from "react";
2432
+ import React2, { useEffect as useEffect9, useState as useState9 } from "react";
2362
2433
 
2363
2434
  // src/components/use-speech-recognition.ts
2364
- import { useCallback as useCallback6, useEffect as useEffect7, useMemo as useMemo8, useRef as useRef7, useState as useState7 } from "react";
2435
+ import { useCallback as useCallback6, useEffect as useEffect8, useMemo as useMemo8, useRef as useRef7, useState as useState8 } from "react";
2365
2436
  function getRecognitionCtor() {
2366
2437
  if (typeof window === "undefined") return null;
2367
2438
  const scope = window;
@@ -2370,14 +2441,14 @@ function getRecognitionCtor() {
2370
2441
  __name(getRecognitionCtor, "getRecognitionCtor");
2371
2442
  function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
2372
2443
  const recognitionRef = useRef7(null);
2373
- const [isListening, setIsListening] = useState7(false);
2444
+ const [isListening, setIsListening] = useState8(false);
2374
2445
  const ctor = useMemo8(() => getRecognitionCtor(), []);
2375
2446
  const isSupported = ctor !== null;
2376
2447
  const finalRef = useRef7(onFinalTranscript);
2377
2448
  const interimRef = useRef7(onInterimTranscript);
2378
2449
  finalRef.current = onFinalTranscript;
2379
2450
  interimRef.current = onInterimTranscript;
2380
- useEffect7(() => {
2451
+ useEffect8(() => {
2381
2452
  if (!ctor) return;
2382
2453
  const recognition = new ctor();
2383
2454
  recognition.lang = lang;
@@ -2445,8 +2516,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
2445
2516
 
2446
2517
  // src/components/chat-input.tsx
2447
2518
  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] = useState8("");
2449
- const [interim, setInterim] = useState8("");
2519
+ const [value, setValue] = useState9("");
2520
+ const [interim, setInterim] = useState9("");
2450
2521
  const speech = useSpeechRecognition({
2451
2522
  lang: speechLang,
2452
2523
  onFinalTranscript: /* @__PURE__ */ __name((text) => {
@@ -2457,7 +2528,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
2457
2528
  }, "onFinalTranscript"),
2458
2529
  onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
2459
2530
  });
2460
- useEffect8(() => {
2531
+ useEffect9(() => {
2461
2532
  if (!speech.isListening) setInterim("");
2462
2533
  }, [
2463
2534
  speech.isListening
@@ -2524,7 +2595,7 @@ __name(ChatInput, "ChatInput");
2524
2595
  import React3 from "react";
2525
2596
 
2526
2597
  // src/transcript/use-chat-transcript.ts
2527
- import { useCallback as useCallback8, useEffect as useEffect10, useRef as useRef9, useState as useState10 } from "react";
2598
+ import { useCallback as useCallback8, useEffect as useEffect11, useRef as useRef9, useState as useState11 } from "react";
2528
2599
 
2529
2600
  // src/transcript/model.ts
2530
2601
  import { readElicitationInput, validateElicitationAnswer as validateElicitationAnswer2 } from "@dudousxd/nestjs-agent-core";
@@ -3501,10 +3572,10 @@ function formatCostUsd(cost) {
3501
3572
  __name(formatCostUsd, "formatCostUsd");
3502
3573
 
3503
3574
  // src/transcript/use-stick-to-bottom.ts
3504
- import { useCallback as useCallback7, useEffect as useEffect9, useRef as useRef8, useState as useState9 } from "react";
3575
+ import { useCallback as useCallback7, useEffect as useEffect10, useRef as useRef8, useState as useState10 } from "react";
3505
3576
  function useStickToBottom({ contentKey, threshold = 32 }) {
3506
3577
  const containerRef = useRef8(null);
3507
- const [isAtBottom, setIsAtBottom] = useState9(true);
3578
+ const [isAtBottom, setIsAtBottom] = useState10(true);
3508
3579
  const measure = useCallback7(() => {
3509
3580
  const element = containerRef.current;
3510
3581
  if (!element) {
@@ -3531,7 +3602,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
3531
3602
  }, [
3532
3603
  measure
3533
3604
  ]);
3534
- useEffect9(() => {
3605
+ useEffect10(() => {
3535
3606
  if (isAtBottom) {
3536
3607
  scrollToBottom();
3537
3608
  }
@@ -3564,12 +3635,12 @@ function useChatTranscript(options) {
3564
3635
  const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
3565
3636
  const latest = useRef9(options);
3566
3637
  latest.current = options;
3567
- const [visibleCount, setVisibleCount] = useState10(initialVisibleCount);
3568
- const [stopRequested, setStopRequested] = useState10(false);
3638
+ const [visibleCount, setVisibleCount] = useState11(initialVisibleCount);
3639
+ const [stopRequested, setStopRequested] = useState11(false);
3569
3640
  const isStreaming = status === "streaming" || status === "reconnecting";
3570
3641
  const isBusy = status === "submitted" || isStreaming;
3571
3642
  const isEmpty = messages.length === 0;
3572
- useEffect10(() => {
3643
+ useEffect11(() => {
3573
3644
  if (!isBusy) {
3574
3645
  setStopRequested(false);
3575
3646
  }
@@ -3649,12 +3720,12 @@ function useTranscriptItem(options) {
3649
3720
  }
3650
3721
  __name(useTranscriptItem, "useTranscriptItem");
3651
3722
  function useTranscriptItems({ messages, visibleStart, streamingMessageId, options }) {
3652
- const [drafts, setDrafts] = useState10(() => /* @__PURE__ */ new Map());
3653
- const [copied, setCopied] = useState10(() => /* @__PURE__ */ new Set());
3654
- const [openReasoning, setOpenReasoning] = useState10(() => /* @__PURE__ */ new Map());
3655
- const [picks, setPicks] = useState10(() => /* @__PURE__ */ new Map());
3656
- const [settling, setSettling] = useState10(() => /* @__PURE__ */ new Map());
3657
- const [settleErrors, setSettleErrors] = useState10(() => /* @__PURE__ */ new Map());
3723
+ const [drafts, setDrafts] = useState11(() => /* @__PURE__ */ new Map());
3724
+ const [copied, setCopied] = useState11(() => /* @__PURE__ */ new Set());
3725
+ const [openReasoning, setOpenReasoning] = useState11(() => /* @__PURE__ */ new Map());
3726
+ const [picks, setPicks] = useState11(() => /* @__PURE__ */ new Map());
3727
+ const [settling, setSettling] = useState11(() => /* @__PURE__ */ new Map());
3728
+ const [settleErrors, setSettleErrors] = useState11(() => /* @__PURE__ */ new Map());
3658
3729
  const backend = useAgentBackend();
3659
3730
  const handlers = settleHandlers(options, backend);
3660
3731
  const latest = useRef9({
@@ -3672,7 +3743,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3672
3743
  messages
3673
3744
  };
3674
3745
  const copyTimers = useRef9(/* @__PURE__ */ new Map());
3675
- useEffect10(() => () => {
3746
+ useEffect11(() => () => {
3676
3747
  for (const timer of copyTimers.current.values()) {
3677
3748
  clearTimeout(timer);
3678
3749
  }
@@ -4476,18 +4547,18 @@ function toItem(entry) {
4476
4547
  __name(toItem, "toItem");
4477
4548
 
4478
4549
  // src/composer/use-composer-autocomplete.ts
4479
- import { useCallback as useCallback9, useEffect as useEffect11, useId, useLayoutEffect, useMemo as useMemo9, useRef as useRef10, useState as useState11 } from "react";
4550
+ import { useCallback as useCallback9, useEffect as useEffect12, useId, useLayoutEffect, useMemo as useMemo9, useRef as useRef10, useState as useState12 } from "react";
4480
4551
  function useComposerAutocomplete(options) {
4481
4552
  const { value, sources, acceptOnTab = true } = options;
4482
4553
  const latest = useRef10(options);
4483
4554
  latest.current = options;
4484
4555
  const inputRef = useRef10(null);
4485
- const [caret, setCaret] = useState11(value.length);
4486
- const [items, setItems] = useState11([]);
4487
- const [isLoading, setLoading] = useState11(false);
4488
- const [error, setError] = useState11(null);
4489
- const [activeIndex, setActiveIndex] = useState11(0);
4490
- const [dismissedIndex, setDismissedIndex] = useState11(null);
4556
+ const [caret, setCaret] = useState12(value.length);
4557
+ const [items, setItems] = useState12([]);
4558
+ const [isLoading, setLoading] = useState12(false);
4559
+ const [error, setError] = useState12(null);
4560
+ const [activeIndex, setActiveIndex] = useState12(0);
4561
+ const [dismissedIndex, setDismissedIndex] = useState12(null);
4491
4562
  const safeCaret = Math.min(caret, value.length);
4492
4563
  const match = useMemo9(() => findActiveTrigger(value, safeCaret, sources), [
4493
4564
  value,
@@ -4504,7 +4575,7 @@ function useComposerAutocomplete(options) {
4504
4575
  const activeIndexRef = useRef10(activeIndex);
4505
4576
  activeIndexRef.current = activeIndex;
4506
4577
  const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
4507
- useEffect11(() => {
4578
+ useEffect12(() => {
4508
4579
  const current = matchRef.current;
4509
4580
  if (requestKey === null || current === null) {
4510
4581
  setItems([]);
@@ -4714,13 +4785,13 @@ function isPromise(value) {
4714
4785
  __name(isPromise, "isPromise");
4715
4786
 
4716
4787
  // src/presentation/use-tool-catalog.ts
4717
- import { useCallback as useCallback10, useEffect as useEffect12, useMemo as useMemo10, useState as useState12 } from "react";
4718
- var shared = /* @__PURE__ */ new WeakMap();
4719
- function load(client, agent) {
4720
- let byAgent = shared.get(client);
4788
+ import { useCallback as useCallback10, useEffect as useEffect13, useMemo as useMemo10, useState as useState13 } from "react";
4789
+ var shared2 = /* @__PURE__ */ new WeakMap();
4790
+ function load2(client, agent) {
4791
+ let byAgent = shared2.get(client);
4721
4792
  if (byAgent === void 0) {
4722
4793
  byAgent = /* @__PURE__ */ new Map();
4723
- shared.set(client, byAgent);
4794
+ shared2.set(client, byAgent);
4724
4795
  }
4725
4796
  const key = agent ?? "";
4726
4797
  const cached = byAgent.get(key);
@@ -4735,22 +4806,22 @@ function load(client, agent) {
4735
4806
  byAgent.set(key, request);
4736
4807
  return request;
4737
4808
  }
4738
- __name(load, "load");
4809
+ __name(load2, "load");
4739
4810
  function useToolCatalog(options = {}) {
4740
4811
  const { agent, enabled = true } = options;
4741
4812
  const client = useAgentBackend(options.backend);
4742
- const [entries, setEntries] = useState12([]);
4743
- const [isLoading, setLoading] = useState12(enabled);
4744
- const [error, setError] = useState12(null);
4745
- const [generation, setGeneration] = useState12(0);
4746
- useEffect12(() => {
4813
+ const [entries, setEntries] = useState13([]);
4814
+ const [isLoading, setLoading] = useState13(enabled);
4815
+ const [error, setError] = useState13(null);
4816
+ const [generation, setGeneration] = useState13(0);
4817
+ useEffect13(() => {
4747
4818
  if (!enabled) {
4748
4819
  setLoading(false);
4749
4820
  return;
4750
4821
  }
4751
4822
  let cancelled = false;
4752
4823
  setLoading(true);
4753
- load(client, agent).then((loaded) => {
4824
+ load2(client, agent).then((loaded) => {
4754
4825
  if (cancelled) return;
4755
4826
  setEntries(Array.isArray(loaded) ? loaded : []);
4756
4827
  setError(null);
@@ -4770,7 +4841,7 @@ function useToolCatalog(options = {}) {
4770
4841
  generation
4771
4842
  ]);
4772
4843
  const refresh = useCallback10(() => {
4773
- shared.get(client)?.delete(agent ?? "");
4844
+ shared2.get(client)?.delete(agent ?? "");
4774
4845
  setGeneration((current) => current + 1);
4775
4846
  }, [
4776
4847
  client,
@@ -4790,7 +4861,7 @@ function useToolCatalog(options = {}) {
4790
4861
  __name(useToolCatalog, "useToolCatalog");
4791
4862
 
4792
4863
  // src/approvals/countdown.ts
4793
- import { useEffect as useEffect13, useRef as useRef11, useState as useState13 } from "react";
4864
+ import { useEffect as useEffect14, useRef as useRef11, useState as useState14 } from "react";
4794
4865
  function approvalCountdown(expiresAt, now = Date.now()) {
4795
4866
  const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
4796
4867
  if (!Number.isFinite(deadline)) {
@@ -4810,8 +4881,8 @@ function useApprovalCountdown(expiresAt, options = {}) {
4810
4881
  const { intervalMs = 1e3 } = options;
4811
4882
  const nowRef = useRef11(options.now ?? Date.now);
4812
4883
  nowRef.current = options.now ?? Date.now;
4813
- const [state, setState] = useState13(() => approvalCountdown(expiresAt, nowRef.current()));
4814
- useEffect13(() => {
4884
+ const [state, setState] = useState14(() => approvalCountdown(expiresAt, nowRef.current()));
4885
+ useEffect14(() => {
4815
4886
  const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
4816
4887
  const first = read();
4817
4888
  setState(first);
@@ -5076,7 +5147,7 @@ __name(sumUsage, "sumUsage");
5076
5147
 
5077
5148
  // src/use-agent-chat.ts
5078
5149
  import { useChat } from "@ai-sdk/react";
5079
- import { useCallback as useCallback11, useEffect as useEffect14, useMemo as useMemo11, useRef as useRef12, useState as useState14 } from "react";
5150
+ import { useCallback as useCallback11, useEffect as useEffect15, useMemo as useMemo11, useRef as useRef12, useState as useState15 } from "react";
5080
5151
  var localChatSequence = 0;
5081
5152
  function localChatId() {
5082
5153
  localChatSequence += 1;
@@ -5100,22 +5171,22 @@ function useAgentChat(options = {}) {
5100
5171
  }
5101
5172
  }
5102
5173
  const chatId = chatIdRef.current;
5103
- const [runId, setRunId] = useState14(options.resumeRunId);
5174
+ const [runId, setRunId] = useState15(options.resumeRunId);
5104
5175
  const runIdRef = useRef12(runId);
5105
5176
  runIdRef.current = runId;
5106
5177
  const settlingRunIdRef = useRef12(void 0);
5107
5178
  const autoResumeRunIdRef = useRef12(void 0);
5108
- const [activeRunId, setActiveRunId] = useState14(null);
5109
- const [isLoadingHistory, setIsLoadingHistory] = useState14(false);
5110
- const [historyError, setHistoryError] = useState14(null);
5111
- const [threadModel, setThreadModel] = useState14(null);
5112
- const [pickedModel, setPickedModel] = useState14(void 0);
5179
+ const [activeRunId, setActiveRunId] = useState15(null);
5180
+ const [isLoadingHistory, setIsLoadingHistory] = useState15(false);
5181
+ const [historyError, setHistoryError] = useState15(null);
5182
+ const [threadModel, setThreadModel] = useState15(null);
5183
+ const [pickedModel, setPickedModel] = useState15(void 0);
5113
5184
  const pickedModelRef = useRef12(pickedModel);
5114
5185
  pickedModelRef.current = pickedModel;
5115
5186
  const pendingPin = useRef12(void 0);
5116
5187
  const regenerateNext = useRef12(false);
5117
5188
  const currentThreadId = useCallback11(() => latest.current.threadId ?? createdThreadId.current, []);
5118
- const [connection, setConnection] = useState14({
5189
+ const [connection, setConnection] = useState15({
5119
5190
  status: "live"
5120
5191
  });
5121
5192
  const resyncAfterSettle = useRef12(false);
@@ -5242,7 +5313,7 @@ function useAgentChat(options = {}) {
5242
5313
  }
5243
5314
  __name(resyncFromThread, "resyncFromThread");
5244
5315
  const firstChatId = useRef12(chatId);
5245
- useEffect14(() => {
5316
+ useEffect15(() => {
5246
5317
  if (chatId === firstChatId.current) return;
5247
5318
  firstChatId.current = chatId;
5248
5319
  setRunId(void 0);
@@ -5255,7 +5326,7 @@ function useAgentChat(options = {}) {
5255
5326
  }, [
5256
5327
  chatId
5257
5328
  ]);
5258
- useEffect14(() => {
5329
+ useEffect15(() => {
5259
5330
  const threadId = options.threadId;
5260
5331
  if (threadId === void 0) return;
5261
5332
  if (threadId === createdThreadId.current) return;
@@ -5325,7 +5396,7 @@ function useAgentChat(options = {}) {
5325
5396
  toolCallId,
5326
5397
  output
5327
5398
  }), []);
5328
- const [backgroundRuns, setBackgroundRuns] = useState14([]);
5399
+ const [backgroundRuns, setBackgroundRuns] = useState15([]);
5329
5400
  const refreshBackground = useCallback11(async () => {
5330
5401
  const threadId = currentThreadId();
5331
5402
  if (threadId === void 0) {
@@ -5352,7 +5423,7 @@ function useAgentChat(options = {}) {
5352
5423
  ]);
5353
5424
  backgroundRef.current = refreshBackground;
5354
5425
  const isWorking = backgroundRuns.some((run) => run.status === "running");
5355
- useEffect14(() => {
5426
+ useEffect15(() => {
5356
5427
  if (options.background !== true || options.threadId === void 0) {
5357
5428
  return;
5358
5429
  }
@@ -5363,7 +5434,7 @@ function useAgentChat(options = {}) {
5363
5434
  chatId,
5364
5435
  refreshBackground
5365
5436
  ]);
5366
- useEffect14(() => {
5437
+ useEffect15(() => {
5367
5438
  const every = latest.current.backgroundPollMs ?? 5e3;
5368
5439
  if (latest.current.background !== true || !isWorking || every <= 0) {
5369
5440
  return;
@@ -5489,7 +5560,7 @@ function useAgentChat(options = {}) {
5489
5560
  client,
5490
5561
  currentThreadId
5491
5562
  ]);
5492
- const [modelsWanted, setModelsWanted] = useState14(false);
5563
+ const [modelsWanted, setModelsWanted] = useState15(false);
5493
5564
  const modelsWantedRef = useRef12(modelsWanted);
5494
5565
  modelsWantedRef.current = modelsWanted;
5495
5566
  const catalog = useModels({
@@ -5545,8 +5616,8 @@ function useAgentChat(options = {}) {
5545
5616
  ...options.composer,
5546
5617
  backend: client
5547
5618
  });
5548
- const [text, setText] = useState14("");
5549
- const blockedBy = blocked != null ? "quota" : files.isUploading ? "uploading" : isBusy ? "busy" : text.trim().length === 0 && files.attachments.length === 0 ? "empty" : null;
5619
+ const [text, setText] = useState15("");
5620
+ const blockedBy = blocked != null ? "quota" : files.isUploading ? "uploading" : isBusy ? "busy" : text.trim().length === 0 && files.refs.length === 0 ? "empty" : null;
5550
5621
  const composerRef = useRef12({
5551
5622
  text,
5552
5623
  files,
@@ -5722,6 +5793,7 @@ export {
5722
5793
  toolCatalogFrom,
5723
5794
  useAgentBackend,
5724
5795
  useAgentChat,
5796
+ useAgentConfig,
5725
5797
  useAgents,
5726
5798
  useAmbientRenderUi,
5727
5799
  useApprovalCountdown,