@dudousxd/nestjs-agent-react 0.15.0 → 0.17.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,19 @@ 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
+ }
159
+ /** `GET /agent/quota` — the caller's budget windows and the one blocking sends, if any. */
160
+ getQuota() {
161
+ return this.request("GET", "/agent/quota");
162
+ }
150
163
  getQuotaToday() {
151
164
  return this.request("GET", "/agent/quota/today");
152
165
  }
@@ -994,28 +1007,196 @@ function requireBackendMethod(backend, name) {
994
1007
  }
995
1008
  __name(requireBackendMethod, "requireBackendMethod");
996
1009
 
1010
+ // src/catalog/use-agents.ts
1011
+ import { useMemo } from "react";
1012
+
1013
+ // src/catalog/use-resource.ts
1014
+ import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
1015
+ function useResource(load2, key, enabled) {
1016
+ const [data, setData] = useState2(void 0);
1017
+ const [isLoading, setIsLoading] = useState2(enabled);
1018
+ const [error, setError] = useState2(null);
1019
+ const loadRef = useRef2(load2);
1020
+ loadRef.current = load2;
1021
+ const generation = useRef2(0);
1022
+ const refresh = useCallback(async () => {
1023
+ const mine = ++generation.current;
1024
+ setIsLoading(true);
1025
+ try {
1026
+ const value = await loadRef.current();
1027
+ if (mine !== generation.current) return;
1028
+ setData(value);
1029
+ setError(null);
1030
+ } catch (caught) {
1031
+ if (mine !== generation.current) return;
1032
+ setError(caught instanceof Error ? caught : new Error(String(caught)));
1033
+ } finally {
1034
+ if (mine === generation.current) setIsLoading(false);
1035
+ }
1036
+ }, []);
1037
+ useEffect2(() => {
1038
+ if (!enabled) return;
1039
+ void refresh();
1040
+ }, [
1041
+ enabled,
1042
+ key,
1043
+ refresh
1044
+ ]);
1045
+ return {
1046
+ data,
1047
+ isLoading,
1048
+ error,
1049
+ refresh
1050
+ };
1051
+ }
1052
+ __name(useResource, "useResource");
1053
+
1054
+ // src/catalog/use-agents.ts
1055
+ function useAgents(options) {
1056
+ const { backend, enabled = true } = options;
1057
+ const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listAgents")(), "", enabled);
1058
+ return useMemo(() => {
1059
+ const agents = data ?? [];
1060
+ return {
1061
+ agents,
1062
+ defaultAgent: agents.find((agent) => agent.isDefault === true)?.name ?? null,
1063
+ isLoading,
1064
+ error,
1065
+ refresh
1066
+ };
1067
+ }, [
1068
+ data,
1069
+ isLoading,
1070
+ error,
1071
+ refresh
1072
+ ]);
1073
+ }
1074
+ __name(useAgents, "useAgents");
1075
+
1076
+ // src/catalog/use-models.ts
1077
+ import { useMemo as useMemo2 } from "react";
1078
+ function useModels(options) {
1079
+ const { backend, agent, enabled = true } = options;
1080
+ const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listModels")(agent), `${agent ?? ""}`, enabled);
1081
+ return useMemo2(() => {
1082
+ const providers = data?.providers ?? [];
1083
+ const models = providers.flatMap((provider) => provider.models.map((model) => ({
1084
+ ...model,
1085
+ providerId: provider.id,
1086
+ providerLabel: provider.label
1087
+ })));
1088
+ const byId = new Map(models.map((model) => [
1089
+ model.id,
1090
+ model
1091
+ ]));
1092
+ return {
1093
+ providers,
1094
+ models,
1095
+ defaultModel: data?.default ?? null,
1096
+ find: /* @__PURE__ */ __name((id) => id == null ? void 0 : byId.get(id), "find"),
1097
+ isLoading,
1098
+ error,
1099
+ refresh
1100
+ };
1101
+ }, [
1102
+ data,
1103
+ isLoading,
1104
+ error,
1105
+ refresh
1106
+ ]);
1107
+ }
1108
+ __name(useModels, "useModels");
1109
+
1110
+ // src/quota/use-quota.ts
1111
+ import { useEffect as useEffect3, useMemo as useMemo3 } from "react";
1112
+
1113
+ // src/threads/threads-events.ts
1114
+ var listeners = /* @__PURE__ */ new WeakMap();
1115
+ function notifyThreads(backend, event) {
1116
+ for (const listener of listeners.get(backend) ?? []) {
1117
+ listener(event);
1118
+ }
1119
+ }
1120
+ __name(notifyThreads, "notifyThreads");
1121
+ function onThreadsEvent(backend, listener) {
1122
+ let set = listeners.get(backend);
1123
+ if (set === void 0) {
1124
+ set = /* @__PURE__ */ new Set();
1125
+ listeners.set(backend, set);
1126
+ }
1127
+ set.add(listener);
1128
+ return () => {
1129
+ set.delete(listener);
1130
+ };
1131
+ }
1132
+ __name(onThreadsEvent, "onThreadsEvent");
1133
+
1134
+ // src/quota/use-quota.ts
1135
+ function useQuota(options) {
1136
+ const { backend, enabled = true, pollMs } = options;
1137
+ const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "getQuota")(), "", enabled);
1138
+ useEffect3(() => {
1139
+ if (!enabled) return;
1140
+ return onThreadsEvent(backend, (event) => {
1141
+ if (event.type === "changed") void refresh();
1142
+ });
1143
+ }, [
1144
+ backend,
1145
+ enabled,
1146
+ refresh
1147
+ ]);
1148
+ useEffect3(() => {
1149
+ if (!enabled || pollMs === void 0 || pollMs <= 0) return;
1150
+ const timer = setInterval(() => void refresh(), pollMs);
1151
+ return () => clearInterval(timer);
1152
+ }, [
1153
+ enabled,
1154
+ pollMs,
1155
+ refresh
1156
+ ]);
1157
+ return useMemo3(() => {
1158
+ const windows = data?.windows ?? [];
1159
+ return {
1160
+ report: data,
1161
+ windows,
1162
+ day: windows.find((window2) => window2.period === "day"),
1163
+ month: windows.find((window2) => window2.period === "month"),
1164
+ blocked: data?.blocked ?? null,
1165
+ isLoading,
1166
+ error,
1167
+ refresh
1168
+ };
1169
+ }, [
1170
+ data,
1171
+ isLoading,
1172
+ error,
1173
+ refresh
1174
+ ]);
1175
+ }
1176
+ __name(useQuota, "useQuota");
1177
+
997
1178
  // src/feedback/use-message-feedback.ts
