@dudousxd/nestjs-agent-react 0.15.0 → 0.16.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
@@ -147,6 +147,15 @@ var AgentClient = class {
147
147
  truncateFromMessage(threadId, messageId) {
148
148
  return this.request("DELETE", `/agent/threads/${encodeURIComponent(threadId)}/from/${encodeURIComponent(messageId)}`);
149
149
  }
150
+ /** `GET /agent/models?agent=` — the models this caller may pick, grouped by provider. */
151
+ listModels(agent) {
152
+ const query = agent === void 0 ? "" : `?agent=${encodeURIComponent(agent)}`;
153
+ return this.request("GET", `/agent/models${query}`);
154
+ }
155
+ /** `GET /agent/agents` — the registered agents, the default one flagged. */
156
+ listAgents() {
157
+ return this.request("GET", "/agent/agents");
158
+ }
150
159
  getQuotaToday() {
151
160
  return this.request("GET", "/agent/quota/today");
152
161
  }
@@ -994,28 +1003,128 @@ function requireBackendMethod(backend, name) {
994
1003
  }
995
1004
  __name(requireBackendMethod, "requireBackendMethod");
996
1005
 
1006
+ // src/catalog/use-agents.ts
1007
+ import { useMemo } from "react";
1008
+
1009
+ // src/catalog/use-resource.ts
1010
+ import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
1011
+ function useResource(load2, key, enabled) {
1012
+ const [data, setData] = useState2(void 0);
1013
+ const [isLoading, setIsLoading] = useState2(enabled);
1014
+ const [error, setError] = useState2(null);
1015
+ const loadRef = useRef2(load2);
1016
+ loadRef.current = load2;
1017
+ const generation = useRef2(0);
1018
+ const refresh = useCallback(async () => {
1019
+ const mine = ++generation.current;
1020
+ setIsLoading(true);
1021
+ try {
1022
+ const value = await loadRef.current();
1023
+ if (mine !== generation.current) return;
1024
+ setData(value);
1025
+ setError(null);
1026
+ } catch (caught) {
1027
+ if (mine !== generation.current) return;
1028
+ setError(caught instanceof Error ? caught : new Error(String(caught)));
1029
+ } finally {
1030
+ if (mine === generation.current) setIsLoading(false);
1031
+ }
1032
+ }, []);
1033
+ useEffect2(() => {
1034
+ if (!enabled) return;
1035
+ void refresh();
1036
+ }, [
1037
+ enabled,
1038
+ key,
1039
+ refresh
1040
+ ]);
1041
+ return {
1042
+ data,
1043
+ isLoading,
1044
+ error,
1045
+ refresh
1046
+ };
1047
+ }
1048
+ __name(useResource, "useResource");
1049
+
1050
+ // src/catalog/use-agents.ts
1051
+ function useAgents(options) {
1052
+ const { backend, enabled = true } = options;
1053
+ const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listAgents")(), "", enabled);
1054
+ return useMemo(() => {
1055
+ const agents = data ?? [];
1056
+ return {
1057
+ agents,
1058
+ defaultAgent: agents.find((agent) => agent.isDefault === true)?.name ?? null,
1059
+ isLoading,
1060
+ error,
1061
+ refresh
1062
+ };
1063
+ }, [
1064
+ data,
1065
+ isLoading,
1066
+ error,
1067
+ refresh
1068
+ ]);
1069
+ }
1070
+ __name(useAgents, "useAgents");
1071
+
1072
+ // src/catalog/use-models.ts
1073
+ import { useMemo as useMemo2 } from "react";
1074
+ function useModels(options) {
1075
+ const { backend, agent, enabled = true } = options;
1076
+ const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listModels")(agent), `${agent ?? ""}`, enabled);
1077
+ return useMemo2(() => {
1078
+ const providers = data?.providers ?? [];
1079
+ const models = providers.flatMap((provider) => provider.models.map((model) => ({
1080
+ ...model,
1081
+ providerId: provider.id,
1082
+ providerLabel: provider.label
1083
+ })));
1084
+ const byId = new Map(models.map((model) => [
1085
+ model.id,
1086
+ model
1087
+ ]));
1088
+ return {
1089
+ providers,
1090
+ models,
1091
+ defaultModel: data?.default ?? null,
1092
+ find: /* @__PURE__ */ __name((id) => id == null ? void 0 : byId.get(id), "find"),
1093
+ isLoading,
1094
+ error,
1095
+ refresh
1096
+ };
1097
+ }, [
1098
+ data,
1099
+ isLoading,
1100
+ error,
1101
+ refresh
1102
+ ]);
1103
+ }
1104
+ __name(useModels, "useModels");
1105
+
997
1106
  // src/feedback/use-message-feedback.ts
998
- import { useCallback, useRef as useRef2, useState as useState2 } from "react";
1107
+ import { useCallback as useCallback2, useRef as useRef3, useState as useState3 } from "react";
999
1108
  function useMessageFeedback(options) {
1000
- const latest = useRef2(options);
1109
+ const latest = useRef3(options);
1001
1110
  latest.current = options;
1002
- const [local, setLocal] = useState2(/* @__PURE__ */ new Map());
1003
- const [pending, setPending] = useState2(/* @__PURE__ */ new Set());
1004
- const [error, setError] = useState2(null);
1005
- const localRef = useRef2(local);
1111
+ const [local, setLocal] = useState3(/* @__PURE__ */ new Map());
1112
+ const [pending, setPending] = useState3(/* @__PURE__ */ new Set());
1113
+ const [error, setError] = useState3(null);
1114
+ const localRef = useRef3(local);
1006
1115
  localRef.current = local;
1007
- const resolved = useRef2(/* @__PURE__ */ new Map());
1008
- const feedbackOf = useCallback((message) => {
1116
+ const resolved = useRef3(/* @__PURE__ */ new Map());
1117
+ const feedbackOf = useCallback2((message) => {
1009
1118
  const mine = local.get(message.id);
1010
1119
  if (mine !== void 0) return mine.feedback;
1011
1120
  return metadataOf(message).feedback ?? null;
1012
1121
  }, [
1013
1122
  local
1014
1123
  ]);
1015
- const isPending = useCallback((message) => pending.has(message.id), [
1124
+ const isPending = useCallback2((message) => pending.has(message.id), [
1016
1125
  pending
1017
1126
  ]);
1018
- const storedIdFor = useCallback(async (message) => {
1127
+ const storedIdFor = useCallback2(async (message) => {
1019
1128
  const runId = metadataOf(message).runId;
1020
1129
  if (runId === void 0) return message.id;
1021
1130
  const known = resolved.current.get(message.id);
@@ -1035,7 +1144,7 @@ function useMessageFeedback(options) {
1035
1144
  resolved.current.set(message.id, row.id);
1036
1145
  return row.id;
1037
1146
  }, []);
1038
- const rate = useCallback(async (message, value, comment) => {
1147
+ const rate = useCallback2(async (message, value, comment) => {
1039
1148
  const setFeedback = requireBackendMethod(latest.current.backend, "setMessageFeedback");
1040
1149
  const had = localRef.current.get(message.id);
1041
1150
  const optimistic = value === null ? null : {
@@ -1081,7 +1190,7 @@ function useMessageFeedback(options) {
1081
1190
  }, [
1082
1191
  storedIdFor
1083
1192
  ]);
1084
- const toggle = useCallback((message, value) => {
1193
+ const toggle = useCallback2((message, value) => {
1085
1194
  const mine = localRef.current.get(message.id);
1086
1195
  const current = mine !== void 0 ? mine.feedback : metadataOf(message).feedback ?? null;
1087
1196
  return rate(message, current?.value === value ? null : value);
@@ -1125,16 +1234,16 @@ function onThreadsEvent(backend, listener) {
1125
1234
  __name(onThreadsEvent, "onThreadsEvent");
1126
1235
 
1127
1236
  // src/threads/use-threads.ts
1128
- import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef3, useState as useState3 } from "react";
1237
+ import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef4, useState as useState4 } from "react";
1129
1238
  function useThreads(options) {
1130
1239
  const { backend, enabled = true } = options;
1131
- const [threads, setThreads] = useState3([]);
1132
- const [isLoading, setIsLoading] = useState3(enabled);
1133
- const [error, setError] = useState3(null);
1134
- const threadsRef = useRef3(threads);
1240
+ const [threads, setThreads] = useState4([]);
1241
+ const [isLoading, setIsLoading] = useState4(enabled);
1242
+ const [error, setError] = useState4(null);
1243
+ const threadsRef = useRef4(threads);
1135
1244
  threadsRef.current = threads;
1136
- const generation = useRef3(0);
1137
- const refresh = useCallback2(async () => {
1245
+ const generation = useRef4(0);
1246
+ const refresh = useCallback3(async () => {
1138
1247
  const mine = ++generation.current;
1139
1248
  setIsLoading(true);
1140
1249
  try {
@@ -1151,7 +1260,7 @@ function useThreads(options) {
1151
1260
  }, [
1152
1261
  backend
1153
1262
  ]);
1154
- useEffect2(() => {
1263
+ useEffect3(() => {
1155
1264
  if (!enabled) return;
1156
1265
  void refresh();
1157
1266
  return onThreadsEvent(backend, (event) => {
@@ -1171,7 +1280,7 @@ function useThreads(options) {
1171
1280
  enabled,
1172
1281
  refresh
1173
1282
  ]);
1174
- const rename = useCallback2(async (id, title) => {
1283
+ const rename = useCallback3(async (id, title) => {
1175
1284
  const before = threadsRef.current;
1176
1285
  setThreads((current) => current.map((thread) => thread.id === id ? {
1177
1286
  ...thread,
@@ -1193,7 +1302,7 @@ function useThreads(options) {
1193
1302
  }, [
1194
1303
  backend
1195
1304
  ]);
1196
- const remove = useCallback2(async (id) => {
1305
+ const remove = useCallback3(async (id) => {
1197
1306
  const before = threadsRef.current;
1198
1307
  setThreads((current) => current.filter((thread) => thread.id !== id));
1199
1308
  try {
@@ -1268,10 +1377,10 @@ function backgroundRunsFromThread(messages) {
1268
1377
  __name(backgroundRunsFromThread, "backgroundRunsFromThread");
1269
1378
 
1270
1379
  // src/components/chat-input.tsx
1271
- import React2, { useEffect as useEffect4, useState as useState5 } from "react";
1380
+ import React2, { useEffect as useEffect5, useState as useState6 } from "react";
1272
1381
 
1273
1382
  // src/components/use-speech-recognition.ts
1274
- import { useCallback as useCallback3, useEffect as useEffect3, useMemo, useRef as useRef4, useState as useState4 } from "react";
1383
+ import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef5, useState as useState5 } from "react";
1275
1384
  function getRecognitionCtor() {
1276
1385
  if (typeof window === "undefined") return null;
1277
1386
  const scope = window;
@@ -1279,15 +1388,15 @@ function getRecognitionCtor() {
1279
1388
  }
1280
1389
  __name(getRecognitionCtor, "getRecognitionCtor");
1281
1390
  function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
1282
- const recognitionRef = useRef4(null);
1283
- const [isListening, setIsListening] = useState4(false);
1284
- const ctor = useMemo(() => getRecognitionCtor(), []);
1391
+ const recognitionRef = useRef5(null);
1392
+ const [isListening, setIsListening] = useState5(false);
1393
+ const ctor = useMemo3(() => getRecognitionCtor(), []);
1285
1394
  const isSupported = ctor !== null;
1286
- const finalRef = useRef4(onFinalTranscript);
1287
- const interimRef = useRef4(onInterimTranscript);
1395
+ const finalRef = useRef5(onFinalTranscript);
1396
+ const interimRef = useRef5(onInterimTranscript);
1288
1397
  finalRef.current = onFinalTranscript;
1289
1398
  interimRef.current = onInterimTranscript;
1290
- useEffect3(() => {
1399
+ useEffect4(() => {
1291
1400
  if (!ctor) return;
1292
1401
  const recognition = new ctor();
1293
1402
  recognition.lang = lang;
@@ -1326,7 +1435,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
1326
1435
  ctor,
1327
1436
  lang
1328
1437
  ]);
1329
- const start = useCallback3(() => {
1438
+ const start = useCallback4(() => {
1330
1439
  const recognition = recognitionRef.current;
1331
1440
  if (!recognition) return;
1332
1441
  try {
@@ -1336,7 +1445,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
1336
1445
  console.warn("SpeechRecognition start failed", error);
1337
1446
  }
1338
1447
  }, []);
1339
- const stop = useCallback3(() => {
1448
+ const stop = useCallback4(() => {
1340
1449
  const recognition = recognitionRef.current;
1341
1450
  if (!recognition) return;
1342
1451
  try {
@@ -1355,8 +1464,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
1355
1464
 
1356
1465
  // src/components/chat-input.tsx
1357
1466
  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 }) {
1358
- const [value, setValue] = useState5("");
1359
- const [interim, setInterim] = useState5("");
1467
+ const [value, setValue] = useState6("");
1468
+ const [interim, setInterim] = useState6("");
1360
1469
  const speech = useSpeechRecognition({
1361
1470
  lang: speechLang,
1362
1471
  onFinalTranscript: /* @__PURE__ */ __name((text) => {
@@ -1367,7 +1476,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
1367
1476
  }, "onFinalTranscript"),
1368
1477
  onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
1369
1478
  });
1370
- useEffect4(() => {
1479
+ useEffect5(() => {
1371
1480
  if (!speech.isListening) setInterim("");
1372
1481
  }, [
1373
1482
  speech.isListening
@@ -1434,7 +1543,7 @@ __name(ChatInput, "ChatInput");
1434
1543
  import React3 from "react";
1435
1544
 
1436
1545
  // src/transcript/use-chat-transcript.ts
1437
- import { useCallback as useCallback5, useEffect as useEffect6, useRef as useRef6, useState as useState7 } from "react";
1546
+ import { useCallback as useCallback6, useEffect as useEffect7, useRef as useRef7, useState as useState8 } from "react";
1438
1547
 
1439
1548
  // src/transcript/model.ts
1440
1549
  import { readElicitationInput, validateElicitationAnswer as validateElicitationAnswer2 } from "@dudousxd/nestjs-agent-core";
@@ -2411,11 +2520,11 @@ function formatCostUsd(cost) {
2411
2520
  __name(formatCostUsd, "formatCostUsd");
2412
2521
 
2413
2522
  // src/transcript/use-stick-to-bottom.ts
2414
- import { useCallback as useCallback4, useEffect as useEffect5, useRef as useRef5, useState as useState6 } from "react";
2523
+ import { useCallback as useCallback5, useEffect as useEffect6, useRef as useRef6, useState as useState7 } from "react";
2415
2524
  function useStickToBottom({ contentKey, threshold = 32 }) {
2416
- const containerRef = useRef5(null);
2417
- const [isAtBottom, setIsAtBottom] = useState6(true);
2418
- const measure = useCallback4(() => {
2525
+ const containerRef = useRef6(null);
2526
+ const [isAtBottom, setIsAtBottom] = useState7(true);
2527
+ const measure = useCallback5(() => {
2419
2528
  const element = containerRef.current;
2420
2529
  if (!element) {
2421
2530
  return;
@@ -2425,7 +2534,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
2425
2534
  }, [
2426
2535
  threshold
2427
2536
  ]);
2428
- const scrollToBottom = useCallback4(() => {
2537
+ const scrollToBottom = useCallback5(() => {
2429
2538
  const element = containerRef.current;
2430
2539
  if (!element) {
2431
2540
  return;
@@ -2433,7 +2542,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
2433
2542
  element.scrollTop = element.scrollHeight;
2434
2543
  setIsAtBottom(true);
2435
2544
  }, []);
2436
- const setContainer = useCallback4((element) => {
2545
+ const setContainer = useCallback5((element) => {
2437
2546
  containerRef.current = element;
2438
2547
  if (element) {
2439
2548
  measure();
@@ -2441,7 +2550,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
2441
2550
  }, [
2442
2551
  measure
2443
2552
  ]);
2444
- useEffect5(() => {
2553
+ useEffect6(() => {
2445
2554
  if (isAtBottom) {
2446
2555
  scrollToBottom();
2447
2556
  }
@@ -2450,7 +2559,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
2450
2559
  isAtBottom,
2451
2560
  scrollToBottom
2452
2561
  ]);
2453
- const getContainerProps = useCallback4(() => ({
2562
+ const getContainerProps = useCallback5(() => ({
2454
2563
  ref: setContainer,
2455
2564
  onScroll: measure
2456
2565
  }), [
@@ -2472,14 +2581,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
2472
2581
  var DEFAULT_COPY_RESET_MS = 1500;
2473
2582
  function useChatTranscript(options) {
2474
2583
  const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
2475
- const latest = useRef6(options);
2584
+ const latest = useRef7(options);
2476
2585
  latest.current = options;
2477
- const [visibleCount, setVisibleCount] = useState7(initialVisibleCount);
2478
- const [stopRequested, setStopRequested] = useState7(false);
2586
+ const [visibleCount, setVisibleCount] = useState8(initialVisibleCount);
2587
+ const [stopRequested, setStopRequested] = useState8(false);
2479
2588
  const isStreaming = status === "streaming" || status === "reconnecting";
2480
2589
  const isBusy = status === "submitted" || isStreaming;
2481
2590
  const isEmpty = messages.length === 0;
2482
- useEffect6(() => {
2591
+ useEffect7(() => {
2483
2592
  if (!isBusy) {
2484
2593
  setStopRequested(false);
2485
2594
  }
@@ -2496,7 +2605,7 @@ function useChatTranscript(options) {
2496
2605
  streamingMessageId,
2497
2606
  options
2498
2607
  });
2499
- const stop = useCallback5(() => {
2608
+ const stop = useCallback6(() => {
2500
2609
  const current = latest.current;
2501
2610
  if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
2502
2611
  return;
@@ -2504,8 +2613,8 @@ function useChatTranscript(options) {
2504
2613
  setStopRequested(true);
2505
2614
  void current.onStop?.();
2506
2615
  }, []);
2507
- const loadEarlier = useCallback5(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
2508
- const showAll = useCallback5(() => setVisibleCount(latest.current.messages.length), []);
2616
+ const loadEarlier = useCallback6(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
2617
+ const showAll = useCallback6(() => setVisibleCount(latest.current.messages.length), []);
2509
2618
  const scroll = useStickToBottom({
2510
2619
  contentKey: contentSignature(messages),
2511
2620
  ...stickToBottomThreshold !== void 0 ? {
@@ -2541,7 +2650,7 @@ function useChatTranscript(options) {
2541
2650
  __name(useChatTranscript, "useChatTranscript");
2542
2651
  function useTranscriptItem(options) {
2543
2652
  const { message, isStreaming = false } = options;
2544
- const messagesRef = useRef6([
2653
+ const messagesRef = useRef7([
2545
2654
  message
2546
2655
  ]);
2547
2656
  if (messagesRef.current[0] !== message) {
@@ -2559,13 +2668,13 @@ function useTranscriptItem(options) {
2559
2668
  }
2560
2669
  __name(useTranscriptItem, "useTranscriptItem");
2561
2670
  function useTranscriptItems({ messages, visibleStart, streamingMessageId, options }) {
2562
- const [drafts, setDrafts] = useState7(() => /* @__PURE__ */ new Map());
2563
- const [copied, setCopied] = useState7(() => /* @__PURE__ */ new Set());
2564
- const [openReasoning, setOpenReasoning] = useState7(() => /* @__PURE__ */ new Map());
2565
- const [picks, setPicks] = useState7(() => /* @__PURE__ */ new Map());
2566
- const [settling, setSettling] = useState7(() => /* @__PURE__ */ new Map());
2567
- const [settleErrors, setSettleErrors] = useState7(() => /* @__PURE__ */ new Map());
2568
- const latest = useRef6({
2671
+ const [drafts, setDrafts] = useState8(() => /* @__PURE__ */ new Map());
2672
+ const [copied, setCopied] = useState8(() => /* @__PURE__ */ new Set());
2673
+ const [openReasoning, setOpenReasoning] = useState8(() => /* @__PURE__ */ new Map());
2674
+ const [picks, setPicks] = useState8(() => /* @__PURE__ */ new Map());
2675
+ const [settling, setSettling] = useState8(() => /* @__PURE__ */ new Map());
2676
+ const [settleErrors, setSettleErrors] = useState8(() => /* @__PURE__ */ new Map());
2677
+ const latest = useRef7({
2569
2678
  options,
2570
2679
  drafts,
2571
2680
  picks,
@@ -2577,23 +2686,23 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2577
2686
  picks,
2578
2687
  messages
2579
2688
  };
2580
- const copyTimers = useRef6(/* @__PURE__ */ new Map());
2581
- useEffect6(() => () => {
2689
+ const copyTimers = useRef7(/* @__PURE__ */ new Map());
2690
+ useEffect7(() => () => {
2582
2691
  for (const timer of copyTimers.current.values()) {
2583
2692
  clearTimeout(timer);
2584
2693
  }
2585
2694
  copyTimers.current.clear();
2586
2695
  }, []);
2587
- const callbackCache = useRef6(/* @__PURE__ */ new Map());
2588
- const reasoningToggleCache = useRef6(/* @__PURE__ */ new Map());
2589
- const toggleReasoning = useCallback5((key, open) => {
2696
+ const callbackCache = useRef7(/* @__PURE__ */ new Map());
2697
+ const reasoningToggleCache = useRef7(/* @__PURE__ */ new Map());
2698
+ const toggleReasoning = useCallback6((key, open) => {
2590
2699
  setOpenReasoning((current) => {
2591
2700
  const next = new Map(current);
2592
2701
  next.set(key, open ?? !(current.get(key) ?? false));
2593
2702
  return next;
2594
2703
  });
2595
2704
  }, []);
2596
- const stableToggle = useCallback5((key) => {
2705
+ const stableToggle = useCallback6((key) => {
2597
2706
  let cached = reasoningToggleCache.current.get(key);
2598
2707
  if (!cached) {
2599
2708
  cached = /* @__PURE__ */ __name((open) => toggleReasoning(key, open), "cached");
@@ -2603,10 +2712,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2603
2712
  }, [
2604
2713
  toggleReasoning
2605
2714
  ]);
2606
- const pick = useCallback5((toolCallId, questionId, values) => {
2715
+ const pick = useCallback6((toolCallId, questionId, values) => {
2607
2716
  setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
2608
2717
  }, []);
2609
- const settle = useCallback5((toolCallId, action, send) => {
2718
+ const settle = useCallback6((toolCallId, action, send) => {
2610
2719
  setSettleErrors((current) => {
2611
2720
  if (!current.has(toolCallId)) {
2612
2721
  return current;
@@ -2630,7 +2739,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2630
2739
  failed(error);
2631
2740
  }
2632
2741
  }, []);
2633
- const answer = useCallback5((toolCallId) => {
2742
+ const answer = useCallback6((toolCallId) => {
2634
2743
  const current = latest.current;
2635
2744
  const onAnswer = current.options.onAnswer;
2636
2745
  if (!onAnswer) {
@@ -2640,7 +2749,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2640
2749
  }, [
2641
2750
  settle
2642
2751
  ]);
2643
- const skip = useCallback5((toolCallId) => {
2752
+ const skip = useCallback6((toolCallId) => {
2644
2753
  const onSkip = latest.current.options.onSkip;
2645
2754
  if (onSkip) {
2646
2755
  settle(toolCallId, "skip", () => onSkip(toolCallId));
@@ -2648,7 +2757,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2648
2757
  }, [
2649
2758
  settle
2650
2759
  ]);
2651
- const approve = useCallback5((toolCallId, options2) => {
2760
+ const approve = useCallback6((toolCallId, options2) => {
2652
2761
  const onApprove = latest.current.options.onApprove;
2653
2762
  if (onApprove) {
2654
2763
  settle(toolCallId, "approve", () => options2 === void 0 ? onApprove(toolCallId) : onApprove(toolCallId, options2));
@@ -2656,7 +2765,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2656
2765
  }, [
2657
2766
  settle
2658
2767
  ]);
2659
- const reject = useCallback5((toolCallId) => {
2768
+ const reject = useCallback6((toolCallId) => {
2660
2769
  const onReject = latest.current.options.onReject;
2661
2770
  if (onReject) {
2662
2771
  settle(toolCallId, "reject", () => onReject(toolCallId));
@@ -2664,7 +2773,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2664
2773
  }, [
2665
2774
  settle
2666
2775
  ]);
2667
- const callbacksFor = useCallback5((id) => {
2776
+ const callbacksFor = useCallback6((id) => {
2668
2777
  const cached = callbackCache.current.get(id);
2669
2778
  if (cached) {
2670
2779
  return cached;
@@ -3321,35 +3430,35 @@ function toItem(entry) {
3321
3430
  __name(toItem, "toItem");
3322
3431
 
3323
3432
  // src/composer/use-composer-autocomplete.ts
3324
- import { useCallback as useCallback6, useEffect as useEffect7, useId, useLayoutEffect, useMemo as useMemo2, useRef as useRef7, useState as useState8 } from "react";
3433
+ import { useCallback as useCallback7, useEffect as useEffect8, useId, useLayoutEffect, useMemo as useMemo4, useRef as useRef8, useState as useState9 } from "react";
3325
3434
  function useComposerAutocomplete(options) {
3326
3435
  const { value, sources, acceptOnTab = true } = options;
3327
- const latest = useRef7(options);
3436
+ const latest = useRef8(options);
3328
3437
  latest.current = options;
3329
- const inputRef = useRef7(null);
3330
- const [caret, setCaret] = useState8(value.length);
3331
- const [items, setItems] = useState8([]);
3332
- const [isLoading, setLoading] = useState8(false);
3333
- const [error, setError] = useState8(null);
3334
- const [activeIndex, setActiveIndex] = useState8(0);
3335
- const [dismissedIndex, setDismissedIndex] = useState8(null);
3438
+ const inputRef = useRef8(null);
3439
+ const [caret, setCaret] = useState9(value.length);
3440
+ const [items, setItems] = useState9([]);
3441
+ const [isLoading, setLoading] = useState9(false);
3442
+ const [error, setError] = useState9(null);
3443
+ const [activeIndex, setActiveIndex] = useState9(0);
3444
+ const [dismissedIndex, setDismissedIndex] = useState9(null);
3336
3445
  const safeCaret = Math.min(caret, value.length);
3337
- const match = useMemo2(() => findActiveTrigger(value, safeCaret, sources), [
3446
+ const match = useMemo4(() => findActiveTrigger(value, safeCaret, sources), [
3338
3447
  value,
3339
3448
  safeCaret,
3340
3449
  sources
3341
3450
  ]);
3342
3451
  const isActive = match !== null && dismissedIndex !== match.index;
3343
- const matchRef = useRef7(match);
3452
+ const matchRef = useRef8(match);
3344
3453
  matchRef.current = match;
3345
- const caretRef = useRef7(safeCaret);
3454
+ const caretRef = useRef8(safeCaret);
3346
3455
  caretRef.current = safeCaret;
3347
- const itemsRef = useRef7(items);
3456
+ const itemsRef = useRef8(items);
3348
3457
  itemsRef.current = items;
3349
- const activeIndexRef = useRef7(activeIndex);
3458
+ const activeIndexRef = useRef8(activeIndex);
3350
3459
  activeIndexRef.current = activeIndex;
3351
3460
  const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
3352
- useEffect7(() => {
3461
+ useEffect8(() => {
3353
3462
  const current = matchRef.current;
3354
3463
  if (requestKey === null || current === null) {
3355
3464
  setItems([]);
@@ -3399,23 +3508,23 @@ function useComposerAutocomplete(options) {
3399
3508
  const activeItem = isOpen ? items[activeIndex] ?? null : null;
3400
3509
  const reactId = useId();
3401
3510
  const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
3402
- const optionId = useCallback6((index) => `${listboxId}-option-${index}`, [
3511
+ const optionId = useCallback7((index) => `${listboxId}-option-${index}`, [
3403
3512
  listboxId
3404
3513
  ]);
3405
- const highlight = useCallback6((index) => {
3514
+ const highlight = useCallback7((index) => {
3406
3515
  const total = itemsRef.current.length;
3407
3516
  if (total === 0) return;
3408
3517
  setActiveIndex((index % total + total) % total);
3409
3518
  }, []);
3410
- const moveHighlight = useCallback6((delta) => highlight(activeIndexRef.current + delta), [
3519
+ const moveHighlight = useCallback7((delta) => highlight(activeIndexRef.current + delta), [
3411
3520
  highlight
3412
3521
  ]);
3413
- const dismiss = useCallback6(() => {
3522
+ const dismiss = useCallback7(() => {
3414
3523
  const current = matchRef.current;
3415
3524
  if (current) setDismissedIndex(current.index);
3416
3525
  }, []);
3417
- const pendingCaret = useRef7(null);
3418
- const accept = useCallback6((item) => {
3526
+ const pendingCaret = useRef8(null);
3527
+ const accept = useCallback7((item) => {
3419
3528
  const current = matchRef.current;
3420
3529
  if (!current) return;
3421
3530
  const chosen = item ?? itemsRef.current[activeIndexRef.current];
@@ -3432,10 +3541,10 @@ function useComposerAutocomplete(options) {
3432
3541
  pendingCaret.current = null;
3433
3542
  inputRef.current?.setSelectionRange(position, position);
3434
3543
  });
3435
- const readCaret = useCallback6((element) => {
3544
+ const readCaret = useCallback7((element) => {
3436
3545
  setCaret(element.selectionStart ?? element.value.length);
3437
3546
  }, []);
3438
- const onKeyDown = useCallback6((event) => {
3547
+ const onKeyDown = useCallback7((event) => {
3439
3548
  if (!isOpen) return;
3440
3549
  const hasItems = itemsRef.current.length > 0;
3441
3550
  switch (event.key) {
@@ -3473,23 +3582,23 @@ function useComposerAutocomplete(options) {
3473
3582
  dismiss,
3474
3583
  moveHighlight
3475
3584
  ]);
3476
- const onChange = useCallback6((event) => {
3585
+ const onChange = useCallback7((event) => {
3477
3586
  readCaret(event.target);
3478
3587
  const next = findActiveTrigger(event.target.value, event.target.selectionStart ?? event.target.value.length, latest.current.sources);
3479
3588
  setDismissedIndex((current) => current !== null && next?.index === current ? current : null);
3480
3589
  }, [
3481
3590
  readCaret
3482
3591
  ]);
3483
- const onSelect = useCallback6((event) => readCaret(event.currentTarget), [
3592
+ const onSelect = useCallback7((event) => readCaret(event.currentTarget), [
3484
3593
  readCaret
3485
3594
  ]);
3486
- const onClick = useCallback6((event) => readCaret(event.currentTarget), [
3595
+ const onClick = useCallback7((event) => readCaret(event.currentTarget), [
3487
3596
  readCaret
3488
3597
  ]);
3489
- const setInput = useCallback6((element) => {
3598
+ const setInput = useCallback7((element) => {
3490
3599
  inputRef.current = element;
3491
3600
  }, []);
3492
- const getInputProps = useCallback6(() => ({
3601
+ const getInputProps = useCallback7(() => ({
3493
3602
  ref: setInput,
3494
3603
  onChange,
3495
3604
  onKeyDown,
@@ -3517,7 +3626,7 @@ function useComposerAutocomplete(options) {
3517
3626
  activeIndex,
3518
3627
  optionId
3519
3628
  ]);
3520
- const getListboxProps = useCallback6(() => ({
3629
+ const getListboxProps = useCallback7(() => ({
3521
3630
  id: listboxId,
3522
3631
  role: "listbox",
3523
3632
  "aria-label": match?.source.label ?? match?.source.id ?? "Suggestions"
@@ -3525,7 +3634,7 @@ function useComposerAutocomplete(options) {
3525
3634
  listboxId,
3526
3635
  match
3527
3636
  ]);
3528
- const getOptionProps = useCallback6((index) => ({
3637
+ const getOptionProps = useCallback7((index) => ({
3529
3638
  id: optionId(index),
3530
3639
  role: "option",
3531
3640
  "aria-selected": index === activeIndex
@@ -3559,7 +3668,7 @@ function isPromise(value) {
3559
3668
  __name(isPromise, "isPromise");
3560
3669
 
3561
3670
  // src/presentation/use-tool-catalog.ts
3562
- import { useCallback as useCallback7, useEffect as useEffect8, useMemo as useMemo3, useState as useState9 } from "react";
3671
+ import { useCallback as useCallback8, useEffect as useEffect9, useMemo as useMemo5, useState as useState10 } from "react";
3563
3672
  var shared = /* @__PURE__ */ new WeakMap();
3564
3673
  function load(client, agent) {
3565
3674
  let byAgent = shared.get(client);
@@ -3583,11 +3692,11 @@ function load(client, agent) {
3583
3692
  __name(load, "load");
3584
3693
  function useToolCatalog(options) {
3585
3694
  const { client, agent, enabled = true } = options;
3586
- const [entries, setEntries] = useState9([]);
3587
- const [isLoading, setLoading] = useState9(enabled);
3588
- const [error, setError] = useState9(null);
3589
- const [generation, setGeneration] = useState9(0);
3590
- useEffect8(() => {
3695
+ const [entries, setEntries] = useState10([]);
3696
+ const [isLoading, setLoading] = useState10(enabled);
3697
+ const [error, setError] = useState10(null);
3698
+ const [generation, setGeneration] = useState10(0);
3699
+ useEffect9(() => {
3591
3700
  if (!enabled) {
3592
3701
  setLoading(false);
3593
3702
  return;
@@ -3613,14 +3722,14 @@ function useToolCatalog(options) {
3613
3722
  enabled,
3614
3723
  generation
3615
3724
  ]);
3616
- const refresh = useCallback7(() => {
3725
+ const refresh = useCallback8(() => {
3617
3726
  shared.get(client)?.delete(agent ?? "");
3618
3727
  setGeneration((current) => current + 1);
3619
3728
  }, [
3620
3729
  client,
3621
3730
  agent
3622
3731
  ]);
3623
- const catalog = useMemo3(() => toolCatalogFrom(entries), [
3732
+ const catalog = useMemo5(() => toolCatalogFrom(entries), [
3624
3733
  entries
3625
3734
  ]);
3626
3735
  return {
@@ -3634,7 +3743,7 @@ function useToolCatalog(options) {
3634
3743
  __name(useToolCatalog, "useToolCatalog");
3635
3744
 
3636
3745
  // src/approvals/countdown.ts
3637
- import { useEffect as useEffect9, useRef as useRef8, useState as useState10 } from "react";
3746
+ import { useEffect as useEffect10, useRef as useRef9, useState as useState11 } from "react";
3638
3747
  function approvalCountdown(expiresAt, now = Date.now()) {
3639
3748
  const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
3640
3749
  if (!Number.isFinite(deadline)) {
@@ -3652,10 +3761,10 @@ function approvalCountdown(expiresAt, now = Date.now()) {
3652
3761
  __name(approvalCountdown, "approvalCountdown");
3653
3762
  function useApprovalCountdown(expiresAt, options = {}) {
3654
3763
  const { intervalMs = 1e3 } = options;
3655
- const nowRef = useRef8(options.now ?? Date.now);
3764
+ const nowRef = useRef9(options.now ?? Date.now);
3656
3765
  nowRef.current = options.now ?? Date.now;
3657
- const [state, setState] = useState10(() => approvalCountdown(expiresAt, nowRef.current()));
3658
- useEffect9(() => {
3766
+ const [state, setState] = useState11(() => approvalCountdown(expiresAt, nowRef.current()));
3767
+ useEffect10(() => {
3659
3768
  const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
3660
3769
  const first = read();
3661
3770
  setState(first);
@@ -3897,20 +4006,20 @@ __name(sumUsage, "sumUsage");
3897
4006
 
3898
4007
  // src/use-agent-chat.ts
3899
4008
  import { useChat } from "@ai-sdk/react";
3900
- import { useCallback as useCallback8, useEffect as useEffect10, useMemo as useMemo4, useRef as useRef9, useState as useState11 } from "react";
4009
+ import { useCallback as useCallback9, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef10, useState as useState12 } from "react";
3901
4010
  function useAgentChat(options) {
3902
- const latest = useRef9(options);
4011
+ const latest = useRef10(options);
3903
4012
  latest.current = options;
3904
- const [runId, setRunId] = useState11(options.resumeRunId);
3905
- const runIdRef = useRef9(runId);
4013
+ const [runId, setRunId] = useState12(options.resumeRunId);
4014
+ const runIdRef = useRef10(runId);
3906
4015
  runIdRef.current = runId;
3907
- const settlingRunIdRef = useRef9(void 0);
3908
- const autoResumeRunIdRef = useRef9(void 0);
3909
- const [autoResume, setAutoResume] = useState11(false);
3910
- const [activeRunId, setActiveRunId] = useState11(null);
3911
- const regenerateNext = useRef9(false);
3912
- const createdThreadId = useRef9(void 0);
3913
- const client = useMemo4(() => {
4016
+ const settlingRunIdRef = useRef10(void 0);
4017
+ const autoResumeRunIdRef = useRef10(void 0);
4018
+ const [autoResume, setAutoResume] = useState12(false);
4019
+ const [activeRunId, setActiveRunId] = useState12(null);
4020
+ const regenerateNext = useRef10(false);
4021
+ const createdThreadId = useRef10(void 0);
4022
+ const client = useMemo6(() => {
3914
4023
  if (options.backend) return options.backend;
3915
4024
  if (options.client) return options.client;
3916
4025
  return new AgentClient({
@@ -3926,11 +4035,11 @@ function useAgentChat(options) {
3926
4035
  getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
3927
4036
  });
3928
4037
  }, []);
3929
- const [connection, setConnection] = useState11({
4038
+ const [connection, setConnection] = useState12({
3930
4039
  status: "live"
3931
4040
  });
3932
- const resyncAfterSettle = useRef9(false);
3933
- useEffect10(() => {
4041
+ const resyncAfterSettle = useRef10(false);
4042
+ useEffect11(() => {
3934
4043
  if (!options.resume || options.threadId === void 0) return;
3935
4044
  let cancelled = false;
3936
4045
  const threadId = options.threadId;
@@ -3950,7 +4059,7 @@ function useAgentChat(options) {
3950
4059
  options.resume,
3951
4060
  options.threadId
3952
4061
  ]);
3953
- const transport = useMemo4(() => {
4062
+ const transport = useMemo6(() => {
3954
4063
  function onMeta(meta) {
3955
4064
  settlingRunIdRef.current = meta.runId;
3956
4065
  setRunId(meta.runId);
@@ -3987,6 +4096,9 @@ function useAgentChat(options) {
3987
4096
  ...threadId !== void 0 ? {
3988
4097
  threadId
3989
4098
  } : {},
4099
+ ...current.model !== void 0 ? {
4100
+ model: current.model
4101
+ } : {},
3990
4102
  ...pageContext ? {
3991
4103
  pageContext
3992
4104
  } : {},
@@ -4002,7 +4114,7 @@ function useAgentChat(options) {
4002
4114
  }, "onAttemptStart")
4003
4115
  });
4004
4116
  }, []);
4005
- const backgroundRef = useRef9(() => Promise.resolve());
4117
+ const backgroundRef = useRef10(() => Promise.resolve());
4006
4118
  const chat = useChat({
4007
4119
  transport,
4008
4120
  resume: options.resumeRunId !== void 0 || autoResume,
@@ -4051,7 +4163,7 @@ function useAgentChat(options) {
4051
4163
  }
4052
4164
  }, "onFinish")
4053
4165
  });
4054
- const chatRef = useRef9(chat);
4166
+ const chatRef = useRef10(chat);
4055
4167
  chatRef.current = chat;
4056
4168
  async function resyncFromThread() {
4057
4169
  const threadId = latest.current.threadId ?? createdThreadId.current;
@@ -4063,11 +4175,11 @@ function useAgentChat(options) {
4063
4175
  }
4064
4176
  }
4065
4177
  __name(resyncFromThread, "resyncFromThread");
4066
- const turnInFlight = useRef9(false);
4067
- const isTurnInFlight = useCallback8(() => turnInFlight.current || transport.isAttemptLive, [
4178
+ const turnInFlight = useRef10(false);
4179
+ const isTurnInFlight = useCallback9(() => turnInFlight.current || transport.isAttemptLive, [
4068
4180
  transport
4069
4181
  ]);
4070
- const sendMessage = useCallback8(async (...args) => {
4182
+ const sendMessage = useCallback9(async (...args) => {
4071
4183
  if (isTurnInFlight()) return;
4072
4184
  turnInFlight.current = true;
4073
4185
  try {
@@ -4078,15 +4190,15 @@ function useAgentChat(options) {
4078
4190
  }, [
4079
4191
  isTurnInFlight
4080
4192
  ]);
4081
- const addToolResult = useCallback8(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
4193
+ const addToolResult = useCallback9(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
4082
4194
  tool,
4083
4195
  toolCallId,
4084
4196
  output
4085
4197
  }), []);
4086
- const [threads, setThreads] = useState11([]);
4087
- const [quota, setQuota] = useState11(null);
4088
- const [backgroundRuns, setBackgroundRuns] = useState11([]);
4089
- const refreshBackground = useCallback8(async () => {
4198
+ const [threads, setThreads] = useState12([]);
4199
+ const [quota, setQuota] = useState12(null);
4200
+ const [backgroundRuns, setBackgroundRuns] = useState12([]);
4201
+ const refreshBackground = useCallback9(async () => {
4090
4202
  const threadId = latest.current.threadId ?? createdThreadId.current;
4091
4203
  if (threadId === void 0) {
4092
4204
  return;
@@ -4111,7 +4223,7 @@ function useAgentChat(options) {
4111
4223
  ]);
4112
4224
  backgroundRef.current = refreshBackground;
4113
4225
  const isWorking = backgroundRuns.some((run) => run.status === "running");
4114
- useEffect10(() => {
4226
+ useEffect11(() => {
4115
4227
  if (options.background !== true || options.threadId === void 0) {
4116
4228
  return;
4117
4229
  }
@@ -4121,7 +4233,7 @@ function useAgentChat(options) {
4121
4233
  options.threadId,
4122
4234
  refreshBackground
4123
4235
  ]);
4124
- useEffect10(() => {
4236
+ useEffect11(() => {
4125
4237
  const every = latest.current.backgroundPollMs ?? 5e3;
4126
4238
  if (latest.current.background !== true || !isWorking || every <= 0) {
4127
4239
  return;
@@ -4132,26 +4244,26 @@ function useAgentChat(options) {
4132
4244
  isWorking,
4133
4245
  refreshBackground
4134
4246
  ]);
4135
- const loadThreads = useCallback8(async () => {
4247
+ const loadThreads = useCallback9(async () => {
4136
4248
  const list = await client.listThreads();
4137
4249
  setThreads(list);
4138
4250
  return list;
4139
4251
  }, [
4140
4252
  client
4141
4253
  ]);
4142
- const loadThread = useCallback8((id) => client.getThread(id), [
4254
+ const loadThread = useCallback9((id) => client.getThread(id), [
4143
4255
  client
4144
4256
  ]);
4145
- const deleteThread = useCallback8(async (id) => {
4257
+ const deleteThread = useCallback9(async (id) => {
4146
4258
  await client.deleteThread(id);
4147
4259
  setThreads((current) => current.filter((thread) => thread.id !== id));
4148
4260
  }, [
4149
4261
  client
4150
4262
  ]);
4151
- const forkThread = useCallback8((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
4263
+ const forkThread = useCallback9((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
4152
4264
  client
4153
4265
  ]);
4154
- const renameThread = useCallback8(async (id, title) => {
4266
+ const renameThread = useCallback9(async (id, title) => {
4155
4267
  await client.updateThread(id, {
4156
4268
  title
4157
4269
  });
@@ -4162,24 +4274,24 @@ function useAgentChat(options) {
4162
4274
  }, [
4163
4275
  client
4164
4276
  ]);
4165
- const promoteThread = useCallback8(async (id) => {
4277
+ const promoteThread = useCallback9(async (id) => {
4166
4278
  await requireBackendMethod(client, "promoteThread")(id);
4167
4279
  await loadThreads();
4168
4280
  }, [
4169
4281
  client,
4170
4282
  loadThreads
4171
4283
  ]);
4172
- const truncateFromMessage = useCallback8((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
4284
+ const truncateFromMessage = useCallback9((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
4173
4285
  client
4174
4286
  ]);
4175
- const loadQuota = useCallback8(async () => {
4287
+ const loadQuota = useCallback9(async () => {
4176
4288
  const today = await requireBackendMethod(client, "getQuotaToday")();
4177
4289
  setQuota(today);
4178
4290
  return today;
4179
4291
  }, [
4180
4292
  client
4181
4293
  ]);
4182
- const cancel = useCallback8(async () => {
4294
+ const cancel = useCallback9(async () => {
4183
4295
  chatRef.current.stop();
4184
4296
  const activeRunId2 = runIdRef.current;
4185
4297
  if (activeRunId2) {
@@ -4191,7 +4303,7 @@ function useAgentChat(options) {
4191
4303
  }, [
4192
4304
  client
4193
4305
  ]);
4194
- const approve = useCallback8(async ({ toolCallId, remember, via }) => {
4306
+ const approve = useCallback9(async ({ toolCallId, remember, via }) => {
4195
4307
  await requireBackendMethod(client, "approveToolCall")({
4196
4308
  toolCallId,
4197
4309
  ...remember === true ? {
@@ -4204,7 +4316,7 @@ function useAgentChat(options) {
4204
4316
  }, [
4205
4317
  client
4206
4318
  ]);
4207
- const reject = useCallback8(async ({ toolCallId, reason, via }) => {
4319
+ const reject = useCallback9(async ({ toolCallId, reason, via }) => {
4208
4320
  await requireBackendMethod(client, "rejectToolCall")({
4209
4321
  toolCallId,
4210
4322
  ...reason !== void 0 ? {
@@ -4217,7 +4329,7 @@ function useAgentChat(options) {
4217
4329
  }, [
4218
4330
  client
4219
4331
  ]);
4220
- const answer = useCallback8(async ({ toolCallId, answers }) => {
4332
+ const answer = useCallback9(async ({ toolCallId, answers }) => {
4221
4333
  await requireBackendMethod(client, "answerToolCall")({
4222
4334
  toolCallId,
4223
4335
  ...answers !== void 0 ? {
@@ -4227,14 +4339,14 @@ function useAgentChat(options) {
4227
4339
  }, [
4228
4340
  client
4229
4341
  ]);
4230
- const skip = useCallback8(async ({ toolCallId }) => {
4342
+ const skip = useCallback9(async ({ toolCallId }) => {
4231
4343
  await requireBackendMethod(client, "skipToolCall")({
4232
4344
  toolCallId
4233
4345
  });
4234
4346
  }, [
4235
4347
  client
4236
4348
  ]);
4237
- const regenerate = useCallback8(() => {
4349
+ const regenerate = useCallback9(() => {
4238
4350
  if (isTurnInFlight()) return;
4239
4351
  regenerateNext.current = true;
4240
4352
  turnInFlight.current = true;
@@ -4249,7 +4361,21 @@ function useAgentChat(options) {
4249
4361
  isWorking,
4250
4362
  refresh: refreshBackground
4251
4363
  };
4252
- const getThreadId = useCallback8(() => latest.current.threadId ?? createdThreadId.current, []);
4364
+ const setThreadModel = useCallback9(async (model) => {
4365
+ const threadId = latest.current.threadId ?? createdThreadId.current;
4366
+ if (threadId === void 0) {
4367
+ throw new Error("setThreadModel: this chat has no thread yet");
4368
+ }
4369
+ await client.updateThread(threadId, {
4370
+ model
4371
+ });
4372
+ notifyThreads(client, {
4373
+ type: "changed"
4374
+ });
4375
+ }, [
4376
+ client
4377
+ ]);
4378
+ const getThreadId = useCallback9(() => latest.current.threadId ?? createdThreadId.current, []);
4253
4379
  const status = connection.status === "reconnecting" ? "reconnecting" : chat.status;
4254
4380
  return {
4255
4381
  ...chat,
@@ -4268,6 +4394,7 @@ function useAgentChat(options) {
4268
4394
  * on the first send. A getter, because the created id is learned mid-stream.
4269
4395
  */
4270
4396
  getThreadId,
4397
+ setThreadModel,
4271
4398
  /** The backend this chat talks to — pass it to `useThreads`, `useMessageFeedback`, … */
4272
4399
  backend: client,
4273
4400
  /** Same object as {@link backend}; kept for callers that read it under its old name. */
@@ -4343,11 +4470,13 @@ export {
4343
4470
  toolCallState,
4344
4471
  toolCatalogFrom,
4345
4472
  useAgentChat,
4473
+ useAgents,
4346
4474
  useApprovalCountdown,
4347
4475
  useChatTranscript,
4348
4476
  useComposerAutocomplete,
4349
4477
  useElapsed,
4350
4478
  useMessageFeedback,
4479
+ useModels,
4351
4480
  useSpeechRecognition,
4352
4481
  useStickToBottom,
4353
4482
  useThreads,