998
- import { useCallback, useRef as useRef2, useState as useState2 } from "react";
1179
+ import { useCallback as useCallback2, useRef as useRef3, useState as useState3 } from "react";
999
1180
  function useMessageFeedback(options) {
1000
- const latest = useRef2(options);
1181
+ const latest = useRef3(options);
1001
1182
  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);
1183
+ const [local, setLocal] = useState3(/* @__PURE__ */ new Map());
1184
+ const [pending, setPending] = useState3(/* @__PURE__ */ new Set());
1185
+ const [error, setError] = useState3(null);
1186
+ const localRef = useRef3(local);
1006
1187
  localRef.current = local;
1007
- const resolved = useRef2(/* @__PURE__ */ new Map());
1008
- const feedbackOf = useCallback((message) => {
1188
+ const resolved = useRef3(/* @__PURE__ */ new Map());
1189
+ const feedbackOf = useCallback2((message) => {
1009
1190
  const mine = local.get(message.id);
1010
1191
  if (mine !== void 0) return mine.feedback;
1011
1192
  return metadataOf(message).feedback ?? null;
1012
1193
  }, [
1013
1194
  local
1014
1195
  ]);
1015
- const isPending = useCallback((message) => pending.has(message.id), [
1196
+ const isPending = useCallback2((message) => pending.has(message.id), [
1016
1197
  pending
1017
1198
  ]);
1018
- const storedIdFor = useCallback(async (message) => {
1199
+ const storedIdFor = useCallback2(async (message) => {
1019
1200
  const runId = metadataOf(message).runId;
1020
1201
  if (runId === void 0) return message.id;
1021
1202
  const known = resolved.current.get(message.id);
@@ -1035,7 +1216,7 @@ function useMessageFeedback(options) {
1035
1216
  resolved.current.set(message.id, row.id);
1036
1217
  return row.id;
1037
1218
  }, []);
1038
- const rate = useCallback(async (message, value, comment) => {
1219
+ const rate = useCallback2(async (message, value, comment) => {
1039
1220
  const setFeedback = requireBackendMethod(latest.current.backend, "setMessageFeedback");
1040
1221
  const had = localRef.current.get(message.id);
1041
1222
  const optimistic = value === null ? null : {
@@ -1081,7 +1262,7 @@ function useMessageFeedback(options) {
1081
1262
  }, [
1082
1263
  storedIdFor
1083
1264
  ]);
1084
- const toggle = useCallback((message, value) => {
1265
+ const toggle = useCallback2((message, value) => {
1085
1266
  const mine = localRef.current.get(message.id);
1086
1267
  const current = mine !== void 0 ? mine.feedback : metadataOf(message).feedback ?? null;
1087
1268
  return rate(message, current?.value === value ? null : value);
@@ -1103,38 +1284,17 @@ function metadataOf(message) {
1103
1284
  }
1104
1285
  __name(metadataOf, "metadataOf");
1105
1286
 
1106
- // src/threads/threads-events.ts
1107
- var listeners = /* @__PURE__ */ new WeakMap();
1108
- function notifyThreads(backend, event) {
1109
- for (const listener of listeners.get(backend) ?? []) {
1110
- listener(event);
1111
- }
1112
- }
1113
- __name(notifyThreads, "notifyThreads");
1114
- function onThreadsEvent(backend, listener) {
1115
- let set = listeners.get(backend);
1116
- if (set === void 0) {
1117
- set = /* @__PURE__ */ new Set();
1118
- listeners.set(backend, set);
1119
- }
1120
- set.add(listener);
1121
- return () => {
1122
- set.delete(listener);
1123
- };
1124
- }
1125
- __name(onThreadsEvent, "onThreadsEvent");
1126
-
1127
1287
  // src/threads/use-threads.ts
1128
- import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef3, useState as useState3 } from "react";
1288
+ import { useCallback as useCallback3, useEffect as useEffect4, useRef as useRef4, useState as useState4 } from "react";
1129
1289
  function useThreads(options) {
1130
1290
  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);
1291
+ const [threads, setThreads] = useState4([]);
1292
+ const [isLoading, setIsLoading] = useState4(enabled);
1293
+ const [error, setError] = useState4(null);
1294
+ const threadsRef = useRef4(threads);
1135
1295
  threadsRef.current = threads;
1136
- const generation = useRef3(0);
1137
- const refresh = useCallback2(async () => {
1296
+ const generation = useRef4(0);
1297
+ const refresh = useCallback3(async () => {
1138
1298
  const mine = ++generation.current;
1139
1299
  setIsLoading(true);
1140
1300
  try {
@@ -1151,7 +1311,7 @@ function useThreads(options) {
1151
1311
  }, [
1152
1312
  backend
1153
1313
  ]);
1154
- useEffect2(() => {
1314
+ useEffect4(() => {
1155
1315
  if (!enabled) return;
1156
1316
  void refresh();
1157
1317
  return onThreadsEvent(backend, (event) => {
@@ -1171,7 +1331,7 @@ function useThreads(options) {
1171
1331
  enabled,
1172
1332
  refresh
1173
1333
  ]);
1174
- const rename = useCallback2(async (id, title) => {
1334
+ const rename = useCallback3(async (id, title) => {
1175
1335
  const before = threadsRef.current;
1176
1336
  setThreads((current) => current.map((thread) => thread.id === id ? {
1177
1337
  ...thread,
@@ -1193,7 +1353,7 @@ function useThreads(options) {
1193
1353
  }, [
1194
1354
  backend
1195
1355
  ]);
1196
- const remove = useCallback2(async (id) => {
1356
+ const remove = useCallback3(async (id) => {
1197
1357
  const before = threadsRef.current;
1198
1358
  setThreads((current) => current.filter((thread) => thread.id !== id));
1199
1359
  try {
@@ -1268,10 +1428,10 @@ function backgroundRunsFromThread(messages) {
1268
1428
  __name(backgroundRunsFromThread, "backgroundRunsFromThread");
1269
1429
 
1270
1430
  // src/components/chat-input.tsx
1271
- import React2, { useEffect as useEffect4, useState as useState5 } from "react";
1431
+ import React2, { useEffect as useEffect6, useState as useState6 } from "react";
1272
1432
 
1273
1433
  // src/components/use-speech-recognition.ts
1274
- import { useCallback as useCallback3, useEffect as useEffect3, useMemo, useRef as useRef4, useState as useState4 } from "react";
1434
+ import { useCallback as useCallback4, useEffect as useEffect5, useMemo as useMemo4, useRef as useRef5, useState as useState5 } from "react";
1275
1435
  function getRecognitionCtor() {
1276
1436
  if (typeof window === "undefined") return null;
1277
1437
  const scope = window;
@@ -1279,15 +1439,15 @@ function getRecognitionCtor() {
1279
1439
  }
1280
1440
  __name(getRecognitionCtor, "getRecognitionCtor");
1281
1441
  function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
1282
- const recognitionRef = useRef4(null);
1283
- const [isListening, setIsListening] = useState4(false);
1284
- const ctor = useMemo(() => getRecognitionCtor(), []);
1442
+ const recognitionRef = useRef5(null);
1443
+ const [isListening, setIsListening] = useState5(false);
1444
+ const ctor = useMemo4(() => getRecognitionCtor(), []);
1285
1445
  const isSupported = ctor !== null;
1286
- const finalRef = useRef4(onFinalTranscript);
1287
- const interimRef = useRef4(onInterimTranscript);
1446
+ const finalRef = useRef5(onFinalTranscript);
1447
+ const interimRef = useRef5(onInterimTranscript);
1288
1448
  finalRef.current = onFinalTranscript;
1289
1449
  interimRef.current = onInterimTranscript;
1290
- useEffect3(() => {
1450
+ useEffect5(() => {
1291
1451
  if (!ctor) return;
1292
1452
  const recognition = new ctor();
1293
1453
  recognition.lang = lang;
@@ -1326,7 +1486,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
1326
1486
  ctor,
1327
1487
  lang
1328
1488
  ]);
1329
- const start = useCallback3(() => {
1489
+ const start = useCallback4(() => {
1330
1490
  const recognition = recognitionRef.current;
1331
1491
  if (!recognition) return;
1332
1492
  try {
@@ -1336,7 +1496,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
1336
1496
  console.warn("SpeechRecognition start failed", error);
1337
1497
  }
1338
1498
  }, []);
1339
- const stop = useCallback3(() => {
1499
+ const stop = useCallback4(() => {
1340
1500
  const recognition = recognitionRef.current;
1341
1501
  if (!recognition) return;
1342
1502
  try {
@@ -1355,8 +1515,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
1355
1515
 
1356
1516
  // src/components/chat-input.tsx
1357
1517
  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("");
1518
+ const [value, setValue] = useState6("");
1519
+ const [interim, setInterim] = useState6("");
1360
1520
  const speech = useSpeechRecognition({
1361
1521
  lang: speechLang,
1362
1522
  onFinalTranscript: /* @__PURE__ */ __name((text) => {
@@ -1367,7 +1527,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
1367
1527
  }, "onFinalTranscript"),
1368
1528
  onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
1369
1529
  });
1370
- useEffect4(() => {
1530
+ useEffect6(() => {
1371
1531
  if (!speech.isListening) setInterim("");
1372
1532
  }, [
1373
1533
  speech.isListening
@@ -1434,7 +1594,7 @@ __name(ChatInput, "ChatInput");
1434
1594
  import React3 from "react";
1435
1595
 
1436
1596
  // src/transcript/use-chat-transcript.ts
1437
- import { useCallback as useCallback5, useEffect as useEffect6, useRef as useRef6, useState as useState7 } from "react";
1597
+ import { useCallback as useCallback6, useEffect as useEffect8, useRef as useRef7, useState as useState8 } from "react";
1438
1598
 
1439
1599
  // src/transcript/model.ts
1440
1600
  import { readElicitationInput, validateElicitationAnswer as validateElicitationAnswer2 } from "@dudousxd/nestjs-agent-core";
@@ -2411,11 +2571,11 @@ function formatCostUsd(cost) {
2411
2571
  __name(formatCostUsd, "formatCostUsd");
2412
2572
 
2413
2573
  // src/transcript/use-stick-to-bottom.ts
2414
- import { useCallback as useCallback4, useEffect as useEffect5, useRef as useRef5, useState as useState6 } from "react";
2574
+ import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef6, useState as useState7 } from "react";
2415
2575
  function useStickToBottom({ contentKey, threshold = 32 }) {
2416
- const containerRef = useRef5(null);
2417
- const [isAtBottom, setIsAtBottom] = useState6(true);
2418
- const measure = useCallback4(() => {
2576
+ const containerRef = useRef6(null);
2577
+ const [isAtBottom, setIsAtBottom] = useState7(true);
2578
+ const measure = useCallback5(() => {
2419
2579
  const element = containerRef.current;
2420
2580
  if (!element) {
2421
2581
  return;
@@ -2425,7 +2585,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
2425
2585
  }, [
2426
2586
  threshold
2427
2587
  ]);
2428
- const scrollToBottom = useCallback4(() => {
2588
+ const scrollToBottom = useCallback5(() => {
2429
2589
  const element = containerRef.current;
2430
2590
  if (!element) {
2431
2591
  return;
@@ -2433,7 +2593,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
2433
2593
  element.scrollTop = element.scrollHeight;
2434
2594
  setIsAtBottom(true);
2435
2595
  }, []);
2436
- const setContainer = useCallback4((element) => {
2596
+ const setContainer = useCallback5((element) => {
2437
2597
  containerRef.current = element;
2438
2598
  if (element) {
2439
2599
  measure();
@@ -2441,7 +2601,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
2441
2601
  }, [
2442
2602
  measure
2443
2603
  ]);
2444
- useEffect5(() => {
2604
+ useEffect7(() => {
2445
2605
  if (isAtBottom) {
2446
2606
  scrollToBottom();
2447
2607
  }
@@ -2450,7 +2610,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
2450
2610
  isAtBottom,
2451
2611
  scrollToBottom
2452
2612
  ]);
2453
- const getContainerProps = useCallback4(() => ({
2613
+ const getContainerProps = useCallback5(() => ({
2454
2614
  ref: setContainer,
2455
2615
  onScroll: measure
2456
2616
  }), [
@@ -2472,14 +2632,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
2472
2632
  var DEFAULT_COPY_RESET_MS = 1500;
2473
2633
  function useChatTranscript(options) {
2474
2634
  const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
2475
- const latest = useRef6(options);
2635
+ const latest = useRef7(options);
2476
2636
  latest.current = options;
2477
- const [visibleCount, setVisibleCount] = useState7(initialVisibleCount);
2478
- const [stopRequested, setStopRequested] = useState7(false);
2637
+ const [visibleCount, setVisibleCount] = useState8(initialVisibleCount);
2638
+ const [stopRequested, setStopRequested] = useState8(false);
2479
2639
  const isStreaming = status === "streaming" || status === "reconnecting";
2480
2640
  const isBusy = status === "submitted" || isStreaming;
2481
2641
  const isEmpty = messages.length === 0;
2482
- useEffect6(() => {
2642
+ useEffect8(() => {
2483
2643
  if (!isBusy) {
2484
2644
  setStopRequested(false);
2485
2645
  }
@@ -2496,7 +2656,7 @@ function useChatTranscript(options) {
2496
2656
  streamingMessageId,
2497
2657
  options
2498
2658
  });
2499
- const stop = useCallback5(() => {
2659
+ const stop = useCallback6(() => {
2500
2660
  const current = latest.current;
2501
2661
  if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
2502
2662
  return;
@@ -2504,8 +2664,8 @@ function useChatTranscript(options) {
2504
2664
  setStopRequested(true);
2505
2665
  void current.onStop?.();
2506
2666
  }, []);
2507
- const loadEarlier = useCallback5(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
2508
- const showAll = useCallback5(() => setVisibleCount(latest.current.messages.length), []);
2667
+ const loadEarlier = useCallback6(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
2668
+ const showAll = useCallback6(() => setVisibleCount(latest.current.messages.length), []);
2509
2669
  const scroll = useStickToBottom({
2510
2670
  contentKey: contentSignature(messages),
2511
2671
  ...stickToBottomThreshold !== void 0 ? {
@@ -2541,7 +2701,7 @@ function useChatTranscript(options) {
2541
2701
  __name(useChatTranscript, "useChatTranscript");
2542
2702
  function useTranscriptItem(options) {
2543
2703
  const { message, isStreaming = false } = options;
2544
- const messagesRef = useRef6([
2704
+ const messagesRef = useRef7([
2545
2705
  message
2546
2706
  ]);
2547
2707
  if (messagesRef.current[0] !== message) {
@@ -2559,13 +2719,13 @@ function useTranscriptItem(options) {
2559
2719
  }
2560
2720
  __name(useTranscriptItem, "useTranscriptItem");
2561
2721
  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({
2722
+ const [drafts, setDrafts] = useState8(() => /* @__PURE__ */ new Map());
2723
+ const [copied, setCopied] = useState8(() => /* @__PURE__ */ new Set());
2724
+ const [openReasoning, setOpenReasoning] = useState8(() => /* @__PURE__ */ new Map());
2725
+ const [picks, setPicks] = useState8(() => /* @__PURE__ */ new Map());
2726
+ const [settling, setSettling] = useState8(() => /* @__PURE__ */ new Map());
2727
+ const [settleErrors, setSettleErrors] = useState8(() => /* @__PURE__ */ new Map());
2728
+ const latest = useRef7({
2569
2729
  options,
2570
2730
  drafts,
2571
2731
  picks,
@@ -2577,23 +2737,23 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2577
2737
  picks,
2578
2738
  messages
2579
2739
  };
2580
- const copyTimers = useRef6(/* @__PURE__ */ new Map());
2581
- useEffect6(() => () => {
2740
+ const copyTimers = useRef7(/* @__PURE__ */ new Map());
2741
+ useEffect8(() => () => {
2582
2742
  for (const timer of copyTimers.current.values()) {
2583
2743
  clearTimeout(timer);
2584
2744
  }
2585
2745
  copyTimers.current.clear();
2586
2746
  }, []);
2587
- const callbackCache = useRef6(/* @__PURE__ */ new Map());
2588
- const reasoningToggleCache = useRef6(/* @__PURE__ */ new Map());
2589
- const toggleReasoning = useCallback5((key, open) => {
2747
+ const callbackCache = useRef7(/* @__PURE__ */ new Map());
2748
+ const reasoningToggleCache = useRef7(/* @__PURE__ */ new Map());
2749
+ const toggleReasoning = useCallback6((key, open) => {
2590
2750
  setOpenReasoning((current) => {
2591
2751
  const next = new Map(current);
2592
2752
  next.set(key, open ?? !(current.get(key) ?? false));
2593
2753
  return next;
2594
2754
  });
2595
2755
  }, []);
2596
- const stableToggle = useCallback5((key) => {
2756
+ const stableToggle = useCallback6((key) => {
2597
2757
  let cached = reasoningToggleCache.current.get(key);
2598
2758
  if (!cached) {
2599
2759
  cached = /* @__PURE__ */ __name((open) => toggleReasoning(key, open), "cached");
@@ -2603,10 +2763,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2603
2763
  }, [
2604
2764
  toggleReasoning
2605
2765
  ]);
2606
- const pick = useCallback5((toolCallId, questionId, values) => {
2766
+ const pick = useCallback6((toolCallId, questionId, values) => {
2607
2767
  setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
2608
2768
  }, []);
2609
- const settle = useCallback5((toolCallId, action, send) => {
2769
+ const settle = useCallback6((toolCallId, action, send) => {
2610
2770
  setSettleErrors((current) => {
2611
2771
  if (!current.has(toolCallId)) {
2612
2772
  return current;
@@ -2630,7 +2790,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2630
2790
  failed(error);
2631
2791
  }
2632
2792
  }, []);
2633
- const answer = useCallback5((toolCallId) => {
2793
+ const answer = useCallback6((toolCallId) => {
2634
2794
  const current = latest.current;
2635
2795
  const onAnswer = current.options.onAnswer;
2636
2796
  if (!onAnswer) {
@@ -2640,7 +2800,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2640
2800
  }, [
2641
2801
  settle
2642
2802
  ]);
2643
- const skip = useCallback5((toolCallId) => {
2803
+ const skip = useCallback6((toolCallId) => {
2644
2804
  const onSkip = latest.current.options.onSkip;
2645
2805
  if (onSkip) {
2646
2806
  settle(toolCallId, "skip", () => onSkip(toolCallId));
@@ -2648,7 +2808,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2648
2808
  }, [
2649
2809
  settle
2650
2810
  ]);
2651
- const approve = useCallback5((toolCallId, options2) => {
2811
+ const approve = useCallback6((toolCallId, options2) => {
2652
2812
  const onApprove = latest.current.options.onApprove;
2653
2813
  if (onApprove) {
2654
2814
  settle(toolCallId, "approve", () => options2 === void 0 ? onApprove(toolCallId) : onApprove(toolCallId, options2));
@@ -2656,7 +2816,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2656
2816
  }, [
2657
2817
  settle
2658
2818
  ]);
2659
- const reject = useCallback5((toolCallId) => {
2819
+ const reject = useCallback6((toolCallId) => {
2660
2820
  const onReject = latest.current.options.onReject;
2661
2821
  if (onReject) {
2662
2822
  settle(toolCallId, "reject", () => onReject(toolCallId));
@@ -2664,7 +2824,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
2664
2824
  }, [
2665
2825
  settle
2666
2826
  ]);
2667
- const callbacksFor = useCallback5((id) => {
2827
+ const callbacksFor = useCallback6((id) => {
2668
2828
  const cached = callbackCache.current.get(id);
2669
2829
  if (cached) {
2670
2830
  return cached;
@@ -3321,35 +3481,35 @@ function toItem(entry) {
3321
3481
  __name(toItem, "toItem");
3322
3482
 
3323
3483
  // 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";
3484
+ import { useCallback as useCallback7, useEffect as useEffect9, useId, useLayoutEffect, useMemo as useMemo5, useRef as useRef8, useState as useState9 } from "react";
3325
3485
  function useComposerAutocomplete(options) {
3326
3486
  const { value, sources, acceptOnTab = true } = options;
3327
- const latest = useRef7(options);
3487
+ const latest = useRef8(options);
3328
3488
  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);
3489
+ const inputRef = useRef8(null);
3490
+ const [caret, setCaret] = useState9(value.length);
3491
+ const [items, setItems] = useState9([]);
3492
+ const [isLoading, setLoading] = useState9(false);
3493
+ const [error, setError] = useState9(null);
3494
+ const [activeIndex, setActiveIndex] = useState9(0);
3495
+ const [dismissedIndex, setDismissedIndex] = useState9(null);
3336
3496
  const safeCaret = Math.min(caret, value.length);
3337
- const match = useMemo2(() => findActiveTrigger(value, safeCaret, sources), [
3497
+ const match = useMemo5(() => findActiveTrigger(value, safeCaret, sources), [
3338
3498
  value,
3339
3499
  safeCaret,
3340
3500
  sources
3341
3501
  ]);
3342
3502
  const isActive = match !== null && dismissedIndex !== match.index;
3343
- const matchRef = useRef7(match);
3503
+ const matchRef = useRef8(match);
3344
3504
  matchRef.current = match;
3345
- const caretRef = useRef7(safeCaret);
3505
+ const caretRef = useRef8(safeCaret);
3346
3506
  caretRef.current = safeCaret;
3347
- const itemsRef = useRef7(items);
3507
+ const itemsRef = useRef8(items);
3348
3508
  itemsRef.current = items;
3349
- const activeIndexRef = useRef7(activeIndex);
3509
+ const activeIndexRef = useRef8(activeIndex);
3350
3510
  activeIndexRef.current = activeIndex;
3351
3511
  const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
3352
- useEffect7(() => {
3512
+ useEffect9(() => {
3353
3513
  const current = matchRef.current;
3354
3514
  if (requestKey === null || current === null) {
3355
3515
  setItems([]);
@@ -3399,23 +3559,23 @@ function useComposerAutocomplete(options) {
3399
3559
  const activeItem = isOpen ? items[activeIndex] ?? null : null;
3400
3560
  const reactId = useId();
3401
3561
  const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
3402
- const optionId = useCallback6((index) => `${listboxId}-option-${index}`, [
3562
+ const optionId = useCallback7((index) => `${listboxId}-option-${index}`, [
3403
3563
  listboxId
3404
3564
  ]);
3405
- const highlight = useCallback6((index) => {
3565
+ const highlight = useCallback7((index) => {
3406
3566
  const total = itemsRef.current.length;
3407
3567
  if (total === 0) return;
3408
3568
  setActiveIndex((index % total + total) % total);
3409
3569
  }, []);
3410
- const moveHighlight = useCallback6((delta) => highlight(activeIndexRef.current + delta), [
3570
+ const moveHighlight = useCallback7((delta) => highlight(activeIndexRef.current + delta), [
3411
3571
  highlight
3412
3572
  ]);
3413
- const dismiss = useCallback6(() => {
3573
+ const dismiss = useCallback7(() => {
3414
3574
  const current = matchRef.current;
3415
3575
  if (current) setDismissedIndex(current.index);
3416
3576
  }, []);
3417
- const pendingCaret = useRef7(null);
3418
- const accept = useCallback6((item) => {
3577
+ const pendingCaret = useRef8(null);
3578
+ const accept = useCallback7((item) => {
3419
3579
  const current = matchRef.current;
3420
3580
  if (!current) return;
3421
3581
  const chosen = item ?? itemsRef.current[activeIndexRef.current];
@@ -3432,10 +3592,10 @@ function useComposerAutocomplete(options) {
3432
3592
  pendingCaret.current = null;
3433
3593
  inputRef.current?.setSelectionRange(position, position);
3434
3594
  });
3435
- const readCaret = useCallback6((element) => {
3595
+ const readCaret = useCallback7((element) => {
3436
3596
  setCaret(element.selectionStart ?? element.value.length);
3437
3597
  }, []);
3438
- const onKeyDown = useCallback6((event) => {
3598
+ const onKeyDown = useCallback7((event) => {
3439
3599
  if (!isOpen) return;
3440
3600
  const hasItems = itemsRef.current.length > 0;
3441
3601
  switch (event.key) {
@@ -3473,23 +3633,23 @@ function useComposerAutocomplete(options) {
3473
3633
  dismiss,
3474
3634
  moveHighlight
3475
3635
  ]);
3476
- const onChange = useCallback6((event) => {
3636
+ const onChange = useCallback7((event) => {
3477
3637
  readCaret(event.target);
3478
3638
  const next = findActiveTrigger(event.target.value, event.target.selectionStart ?? event.target.value.length, latest.current.sources);
3479
3639
  setDismissedIndex((current) => current !== null && next?.index === current ? current : null);
3480
3640
  }, [
3481
3641
  readCaret
3482
3642
  ]);
3483
- const onSelect = useCallback6((event) => readCaret(event.currentTarget), [
3643
+ const onSelect = useCallback7((event) => readCaret(event.currentTarget), [
3484
3644
  readCaret
3485
3645
  ]);
3486
- const onClick = useCallback6((event) => readCaret(event.currentTarget), [
3646
+ const onClick = useCallback7((event) => readCaret(event.currentTarget), [
3487
3647
  readCaret
3488
3648
  ]);
3489
- const setInput = useCallback6((element) => {
3649
+ const setInput = useCallback7((element) => {
3490
3650
  inputRef.current = element;
3491
3651
  }, []);
3492
- const getInputProps = useCallback6(() => ({
3652
+ const getInputProps = useCallback7(() => ({
3493
3653
  ref: setInput,
3494
3654
  onChange,
3495
3655
  onKeyDown,
@@ -3517,7 +3677,7 @@ function useComposerAutocomplete(options) {
3517
3677
  activeIndex,
3518
3678
  optionId
3519
3679
  ]);
3520
- const getListboxProps = useCallback6(() => ({
3680
+ const getListboxProps = useCallback7(() => ({
3521
3681
  id: listboxId,
3522
3682
  role: "listbox",
3523
3683
  "aria-label": match?.source.label ?? match?.source.id ?? "Suggestions"
@@ -3525,7 +3685,7 @@ function useComposerAutocomplete(options) {
3525
3685
  listboxId,
3526
3686
  match
3527
3687
  ]);
3528
- const getOptionProps = useCallback6((index) => ({
3688
+ const getOptionProps = useCallback7((index) => ({
3529
3689
  id: optionId(index),
3530
3690
  role: "option",
3531
3691
  "aria-selected": index === activeIndex
@@ -3559,7 +3719,7 @@ function isPromise(value) {
3559
3719
  __name(isPromise, "isPromise");
3560
3720
 
3561
3721
  // src/presentation/use-tool-catalog.ts
3562
- import { useCallback as useCallback7, useEffect as useEffect8, useMemo as useMemo3, useState as useState9 } from "react";
3722
+ import { useCallback as useCallback8, useEffect as useEffect10, useMemo as useMemo6, useState as useState10 } from "react";
3563
3723
  var shared = /* @__PURE__ */ new WeakMap();
3564
3724
  function load(client, agent) {
3565
3725
  let byAgent = shared.get(client);
@@ -3583,11 +3743,11 @@ function load(client, agent) {
3583
3743
  __name(load, "load");
3584
3744
  function useToolCatalog(options) {
3585
3745
  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(() => {
3746
+ const [entries, setEntries] = useState10([]);
3747
+ const [isLoading, setLoading] = useState10(enabled);
3748
+ const [error, setError] = useState10(null);
3749
+ const [generation, setGeneration] = useState10(0);
3750
+ useEffect10(() => {
3591
3751
  if (!enabled) {
3592
3752
  setLoading(false);
3593
3753
  return;
@@ -3613,14 +3773,14 @@ function useToolCatalog(options) {
3613
3773
  enabled,
3614
3774
  generation
3615
3775
  ]);
3616
- const refresh = useCallback7(() => {
3776
+ const refresh = useCallback8(() => {
3617
3777
  shared.get(client)?.delete(agent ?? "");
3618
3778
  setGeneration((current) => current + 1);
3619
3779
  }, [
3620
3780
  client,
3621
3781
  agent
3622
3782
  ]);
3623
- const catalog = useMemo3(() => toolCatalogFrom(entries), [
3783
+ const catalog = useMemo6(() => toolCatalogFrom(entries), [
3624
3784
  entries
3625
3785
  ]);
3626
3786
  return {
@@ -3634,7 +3794,7 @@ function useToolCatalog(options) {
3634
3794
  __name(useToolCatalog, "useToolCatalog");
3635
3795
 
3636
3796
  // src/approvals/countdown.ts
3637
- import { useEffect as useEffect9, useRef as useRef8, useState as useState10 } from "react";
3797
+ import { useEffect as useEffect11, useRef as useRef9, useState as useState11 } from "react";
3638
3798
  function approvalCountdown(expiresAt, now = Date.now()) {
3639
3799
  const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
3640
3800
  if (!Number.isFinite(deadline)) {
@@ -3652,10 +3812,10 @@ function approvalCountdown(expiresAt, now = Date.now()) {
3652
3812
  __name(approvalCountdown, "approvalCountdown");
3653
3813
  function useApprovalCountdown(expiresAt, options = {}) {
3654
3814
  const { intervalMs = 1e3 } = options;
3655
- const nowRef = useRef8(options.now ?? Date.now);
3815
+ const nowRef = useRef9(options.now ?? Date.now);
3656
3816
  nowRef.current = options.now ?? Date.now;
3657
- const [state, setState] = useState10(() => approvalCountdown(expiresAt, nowRef.current()));
3658
- useEffect9(() => {
3817
+ const [state, setState] = useState11(() => approvalCountdown(expiresAt, nowRef.current()));
3818
+ useEffect11(() => {
3659
3819
  const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
3660
3820
  const first = read();
3661
3821
  setState(first);
@@ -3897,20 +4057,20 @@ __name(sumUsage, "sumUsage");
3897
4057
 
3898
4058
  // src/use-agent-chat.ts
3899
4059
  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";
4060
+ import { useCallback as useCallback9, useEffect as useEffect12, useMemo as useMemo7, useRef as useRef10, useState as useState12 } from "react";
3901
4061
  function useAgentChat(options) {
3902
- const latest = useRef9(options);
4062
+ const latest = useRef10(options);
3903
4063
  latest.current = options;
3904
- const [runId, setRunId] = useState11(options.resumeRunId);
3905
- const runIdRef = useRef9(runId);
4064
+ const [runId, setRunId] = useState12(options.resumeRunId);
4065
+ const runIdRef = useRef10(runId);
3906
4066
  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(() => {
4067
+ const settlingRunIdRef = useRef10(void 0);
4068
+ const autoResumeRunIdRef = useRef10(void 0);
4069
+ const [autoResume, setAutoResume] = useState12(false);
4070
+ const [activeRunId, setActiveRunId] = useState12(null);
4071
+ const regenerateNext = useRef10(false);
4072
+ const createdThreadId = useRef10(void 0);
4073
+ const client = useMemo7(() => {
3914
4074
  if (options.backend) return options.backend;
3915
4075
  if (options.client) return options.client;
3916
4076
  return new AgentClient({
@@ -3926,11 +4086,11 @@ function useAgentChat(options) {
3926
4086
  getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
3927
4087
  });
3928
4088
  }, []);
3929
- const [connection, setConnection] = useState11({
4089
+ const [connection, setConnection] = useState12({
3930
4090
  status: "live"
3931
4091
  });
3932
- const resyncAfterSettle = useRef9(false);
3933
- useEffect10(() => {
4092
+ const resyncAfterSettle = useRef10(false);
4093
+ useEffect12(() => {
3934
4094
  if (!options.resume || options.threadId === void 0) return;
3935
4095
  let cancelled = false;
3936
4096
  const threadId = options.threadId;
@@ -3950,7 +4110,7 @@ function useAgentChat(options) {
3950
4110
  options.resume,
3951
4111
  options.threadId
3952
4112
  ]);
3953
- const transport = useMemo4(() => {
4113
+ const transport = useMemo7(() => {
3954
4114
  function onMeta(meta) {
3955
4115
  settlingRunIdRef.current = meta.runId;
3956
4116
  setRunId(meta.runId);
@@ -3987,6 +4147,9 @@ function useAgentChat(options) {
3987
4147
  ...threadId !== void 0 ? {
3988
4148
  threadId
3989
4149
  } : {},
4150
+ ...current.model !== void 0 ? {
4151
+ model: current.model
4152
+ } : {},
3990
4153
  ...pageContext ? {
3991
4154
  pageContext
3992
4155
  } : {},
@@ -4002,7 +4165,7 @@ function useAgentChat(options) {
4002
4165
  }, "onAttemptStart")
4003
4166
  });
4004
4167
  }, []);
4005
- const backgroundRef = useRef9(() => Promise.resolve());
4168
+ const backgroundRef = useRef10(() => Promise.resolve());
4006
4169
  const chat = useChat({
4007
4170
  transport,
4008
4171
  resume: options.resumeRunId !== void 0 || autoResume,
@@ -4051,7 +4214,7 @@ function useAgentChat(options) {
4051
4214
  }
4052
4215
  }, "onFinish")
4053
4216
  });
4054
- const chatRef = useRef9(chat);
4217
+ const chatRef = useRef10(chat);
4055
4218
  chatRef.current = chat;
4056
4219
  async function resyncFromThread() {
4057
4220
  const threadId = latest.current.threadId ?? createdThreadId.current;
@@ -4063,11 +4226,13 @@ function useAgentChat(options) {
4063
4226
  }
4064
4227
  }
4065
4228
  __name(resyncFromThread, "resyncFromThread");
4066
- const turnInFlight = useRef9(false);
4067
- const isTurnInFlight = useCallback8(() => turnInFlight.current || transport.isAttemptLive, [
4229
+ const turnInFlight = useRef10(false);
4230
+ const isTurnInFlight = useCallback9(() => turnInFlight.current || transport.isAttemptLive, [
4068
4231
  transport
4069
4232
  ]);
4070
- const sendMessage = useCallback8(async (...args) => {
4233
+ const sendMessage = useCallback9(async (...args) => {
4234
+ const blocked = latest.current.blocked;
4235
+ if (blocked != null) throw new QuotaBlockedError(blocked);
4071
4236
  if (isTurnInFlight()) return;
4072
4237
  turnInFlight.current = true;
4073
4238
  try {
@@ -4078,15 +4243,15 @@ function useAgentChat(options) {
4078
4243
  }, [
4079
4244
  isTurnInFlight
4080
4245
  ]);
4081
- const addToolResult = useCallback8(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
4246
+ const addToolResult = useCallback9(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
4082
4247
  tool,
4083
4248
  toolCallId,
4084
4249
  output
4085
4250
  }), []);
4086
- const [threads, setThreads] = useState11([]);
4087
- const [quota, setQuota] = useState11(null);
4088
- const [backgroundRuns, setBackgroundRuns] = useState11([]);
4089
- const refreshBackground = useCallback8(async () => {
4251
+ const [threads, setThreads] = useState12([]);
4252
+ const [quota, setQuota] = useState12(null);
4253
+ const [backgroundRuns, setBackgroundRuns] = useState12([]);
4254
+ const refreshBackground = useCallback9(async () => {
4090
4255
  const threadId = latest.current.threadId ?? createdThreadId.current;
4091
4256
  if (threadId === void 0) {
4092
4257
  return;
@@ -4111,7 +4276,7 @@ function useAgentChat(options) {
4111
4276
  ]);
4112
4277
  backgroundRef.current = refreshBackground;
4113
4278
  const isWorking = backgroundRuns.some((run) => run.status === "running");
4114
- useEffect10(() => {
4279
+ useEffect12(() => {
4115
4280
  if (options.background !== true || options.threadId === void 0) {
4116
4281
  return;
4117
4282
  }
@@ -4121,7 +4286,7 @@ function useAgentChat(options) {
4121
4286
  options.threadId,
4122
4287
  refreshBackground
4123
4288
  ]);
4124
- useEffect10(() => {
4289
+ useEffect12(() => {
4125
4290
  const every = latest.current.backgroundPollMs ?? 5e3;
4126
4291
  if (latest.current.background !== true || !isWorking || every <= 0) {
4127
4292
  return;
@@ -4132,26 +4297,26 @@ function useAgentChat(options) {
4132
4297
  isWorking,
4133
4298
  refreshBackground
4134
4299
  ]);
4135
- const loadThreads = useCallback8(async () => {
4300
+ const loadThreads = useCallback9(async () => {
4136
4301
  const list = await client.listThreads();
4137
4302
  setThreads(list);
4138
4303
  return list;
4139
4304
  }, [
4140
4305
  client
4141
4306
  ]);
4142
- const loadThread = useCallback8((id) => client.getThread(id), [
4307
+ const loadThread = useCallback9((id) => client.getThread(id), [
4143
4308
  client
4144
4309
  ]);
4145
- const deleteThread = useCallback8(async (id) => {
4310
+ const deleteThread = useCallback9(async (id) => {
4146
4311
  await client.deleteThread(id);
4147
4312
  setThreads((current) => current.filter((thread) => thread.id !== id));
4148
4313
  }, [
4149
4314
  client
4150
4315
  ]);
4151
- const forkThread = useCallback8((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
4316
+ const forkThread = useCallback9((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
4152
4317
  client
4153
4318
  ]);
4154
- const renameThread = useCallback8(async (id, title) => {
4319
+ const renameThread = useCallback9(async (id, title) => {
4155
4320
  await client.updateThread(id, {
4156
4321
  title
4157
4322
  });
@@ -4162,24 +4327,24 @@ function useAgentChat(options) {
4162
4327
  }, [
4163
4328
  client
4164
4329
  ]);
4165
- const promoteThread = useCallback8(async (id) => {
4330
+ const promoteThread = useCallback9(async (id) => {
4166
4331
  await requireBackendMethod(client, "promoteThread")(id);
4167
4332
  await loadThreads();
4168
4333
  }, [
4169
4334
  client,
4170
4335
  loadThreads
4171
4336
  ]);
4172
- const truncateFromMessage = useCallback8((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
4337
+ const truncateFromMessage = useCallback9((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
4173
4338
  client
4174
4339
  ]);
4175
- const loadQuota = useCallback8(async () => {
4340
+ const loadQuota = useCallback9(async () => {
4176
4341
  const today = await requireBackendMethod(client, "getQuotaToday")();
4177
4342
  setQuota(today);
4178
4343
  return today;
4179
4344
  }, [
4180
4345
  client
4181
4346
  ]);
4182
- const cancel = useCallback8(async () => {
4347
+ const cancel = useCallback9(async () => {
4183
4348
  chatRef.current.stop();
4184
4349
  const activeRunId2 = runIdRef.current;
4185
4350
  if (activeRunId2) {
@@ -4191,7 +4356,7 @@ function useAgentChat(options) {
4191
4356
  }, [
4192
4357
  client
4193
4358
  ]);
4194
- const approve = useCallback8(async ({ toolCallId, remember, via }) => {
4359
+ const approve = useCallback9(async ({ toolCallId, remember, via }) => {
4195
4360
  await requireBackendMethod(client, "approveToolCall")({
4196
4361
  toolCallId,
4197
4362
  ...remember === true ? {
@@ -4204,7 +4369,7 @@ function useAgentChat(options) {
4204
4369
  }, [
4205
4370
  client
4206
4371
  ]);
4207
- const reject = useCallback8(async ({ toolCallId, reason, via }) => {
4372
+ const reject = useCallback9(async ({ toolCallId, reason, via }) => {
4208
4373
  await requireBackendMethod(client, "rejectToolCall")({
4209
4374
  toolCallId,
4210
4375
  ...reason !== void 0 ? {
@@ -4217,7 +4382,7 @@ function useAgentChat(options) {
4217
4382
  }, [
4218
4383
  client
4219
4384
  ]);
4220
- const answer = useCallback8(async ({ toolCallId, answers }) => {
4385
+ const answer = useCallback9(async ({ toolCallId, answers }) => {
4221
4386
  await requireBackendMethod(client, "answerToolCall")({
4222
4387
  toolCallId,
4223
4388
  ...answers !== void 0 ? {
@@ -4227,14 +4392,16 @@ function useAgentChat(options) {
4227
4392
  }, [
4228
4393
  client
4229
4394
  ]);
4230
- const skip = useCallback8(async ({ toolCallId }) => {
4395
+ const skip = useCallback9(async ({ toolCallId }) => {
4231
4396
  await requireBackendMethod(client, "skipToolCall")({
4232
4397
  toolCallId
4233
4398
  });
4234
4399
  }, [
4235
4400
  client
4236
4401
  ]);
4237
- const regenerate = useCallback8(() => {
4402
+ const regenerate = useCallback9(() => {
4403
+ const blocked = latest.current.blocked;
4404
+ if (blocked != null) throw new QuotaBlockedError(blocked);
4238
4405
  if (isTurnInFlight()) return;
4239
4406
  regenerateNext.current = true;
4240
4407
  turnInFlight.current = true;
@@ -4249,7 +4416,21 @@ function useAgentChat(options) {
4249
4416
  isWorking,
4250
4417
  refresh: refreshBackground
4251
4418
  };
4252
- const getThreadId = useCallback8(() => latest.current.threadId ?? createdThreadId.current, []);
4419
+ const setThreadModel = useCallback9(async (model) => {
4420
+ const threadId = latest.current.threadId ?? createdThreadId.current;
4421
+ if (threadId === void 0) {
4422
+ throw new Error("setThreadModel: this chat has no thread yet");
4423
+ }
4424
+ await client.updateThread(threadId, {
4425
+ model
4426
+ });
4427
+ notifyThreads(client, {
4428
+ type: "changed"
4429
+ });
4430
+ }, [
4431
+ client
4432
+ ]);
4433
+ const getThreadId = useCallback9(() => latest.current.threadId ?? createdThreadId.current, []);
4253
4434
  const status = connection.status === "reconnecting" ? "reconnecting" : chat.status;
4254
4435
  return {
4255
4436
  ...chat,
@@ -4268,6 +4449,7 @@ function useAgentChat(options) {
4268
4449
  * on the first send. A getter, because the created id is learned mid-stream.
4269
4450
  */
4270
4451
  getThreadId,
4452
+ setThreadModel,
4271
4453
  /** The backend this chat talks to — pass it to `useThreads`, `useMessageFeedback`, … */
4272
4454
  backend: client,
4273
4455
  /** Same object as {@link backend}; kept for callers that read it under its old name. */
@@ -4291,6 +4473,16 @@ function useAgentChat(options) {
4291
4473
  };
4292
4474
  }
4293
4475
  __name(useAgentChat, "useAgentChat");
4476
+ var QuotaBlockedError = class extends Error {
4477
+ static {
4478
+ __name(this, "QuotaBlockedError");
4479
+ }
4480
+ block;
4481
+ constructor(block) {
4482
+ super(block.reason ?? `The ${block.period === "day" ? "daily" : "monthly"} quota is used up`), this.block = block;
4483
+ this.name = "QuotaBlockedError";
4484
+ }
4485
+ };
4294
4486
  async function mergeHeaders(options) {
4295
4487
  const dynamic = await options.getHeaders?.() ?? {};
4296
4488
  return {
@@ -4309,6 +4501,7 @@ export {
4309
4501
  MessageItem,
4310
4502
  MessageItemView,
4311
4503
  MessageList,
4504
+ QuotaBlockedError,
4312
4505
  SPEECH_LANGUAGES,
4313
4506
  applyCompletion,
4314
4507
  approvalCountdown,
@@ -4343,11 +4536,14 @@ export {
4343
4536
  toolCallState,
4344
4537
  toolCatalogFrom,
4345
4538
  useAgentChat,
4539
+ useAgents,
4346
4540
  useApprovalCountdown,
4347
4541
  useChatTranscript,
4348
4542
  useComposerAutocomplete,
4349
4543
  useElapsed,
4350
4544
  useMessageFeedback,
4545
+ useModels,
4546
+ useQuota,
4351
4547
  useSpeechRecognition,
4352
4548
  useStickToBottom,
4353
4549
  useThreads,