@dudousxd/nestjs-agent-react 0.19.0 → 0.21.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.cjs CHANGED
@@ -35,6 +35,7 @@ __export(src_exports, {
35
35
  AgentChatTransport: () => AgentChatTransport,
36
36
  AgentClient: () => AgentClient,
37
37
  AgentHttpError: () => AgentHttpError,
38
+ AgentProvider: () => AgentProvider,
38
39
  AmbientRenderUiContext: () => AmbientRenderUiContext,
39
40
  ChatInput: () => ChatInput,
40
41
  DEFAULT_SPEECH_LANG: () => DEFAULT_SPEECH_LANG,
@@ -80,6 +81,7 @@ __export(src_exports, {
80
81
  storedThreadToUiMessages: () => storedThreadToUiMessages,
81
82
  toolCallState: () => toolCallState,
82
83
  toolCatalogFrom: () => toolCatalogFrom,
84
+ useAgentBackend: () => useAgentBackend,
83
85
  useAgentChat: () => useAgentChat,
84
86
  useAgents: () => useAgents,
85
87
  useAmbientRenderUi: () => useAmbientRenderUi,
@@ -114,6 +116,11 @@ var AgentHttpError = class extends Error {
114
116
  this.name = "AgentHttpError";
115
117
  }
116
118
  };
119
+ function normalizeAgentPath(path) {
120
+ const trimmed = (path ?? "agent").replace(/^\/+|\/+$/g, "");
121
+ return trimmed === "" ? "" : `/${trimmed}`;
122
+ }
123
+ __name(normalizeAgentPath, "normalizeAgentPath");
117
124
  var HEADER_RUN_ID = "x-agent-run-id";
118
125
  var HEADER_THREAD_ID = "x-agent-thread-id";
119
126
  var AgentClient = class {
@@ -124,9 +131,9 @@ var AgentClient = class {
124
131
  constructor(options = {}) {
125
132
  this.options = options;
126
133
  }
127
- /** `POST /agent/chat` → the turn's SSE stream. Throws {@link AgentHttpError} on a non-2xx. */
134
+ /** `POST <path>/chat` → the turn's SSE stream. Throws {@link AgentHttpError} on a non-2xx. */
128
135
  async openChatStream(request) {
129
- const response = await this.fetchImpl()(`${this.baseUrl()}/agent/chat`, {
136
+ const response = await this.fetchImpl()(`${this.root()}/chat`, {
130
137
  method: "POST",
131
138
  headers: {
132
139
  "content-type": "application/json",
@@ -141,18 +148,18 @@ var AgentClient = class {
141
148
  } : {}
142
149
  });
143
150
  if (!response.ok || !response.body) {
144
- throw new AgentHttpError(response.status, "POST", "/agent/chat", response.statusText);
151
+ throw new AgentHttpError(response.status, "POST", `${this.agentPath()}/chat`, response.statusText);
145
152
  }
146
153
  return streamResponse(response);
147
154
  }
148
155
  /**
149
- * `GET /agent/chat/:runId/stream[?after=<seq>]` → the run's SSE stream, or `null` when nothing is
156
+ * `GET <path>/chat/:runId/stream[?after=<seq>]` → the run's SSE stream, or `null` when nothing is
150
157
  * streaming under that id (404).
151
158
  */
152
159
  async resumeChatStream(request) {
153
- const path = `/agent/chat/${encodeURIComponent(request.runId)}/stream`;
160
+ const path = `/chat/${encodeURIComponent(request.runId)}/stream`;
154
161
  const query = request.after !== void 0 && request.after > 0 ? `?after=${request.after}` : "";
155
- const response = await this.fetchImpl()(`${this.baseUrl()}${path}${query}`, {
162
+ const response = await this.fetchImpl()(`${this.root()}${path}${query}`, {
156
163
  method: "GET",
157
164
  headers: {
158
165
  accept: "text/event-stream",
@@ -168,7 +175,7 @@ var AgentClient = class {
168
175
  return null;
169
176
  }
170
177
  if (!response.ok || !response.body) {
171
- throw new AgentHttpError(response.status, "GET", path, response.statusText);
178
+ throw new AgentHttpError(response.status, "GET", `${this.agentPath()}${path}`, response.statusText);
172
179
  }
173
180
  return streamResponse(response);
174
181
  }
@@ -177,10 +184,10 @@ var AgentClient = class {
177
184
  * the stored rating.
178
185
  */
179
186
  setMessageFeedback(messageId, input) {
180
- return this.request("POST", `/agent/messages/${encodeURIComponent(messageId)}/feedback`, input);
187
+ return this.request("POST", `/messages/${encodeURIComponent(messageId)}/feedback`, input);
181
188
  }
182
189
  listThreads() {
183
- return this.request("GET", "/agent/threads");
190
+ return this.request("GET", "/threads");
184
191
  }
185
192
  /**
186
193
  * The skills this caller can invoke right now, scope-resolved — the same list, built by the same
@@ -190,7 +197,7 @@ var AgentClient = class {
190
197
  */
191
198
  listSkills(threadId) {
192
199
  const query = threadId === void 0 ? "" : `?threadId=${encodeURIComponent(threadId)}`;
193
- return this.request("GET", `/agent/skills${query}`);
200
+ return this.request("GET", `/skills${query}`);
194
201
  }
195
202
  /**
196
203
  * The tools this caller can reach through `agent` (the default agent when omitted), each with the
@@ -199,38 +206,42 @@ var AgentClient = class {
199
206
  */
200
207
  listTools(agent) {
201
208
  const query = agent === void 0 ? "" : `?agent=${encodeURIComponent(agent)}`;
202
- return this.request("GET", `/agent/tools${query}`);
209
+ return this.request("GET", `/tools${query}`);
203
210
  }
204
211
  getThread(id) {
205
- return this.request("GET", `/agent/threads/${encodeURIComponent(id)}`);
212
+ return this.request("GET", `/threads/${encodeURIComponent(id)}`);
206
213
  }
207
214
  deleteThread(id) {
208
- return this.request("DELETE", `/agent/threads/${encodeURIComponent(id)}`);
215
+ return this.request("DELETE", `/threads/${encodeURIComponent(id)}`);
209
216
  }
210
217
  forkFromMessage(threadId, messageId) {
211
- return this.request("POST", `/agent/threads/${encodeURIComponent(threadId)}/fork-from/${encodeURIComponent(messageId)}`);
218
+ return this.request("POST", `/threads/${encodeURIComponent(threadId)}/fork-from/${encodeURIComponent(messageId)}`);
212
219
  }
213
220
  renameThread(id, title) {
214
221
  return this.updateThread(id, {
215
222
  title
216
223
  });
217
224
  }
218
- /** General `PATCH /agent/threads/:threadId` — title and/or the thread's pinned default agent. */
225
+ /** General `PATCH <path>/threads/:threadId` — title and/or the thread's pinned default agent. */
219
226
  updateThread(id, patch) {
220
- return this.request("PATCH", `/agent/threads/${encodeURIComponent(id)}`, patch);
227
+ return this.request("PATCH", `/threads/${encodeURIComponent(id)}`, patch);
221
228
  }
222
229
  /**
223
230
  * Uploads a file (image/PDF) for a vision-capable model turn. Multipart, field name `file` —
224
- * mirrors the backend's `POST /agent/attachments`. The returned {@link MessageAttachment} is
231
+ * mirrors the backend's `POST <path>/attachments`. The returned {@link MessageAttachment} is
225
232
  * what a caller then rides on `sendMessage({ text }, { body: { attachments: [...] } })`.
226
233
  */
227
234
  async uploadAttachment(file, options = {}) {
235
+ const upload = this.options.attachments?.upload;
236
+ if (upload !== void 0) {
237
+ return upload(file, options, this.connection());
238
+ }
228
239
  if (options.onProgress !== void 0 && this.options.fetch === void 0 && typeof XMLHttpRequest !== "undefined") {
229
240
  return this.uploadWithProgress(file, options);
230
241
  }
231
242
  const formData = new FormData();
232
243
  formData.append("file", file);
233
- const response = await this.fetchImpl()(`${this.baseUrl()}/agent/attachments`, {
244
+ const response = await this.fetchImpl()(`${this.root()}/attachments`, {
234
245
  method: "POST",
235
246
  headers: {
236
247
  accept: "application/json",
@@ -242,7 +253,7 @@ var AgentClient = class {
242
253
  signal: options.signal
243
254
  } : {}
244
255
  });
245
- const attachment = await this.handleResponse(response, "POST", "/agent/attachments");
256
+ const attachment = await this.handleResponse(response, "POST", `${this.agentPath()}/attachments`);
246
257
  options.onProgress?.(1);
247
258
  return attachment;
248
259
  }
@@ -251,7 +262,7 @@ var AgentClient = class {
251
262
  accept: "application/json",
252
263
  ...await this.resolveHeaders()
253
264
  };
254
- const url = `${this.baseUrl()}/agent/attachments`;
265
+ const url = `${this.root()}/attachments`;
255
266
  return new Promise((resolve, reject) => {
256
267
  const xhr = new XMLHttpRequest();
257
268
  xhr.open("POST", url);
@@ -262,7 +273,7 @@ var AgentClient = class {
262
273
  };
263
274
  xhr.onload = () => {
264
275
  if (xhr.status < 200 || xhr.status >= 300) {
265
- reject(new AgentHttpError(xhr.status, "POST", "/agent/attachments", xhr.statusText));
276
+ reject(new AgentHttpError(xhr.status, "POST", `${this.agentPath()}/attachments`, xhr.statusText));
266
277
  return;
267
278
  }
268
279
  onProgress?.(1);
@@ -285,39 +296,39 @@ var AgentClient = class {
285
296
  });
286
297
  }
287
298
  promoteThread(id) {
288
- return this.request("POST", `/agent/threads/${encodeURIComponent(id)}/promote`);
299
+ return this.request("POST", `/threads/${encodeURIComponent(id)}/promote`);
289
300
  }
290
301
  truncateFromMessage(threadId, messageId) {
291
- return this.request("DELETE", `/agent/threads/${encodeURIComponent(threadId)}/from/${encodeURIComponent(messageId)}`);
302
+ return this.request("DELETE", `/threads/${encodeURIComponent(threadId)}/from/${encodeURIComponent(messageId)}`);
292
303
  }
293
- /** `GET /agent/models?agent=` — the models this caller may pick, grouped by provider. */
304
+ /** `GET <path>/models?agent=` — the models this caller may pick, grouped by provider. */
294
305
  listModels(agent) {
295
306
  const query = agent === void 0 ? "" : `?agent=${encodeURIComponent(agent)}`;
296
- return this.request("GET", `/agent/models${query}`);
307
+ return this.request("GET", `/models${query}`);
297
308
  }
298
- /** `GET /agent/agents` — the registered agents, the default one flagged. */
309
+ /** `GET <path>/agents` — the registered agents, the default one flagged. */
299
310
  listAgents() {
300
- return this.request("GET", "/agent/agents");
311
+ return this.request("GET", "/agents");
301
312
  }
302
- /** `GET /agent/quota` — the caller's budget windows and the one blocking sends, if any. */
313
+ /** `GET <path>/quota` — the caller's budget windows and the one blocking sends, if any. */
303
314
  getQuota() {
304
- return this.request("GET", "/agent/quota");
315
+ return this.request("GET", "/quota");
305
316
  }
306
317
  getQuotaToday() {
307
- return this.request("GET", "/agent/quota/today");
318
+ return this.request("GET", "/quota/today");
308
319
  }
309
320
  cancelStream(runId) {
310
- return this.request("POST", `/agent/chat/${encodeURIComponent(runId)}/cancel`);
321
+ return this.request("POST", `/chat/${encodeURIComponent(runId)}/cancel`);
311
322
  }
312
323
  /**
313
324
  * `remember` approves later calls of the same tool in the same thread; `via` names the surface
314
325
  * the decision came through (the server records `'web'` when omitted).
315
326
  */
316
327
  approveToolCall(input) {
317
- return this.request("POST", "/agent/tool-call/approve", input);
328
+ return this.request("POST", "/tool-call/approve", input);
318
329
  }
319
330
  rejectToolCall(input) {
320
- return this.request("POST", "/agent/tool-call/reject", input);
331
+ return this.request("POST", "/tool-call/reject", input);
321
332
  }
322
333
  /**
323
334
  * Settle a parked question set. `answers` is questionId → chosen option values; a question left
@@ -326,7 +337,7 @@ var AgentClient = class {
326
337
  * answer — which is the point of the surface, so it is a valid submission rather than a blank.
327
338
  */
328
339
  answerToolCall(input) {
329
- return this.request("POST", "/agent/tool-call/answer", input);
340
+ return this.request("POST", "/tool-call/answer", input);
330
341
  }
331
342
  /**
332
343
  * Decline to answer and let the agent proceed on its own pre-picked values. Lands on the same
@@ -334,13 +345,30 @@ var AgentClient = class {
334
345
  * evidence the user chose them.
335
346
  */
336
347
  skipToolCall(input) {
337
- return this.request("POST", "/agent/tool-call/skip", input);
348
+ return this.request("POST", "/tool-call/skip", input);
338
349
  }
339
350
  fetchImpl() {
340
351
  return this.options.fetch ?? globalThis.fetch;
341
352
  }
353
+ /** This client's connection, for an {@link AttachmentUploadStrategy}. */
354
+ connection() {
355
+ return {
356
+ baseUrl: this.baseUrl(),
357
+ path: this.agentPath(),
358
+ headers: /* @__PURE__ */ __name(() => this.resolveHeaders(), "headers"),
359
+ fetch: this.fetchImpl(),
360
+ ...this.credentials()
361
+ };
362
+ }
342
363
  baseUrl() {
343
- return (this.options.baseUrl ?? "").replace(/\/$/, "");
364
+ return (this.options.baseUrl ?? "").replace(/\/+$/, "");
365
+ }
366
+ agentPath() {
367
+ return normalizeAgentPath(this.options.path);
368
+ }
369
+ /** Origin + agent path: what every route hangs off. */
370
+ root() {
371
+ return `${this.baseUrl()}${this.agentPath()}`;
344
372
  }
345
373
  async resolveHeaders() {
346
374
  const dynamic = await this.options.getHeaders?.() ?? {};
@@ -354,7 +382,8 @@ var AgentClient = class {
354
382
  credentials: this.options.credentials
355
383
  } : {};
356
384
  }
357
- async request(method, path, body) {
385
+ async request(method, route, body) {
386
+ const path = `${this.agentPath()}${route}`;
358
387
  const response = await this.fetchImpl()(`${this.baseUrl()}${path}`, {
359
388
  method,
360
389
  headers: {
@@ -485,6 +514,9 @@ var AgentChatTransport = class {
485
514
  ...options.baseUrl !== void 0 ? {
486
515
  baseUrl: options.baseUrl
487
516
  } : {},
517
+ ...options.path !== void 0 ? {
518
+ path: options.path
519
+ } : {},
488
520
  ...options.headers !== void 0 ? {
489
521
  headers: options.headers
490
522
  } : {},
@@ -1190,7 +1222,7 @@ function dragHasFiles(data) {
1190
1222
  __name(dragHasFiles, "dragHasFiles");
1191
1223
 
1192
1224
  // src/attachments/use-attachments.ts
1193
- var import_react2 = require("react");
1225
+ var import_react6 = require("react");
1194
1226
 
1195
1227
  // src/backend.ts
1196
1228
  var AgentBackendUnsupportedError = class extends Error {
@@ -1212,6 +1244,570 @@ function requireBackendMethod(backend, name) {
1212
1244
  }
1213
1245
  __name(requireBackendMethod, "requireBackendMethod");
1214
1246
 
1247
+ // src/provider.tsx
1248
+ var import_react5 = require("react");
1249
+
1250
+ // src/components/ambient-ui.ts
1251
+ var import_react2 = require("react");
1252
+ function sharedContext(key) {
1253
+ const symbol = Symbol.for(key);
1254
+ const holder = globalThis;
1255
+ const existing = holder[symbol];
1256
+ if (existing !== void 0) return existing;
1257
+ const created = (0, import_react2.createContext)(null);
1258
+ holder[symbol] = created;
1259
+ return created;
1260
+ }
1261
+ __name(sharedContext, "sharedContext");
1262
+ var AmbientRenderUiContext = sharedContext("@dudousxd/nestjs-agent-react:ambient-render-ui");
1263
+ function useAmbientRenderUi() {
1264
+ return (0, import_react2.useContext)(AmbientRenderUiContext);
1265
+ }
1266
+ __name(useAmbientRenderUi, "useAmbientRenderUi");
1267
+
1268
+ // src/genui/generative-ui.tsx
1269
+ var import_react4 = require("react");
1270
+
1271
+ // src/genui/use-generative-ui.ts
1272
+ var import_react3 = require("react");
1273
+
1274
+ // src/genui/types.ts
1275
+ var GENUI_TREE_COMPONENT = "genui:tree";
1276
+
1277
+ // src/genui/use-generative-ui.ts
1278
+ function isRecord(value) {
1279
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1280
+ }
1281
+ __name(isRecord, "isRecord");
1282
+ function toGenerativeUIItem(part) {
1283
+ if (!isRecord(part)) return null;
1284
+ const source = part.type === "data-ui" && isRecord(part.data) ? part.data : part;
1285
+ if (typeof source.component !== "string") return null;
1286
+ const id = typeof source.id === "string" ? source.id : typeof part.id === "string" ? part.id : null;
1287
+ if (id === null) return null;
1288
+ return {
1289
+ id,
1290
+ component: source.component,
1291
+ props: isRecord(source.props) ? source.props : {},
1292
+ version: typeof source.version === "number" ? source.version : null,
1293
+ toolCallId: typeof source.toolCallId === "string" ? source.toolCallId : null
1294
+ };
1295
+ }
1296
+ __name(toGenerativeUIItem, "toGenerativeUIItem");
1297
+ var resolverCaches = /* @__PURE__ */ new WeakMap();
1298
+ function resolveCached(resolve, name, version) {
1299
+ let cache = resolverCaches.get(resolve);
1300
+ if (cache === void 0) {
1301
+ cache = /* @__PURE__ */ new Map();
1302
+ resolverCaches.set(resolve, cache);
1303
+ }
1304
+ const key = `${name}@${version ?? ""}`;
1305
+ const hit = cache.get(key);
1306
+ if (hit !== void 0) return hit;
1307
+ let entry;
1308
+ try {
1309
+ const result = resolve(name, version);
1310
+ if (result instanceof Promise) {
1311
+ entry = {
1312
+ resolution: {
1313
+ status: "loading"
1314
+ },
1315
+ settled: null
1316
+ };
1317
+ entry.settled = result.then((Component2) => {
1318
+ entry.resolution = Component2 ? {
1319
+ status: "ready",
1320
+ Component: Component2
1321
+ } : {
1322
+ status: "unknown"
1323
+ };
1324
+ }, (error) => {
1325
+ entry.resolution = {
1326
+ status: "error",
1327
+ error
1328
+ };
1329
+ });
1330
+ } else {
1331
+ entry = {
1332
+ resolution: result ? {
1333
+ status: "ready",
1334
+ Component: result
1335
+ } : {
1336
+ status: "unknown"
1337
+ },
1338
+ settled: null
1339
+ };
1340
+ }
1341
+ } catch (error) {
1342
+ entry = {
1343
+ resolution: {
1344
+ status: "error",
1345
+ error
1346
+ },
1347
+ settled: null
1348
+ };
1349
+ }
1350
+ cache.set(key, entry);
1351
+ return entry;
1352
+ }
1353
+ __name(resolveCached, "resolveCached");
1354
+ function useResolvedComponent(name, version, registry, resolve, fallbackTree) {
1355
+ const [, setTick] = (0, import_react3.useState)(0);
1356
+ const own = registry[name];
1357
+ const entry = own !== void 0 || resolve === void 0 ? null : resolveCached(resolve, name, version);
1358
+ const pending = entry?.resolution.status === "loading" ? entry.settled : null;
1359
+ (0, import_react3.useEffect)(() => {
1360
+ if (pending === null) return;
1361
+ let live = true;
1362
+ void pending.then(() => {
1363
+ if (live) setTick((tick) => tick + 1);
1364
+ });
1365
+ return () => {
1366
+ live = false;
1367
+ };
1368
+ }, [
1369
+ pending
1370
+ ]);
1371
+ if (own !== void 0) return {
1372
+ status: "ready",
1373
+ Component: own
1374
+ };
1375
+ if (entry !== null && entry.resolution.status !== "unknown") return entry.resolution;
1376
+ if (name === GENUI_TREE_COMPONENT && fallbackTree !== void 0) {
1377
+ return {
1378
+ status: "ready",
1379
+ Component: fallbackTree
1380
+ };
1381
+ }
1382
+ return {
1383
+ status: "unknown"
1384
+ };
1385
+ }
1386
+ __name(useResolvedComponent, "useResolvedComponent");
1387
+ function useValidatedProps(catalog, name, props) {
1388
+ const checked = catalog?.has(name) === true;
1389
+ const immediate = (0, import_react3.useMemo)(() => {
1390
+ if (!checked || catalog === void 0) return {
1391
+ status: "ok",
1392
+ props
1393
+ };
1394
+ const result = catalog.validateSync?.(name, props);
1395
+ if (result === void 0) return null;
1396
+ return result.ok ? {
1397
+ status: "ok",
1398
+ props: result.value
1399
+ } : {
1400
+ status: "invalid",
1401
+ issues: result.issues
1402
+ };
1403
+ }, [
1404
+ checked,
1405
+ catalog,
1406
+ name,
1407
+ props
1408
+ ]);
1409
+ const [late, setLate] = (0, import_react3.useState)(null);
1410
+ (0, import_react3.useEffect)(() => {
1411
+ if (immediate !== null || catalog === void 0) return;
1412
+ let live = true;
1413
+ catalog.validate(name, props).then((result) => {
1414
+ if (!live) return;
1415
+ setLate({
1416
+ props,
1417
+ result: result.ok ? {
1418
+ status: "ok",
1419
+ props: result.value
1420
+ } : {
1421
+ status: "invalid",
1422
+ issues: result.issues
1423
+ }
1424
+ });
1425
+ }, (error) => {
1426
+ if (!live) return;
1427
+ setLate({
1428
+ props,
1429
+ result: {
1430
+ status: "invalid",
1431
+ issues: [
1432
+ {
1433
+ path: [],
1434
+ message: error instanceof Error ? error.message : String(error)
1435
+ }
1436
+ ]
1437
+ }
1438
+ });
1439
+ });
1440
+ return () => {
1441
+ live = false;
1442
+ };
1443
+ }, [
1444
+ immediate,
1445
+ catalog,
1446
+ name,
1447
+ props
1448
+ ]);
1449
+ if (immediate !== null) return immediate;
1450
+ return late !== null && late.props === props ? late.result : {
1451
+ status: "pending"
1452
+ };
1453
+ }
1454
+ __name(useValidatedProps, "useValidatedProps");
1455
+ function useGenerativeUIState(part, options, fallbackTree) {
1456
+ const item = (0, import_react3.useMemo)(() => toGenerativeUIItem(part), [
1457
+ part
1458
+ ]);
1459
+ const name = item?.component ?? "";
1460
+ const resolution = useResolvedComponent(name, item?.version ?? null, options.registry, item === null ? void 0 : options.resolveComponent, fallbackTree);
1461
+ const empty = (0, import_react3.useMemo)(() => ({}), []);
1462
+ const validation = useValidatedProps(item === null || name === GENUI_TREE_COMPONENT ? void 0 : options.catalog, name, item?.props ?? empty);
1463
+ if (item === null) return null;
1464
+ if (resolution.status === "loading") return {
1465
+ status: "loading",
1466
+ item
1467
+ };
1468
+ if (resolution.status === "unknown") return {
1469
+ status: "problem",
1470
+ reason: "unknown",
1471
+ item
1472
+ };
1473
+ if (resolution.status === "error") {
1474
+ return {
1475
+ status: "problem",
1476
+ reason: "error",
1477
+ item,
1478
+ error: resolution.error
1479
+ };
1480
+ }
1481
+ if (validation.status === "pending") return {
1482
+ status: "loading",
1483
+ item
1484
+ };
1485
+ if (validation.status === "invalid") {
1486
+ return {
1487
+ status: "problem",
1488
+ reason: "invalid",
1489
+ item,
1490
+ issues: validation.issues
1491
+ };
1492
+ }
1493
+ return {
1494
+ status: "ready",
1495
+ item,
1496
+ Component: resolution.Component,
1497
+ props: validation.props
1498
+ };
1499
+ }
1500
+ __name(useGenerativeUIState, "useGenerativeUIState");
1501
+
1502
+ // src/genui/generative-ui.tsx
1503
+ var TreeScopeContext = /* @__PURE__ */ (0, import_react4.createContext)(null);
1504
+ function renderFallback(fallback2, problem) {
1505
+ if (typeof fallback2 === "function") return fallback2(problem);
1506
+ return fallback2 ?? null;
1507
+ }
1508
+ __name(renderFallback, "renderFallback");
1509
+ var ItemBoundary = class ItemBoundary2 extends import_react4.Component {
1510
+ static {
1511
+ __name(this, "ItemBoundary");
1512
+ }
1513
+ state = {
1514
+ error: void 0,
1515
+ failed: false
1516
+ };
1517
+ static getDerivedStateFromError(error) {
1518
+ return {
1519
+ error,
1520
+ failed: true
1521
+ };
1522
+ }
1523
+ componentDidCatch(error, _info) {
1524
+ this.props.onError?.(error, this.props.item);
1525
+ }
1526
+ componentDidUpdate(previous) {
1527
+ if (this.state.failed && previous.item !== this.props.item) {
1528
+ this.setState({
1529
+ error: void 0,
1530
+ failed: false
1531
+ });
1532
+ }
1533
+ }
1534
+ render() {
1535
+ if (this.state.failed) {
1536
+ return renderFallback(this.props.fallback, {
1537
+ reason: "error",
1538
+ item: this.props.item,
1539
+ error: this.state.error
1540
+ });
1541
+ }
1542
+ return this.props.children;
1543
+ }
1544
+ };
1545
+ function nodeItem(node, id) {
1546
+ return {
1547
+ id,
1548
+ component: node.type,
1549
+ props: node.props ?? {},
1550
+ version: null,
1551
+ toolCallId: null
1552
+ };
1553
+ }
1554
+ __name(nodeItem, "nodeItem");
1555
+ function TreeNode({ node, id }) {
1556
+ const scope = (0, import_react4.useContext)(TreeScopeContext);
1557
+ const item = (0, import_react4.useMemo)(() => nodeItem(node, id), [
1558
+ node,
1559
+ id
1560
+ ]);
1561
+ const resolution = useResolvedComponent(node.type, null, scope?.options.registry ?? {}, scope?.options.resolveComponent);
1562
+ const validation = useValidatedProps(scope?.options.catalog, node.type, item.props);
1563
+ if (scope === null) return null;
1564
+ if (resolution.status === "loading" || validation.status === "pending") return scope.loading;
1565
+ if (resolution.status === "unknown") {
1566
+ return renderFallback(scope.fallback, {
1567
+ reason: "unknown",
1568
+ item
1569
+ });
1570
+ }
1571
+ if (resolution.status === "error") {
1572
+ return renderFallback(scope.fallback, {
1573
+ reason: "error",
1574
+ item,
1575
+ error: resolution.error
1576
+ });
1577
+ }
1578
+ if (validation.status === "invalid") {
1579
+ return renderFallback(scope.fallback, {
1580
+ reason: "invalid",
1581
+ item,
1582
+ issues: validation.issues
1583
+ });
1584
+ }
1585
+ const Renderer = resolution.Component;
1586
+ const children = Array.isArray(node.children) ? node.children : [];
1587
+ return /* @__PURE__ */ React.createElement(Renderer, validation.props, children.length > 0 ? children.map((child, index) => {
1588
+ const childId = `${id}.${index}`;
1589
+ return /* @__PURE__ */ React.createElement(ItemBoundary, {
1590
+ key: childId,
1591
+ item: nodeItem(child, childId),
1592
+ fallback: scope.fallback,
1593
+ onError: scope.onError
1594
+ }, /* @__PURE__ */ React.createElement(TreeNode, {
1595
+ node: child,
1596
+ id: childId
1597
+ }));
1598
+ }) : void 0);
1599
+ }
1600
+ __name(TreeNode, "TreeNode");
1601
+ function GenuiTree({ root }) {
1602
+ if (root === void 0 || root === null || typeof root.type !== "string") return null;
1603
+ return /* @__PURE__ */ React.createElement(TreeNode, {
1604
+ node: root,
1605
+ id: "root"
1606
+ });
1607
+ }
1608
+ __name(GenuiTree, "GenuiTree");
1609
+ function GenerativeUIScope({ registry, catalog, resolveComponent, fallback: fallback2, loading = null, onError, children }) {
1610
+ const scope = (0, import_react4.useMemo)(() => ({
1611
+ options: {
1612
+ registry,
1613
+ ...catalog !== void 0 ? {
1614
+ catalog
1615
+ } : {},
1616
+ ...resolveComponent !== void 0 ? {
1617
+ resolveComponent
1618
+ } : {}
1619
+ },
1620
+ fallback: fallback2,
1621
+ loading,
1622
+ onError
1623
+ }), [
1624
+ registry,
1625
+ catalog,
1626
+ resolveComponent,
1627
+ fallback2,
1628
+ loading,
1629
+ onError
1630
+ ]);
1631
+ return /* @__PURE__ */ React.createElement(TreeScopeContext.Provider, {
1632
+ value: scope
1633
+ }, children);
1634
+ }
1635
+ __name(GenerativeUIScope, "GenerativeUIScope");
1636
+ var GenuiContext = sharedContext("@dudousxd/nestjs-agent-react:genui-provider");
1637
+ function GenuiProvider({ registry, catalog, resolveComponent, treeRenderer, fallback: fallback2, loading, onError, children }) {
1638
+ const value = (0, import_react4.useMemo)(() => ({
1639
+ ...registry !== void 0 ? {
1640
+ registry
1641
+ } : {},
1642
+ ...catalog !== void 0 ? {
1643
+ catalog
1644
+ } : {},
1645
+ ...resolveComponent !== void 0 ? {
1646
+ resolveComponent
1647
+ } : {},
1648
+ ...treeRenderer !== void 0 ? {
1649
+ treeRenderer
1650
+ } : {},
1651
+ ...fallback2 !== void 0 ? {
1652
+ fallback: fallback2
1653
+ } : {},
1654
+ ...loading !== void 0 ? {
1655
+ loading
1656
+ } : {},
1657
+ ...onError !== void 0 ? {
1658
+ onError
1659
+ } : {}
1660
+ }), [
1661
+ registry,
1662
+ catalog,
1663
+ resolveComponent,
1664
+ treeRenderer,
1665
+ fallback2,
1666
+ loading,
1667
+ onError
1668
+ ]);
1669
+ const renderUi = (0, import_react4.useCallback)((block) => /* @__PURE__ */ React.createElement(GenerativeUI, {
1670
+ part: block
1671
+ }), []);
1672
+ return /* @__PURE__ */ React.createElement(GenuiContext.Provider, {
1673
+ value
1674
+ }, /* @__PURE__ */ React.createElement(AmbientRenderUiContext.Provider, {
1675
+ value: renderUi
1676
+ }, children));
1677
+ }
1678
+ __name(GenuiProvider, "GenuiProvider");
1679
+ var NO_REGISTRY = {};
1680
+ function useMergedOptions(own) {
1681
+ const provided = (0, import_react4.useContext)(GenuiContext);
1682
+ const registry = own.registry ?? provided?.registry ?? NO_REGISTRY;
1683
+ const catalog = own.catalog ?? provided?.catalog;
1684
+ const resolveComponent = own.resolveComponent ?? provided?.resolveComponent;
1685
+ const treeRenderer = own.treeRenderer ?? provided?.treeRenderer;
1686
+ return (0, import_react4.useMemo)(() => ({
1687
+ registry,
1688
+ ...catalog !== void 0 ? {
1689
+ catalog
1690
+ } : {},
1691
+ ...resolveComponent !== void 0 ? {
1692
+ resolveComponent
1693
+ } : {},
1694
+ ...treeRenderer !== void 0 ? {
1695
+ treeRenderer
1696
+ } : {}
1697
+ }), [
1698
+ registry,
1699
+ catalog,
1700
+ resolveComponent,
1701
+ treeRenderer
1702
+ ]);
1703
+ }
1704
+ __name(useMergedOptions, "useMergedOptions");
1705
+ function GenerativeUI({ part, registry, catalog, resolveComponent, treeRenderer, fallback: ownFallback, loading: ownLoading, onError: ownOnError }) {
1706
+ const provided = (0, import_react4.useContext)(GenuiContext);
1707
+ const fallback2 = ownFallback ?? provided?.fallback;
1708
+ const loading = ownLoading ?? provided?.loading ?? null;
1709
+ const onError = ownOnError ?? provided?.onError;
1710
+ const options = useMergedOptions({
1711
+ ...registry !== void 0 ? {
1712
+ registry
1713
+ } : {},
1714
+ ...catalog !== void 0 ? {
1715
+ catalog
1716
+ } : {},
1717
+ ...resolveComponent !== void 0 ? {
1718
+ resolveComponent
1719
+ } : {},
1720
+ ...treeRenderer !== void 0 ? {
1721
+ treeRenderer
1722
+ } : {}
1723
+ });
1724
+ const state = useGenerativeUIState(part, options, options.treeRenderer ?? GenuiTree);
1725
+ if (state === null) return null;
1726
+ if (state.status === "loading") return loading;
1727
+ if (state.status === "problem") {
1728
+ const { status: _status, ...problem } = state;
1729
+ return renderFallback(fallback2, problem);
1730
+ }
1731
+ const Renderer = state.Component;
1732
+ return /* @__PURE__ */ React.createElement(GenerativeUIScope, {
1733
+ ...options,
1734
+ fallback: fallback2,
1735
+ loading,
1736
+ ...onError !== void 0 ? {
1737
+ onError
1738
+ } : {}
1739
+ }, /* @__PURE__ */ React.createElement(ItemBoundary, {
1740
+ item: state.item,
1741
+ fallback: fallback2,
1742
+ onError
1743
+ }, /* @__PURE__ */ React.createElement(Renderer, state.props)));
1744
+ }
1745
+ __name(GenerativeUI, "GenerativeUI");
1746
+
1747
+ // src/provider.tsx
1748
+ var AgentBackendContext = sharedContext("@dudousxd/nestjs-agent-react:agent-backend");
1749
+ function AgentProvider({ backend, baseUrl, path, headers, getHeaders, credentials, fetch, attachments, genui, children }) {
1750
+ const latestHeaders = (0, import_react5.useRef)({
1751
+ headers,
1752
+ getHeaders
1753
+ });
1754
+ latestHeaders.current = {
1755
+ headers,
1756
+ getHeaders
1757
+ };
1758
+ const upload = attachments?.upload;
1759
+ const value = (0, import_react5.useMemo)(() => backend ?? new AgentClient({
1760
+ ...baseUrl !== void 0 ? {
1761
+ baseUrl
1762
+ } : {},
1763
+ ...path !== void 0 ? {
1764
+ path
1765
+ } : {},
1766
+ ...credentials !== void 0 ? {
1767
+ credentials
1768
+ } : {},
1769
+ ...fetch !== void 0 ? {
1770
+ fetch
1771
+ } : {},
1772
+ ...upload !== void 0 ? {
1773
+ attachments: {
1774
+ upload
1775
+ }
1776
+ } : {},
1777
+ getHeaders: /* @__PURE__ */ __name(async () => {
1778
+ const current = latestHeaders.current;
1779
+ const dynamic = await current.getHeaders?.() ?? {};
1780
+ return {
1781
+ ...current.headers,
1782
+ ...dynamic
1783
+ };
1784
+ }, "getHeaders")
1785
+ }), [
1786
+ backend,
1787
+ baseUrl,
1788
+ path,
1789
+ credentials,
1790
+ fetch,
1791
+ upload
1792
+ ]);
1793
+ const content = genui !== void 0 ? /* @__PURE__ */ React.createElement(GenuiProvider, genui, children) : children;
1794
+ return /* @__PURE__ */ React.createElement(AgentBackendContext.Provider, {
1795
+ value
1796
+ }, content);
1797
+ }
1798
+ __name(AgentProvider, "AgentProvider");
1799
+ var fallback;
1800
+ function defaultBackend() {
1801
+ fallback ??= new AgentClient();
1802
+ return fallback;
1803
+ }
1804
+ __name(defaultBackend, "defaultBackend");
1805
+ function useAgentBackend(own) {
1806
+ const provided = (0, import_react5.useContext)(AgentBackendContext);
1807
+ return own ?? provided ?? defaultBackend();
1808
+ }
1809
+ __name(useAgentBackend, "useAgentBackend");
1810
+
1215
1811
  // src/attachments/use-attachments.ts
1216
1812
  var DEFAULT_REJECTION = {
1217
1813
  type: /* @__PURE__ */ __name((file) => `${file.name} is not a supported file type`, "type"),
@@ -1219,23 +1815,30 @@ var DEFAULT_REJECTION = {
1219
1815
  count: /* @__PURE__ */ __name(() => "Too many files", "count")
1220
1816
  };
1221
1817
  var sequence = 0;
1222
- function useAttachments(options) {
1223
- const latest = (0, import_react2.useRef)(options);
1224
- latest.current = options;
1225
- const [items, setItems] = (0, import_react2.useState)([]);
1226
- const itemsRef = (0, import_react2.useRef)(items);
1818
+ function useAttachments(options = {}) {
1819
+ const backend = useAgentBackend(options.backend);
1820
+ const latest = (0, import_react6.useRef)({
1821
+ ...options,
1822
+ backend
1823
+ });
1824
+ latest.current = {
1825
+ ...options,
1826
+ backend
1827
+ };
1828
+ const [items, setItems] = (0, import_react6.useState)([]);
1829
+ const itemsRef = (0, import_react6.useRef)(items);
1227
1830
  itemsRef.current = items;
1228
- const controllers = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
1229
- const [dragDepth, setDragDepth] = (0, import_react2.useState)(0);
1230
- const patch = (0, import_react2.useCallback)((id, change) => {
1831
+ const controllers = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
1832
+ const [dragDepth, setDragDepth] = (0, import_react6.useState)(0);
1833
+ const patch = (0, import_react6.useCallback)((id, change) => {
1231
1834
  setItems((current) => current.map((item) => item.id === id ? {
1232
1835
  ...item,
1233
1836
  ...change
1234
1837
  } : item));
1235
1838
  }, []);
1236
- const start = (0, import_react2.useCallback)((item) => {
1237
- const { upload, backend } = latest.current;
1238
- const run = upload ?? (backend?.uploadAttachment !== void 0 ? backend.uploadAttachment.bind(backend) : void 0);
1839
+ const start = (0, import_react6.useCallback)((item) => {
1840
+ const { upload, backend: backend2 } = latest.current;
1841
+ const run = upload ?? (backend2.uploadAttachment !== void 0 ? backend2.uploadAttachment.bind(backend2) : void 0);
1239
1842
  if (run === void 0) {
1240
1843
  patch(item.id, {
1241
1844
  status: "error",
@@ -1269,7 +1872,7 @@ function useAttachments(options) {
1269
1872
  }, [
1270
1873
  patch
1271
1874
  ]);
1272
- const add = (0, import_react2.useCallback)((files) => {
1875
+ const add = (0, import_react6.useCallback)((files) => {
1273
1876
  if (files == null) return;
1274
1877
  const { accept: accept2, maxBytes, maxFiles, describeRejection } = latest.current;
1275
1878
  const describe = /* @__PURE__ */ __name((reason, file) => describeRejection?.(reason, file) ?? DEFAULT_REJECTION[reason](file), "describe");
@@ -1315,7 +1918,7 @@ function useAttachments(options) {
1315
1918
  }, [
1316
1919
  start
1317
1920
  ]);
1318
- const release = (0, import_react2.useCallback)((item) => {
1921
+ const release = (0, import_react6.useCallback)((item) => {
1319
1922
  if (item === void 0) return;
1320
1923
  controllers.current.get(item.id)?.abort();
1321
1924
  controllers.current.delete(item.id);
@@ -1323,19 +1926,19 @@ function useAttachments(options) {
1323
1926
  URL.revokeObjectURL(item.previewUrl);
1324
1927
  }
1325
1928
  }, []);
1326
- const remove = (0, import_react2.useCallback)((id) => {
1929
+ const remove = (0, import_react6.useCallback)((id) => {
1327
1930
  release(itemsRef.current.find((item) => item.id === id));
1328
1931
  setItems((current) => current.filter((item) => item.id !== id));
1329
1932
  }, [
1330
1933
  release
1331
1934
  ]);
1332
- const clear = (0, import_react2.useCallback)(() => {
1935
+ const clear = (0, import_react6.useCallback)(() => {
1333
1936
  for (const item of itemsRef.current) release(item);
1334
1937
  setItems([]);
1335
1938
  }, [
1336
1939
  release
1337
1940
  ]);
1338
- const retry = (0, import_react2.useCallback)((id) => {
1941
+ const retry = (0, import_react6.useCallback)((id) => {
1339
1942
  const item = itemsRef.current.find((candidate) => candidate.id === id);
1340
1943
  if (item === void 0 || item.status !== "error") return;
1341
1944
  const { error: _previous, ...rest } = item;
@@ -1349,12 +1952,12 @@ function useAttachments(options) {
1349
1952
  }, [
1350
1953
  start
1351
1954
  ]);
1352
- (0, import_react2.useEffect)(() => () => {
1955
+ (0, import_react6.useEffect)(() => () => {
1353
1956
  for (const item of itemsRef.current) release(item);
1354
1957
  }, [
1355
1958
  release
1356
1959
  ]);
1357
- const onPaste = (0, import_react2.useCallback)((event) => {
1960
+ const onPaste = (0, import_react6.useCallback)((event) => {
1358
1961
  const files = filesFromClipboard(event.clipboardData);
1359
1962
  if (files.length === 0) return;
1360
1963
  event.preventDefault();
@@ -1362,7 +1965,7 @@ function useAttachments(options) {
1362
1965
  }, [
1363
1966
  add
1364
1967
  ]);
1365
- const dropZoneProps = (0, import_react2.useMemo)(() => ({
1968
+ const dropZoneProps = (0, import_react6.useMemo)(() => ({
1366
1969
  onDragEnter: /* @__PURE__ */ __name((event) => {
1367
1970
  if (!dragHasFiles(event.dataTransfer)) return;
1368
1971
  event.preventDefault();
@@ -1385,7 +1988,7 @@ function useAttachments(options) {
1385
1988
  add
1386
1989
  ]);
1387
1990
  const accept = options.accept;
1388
- const inputProps = (0, import_react2.useMemo)(() => ({
1991
+ const inputProps = (0, import_react6.useMemo)(() => ({
1389
1992
  type: "file",
1390
1993
  accept: typeof accept === "string" ? accept : accept?.join(","),
1391
1994
  multiple: options.maxFiles === void 0 || options.maxFiles > 1,
@@ -1399,7 +2002,7 @@ function useAttachments(options) {
1399
2002
  options.maxFiles,
1400
2003
  add
1401
2004
  ]);
1402
- return (0, import_react2.useMemo)(() => {
2005
+ return (0, import_react6.useMemo)(() => {
1403
2006
  const ready = items.filter((item) => item.status === "ready" && item.attachment !== void 0);
1404
2007
  const attachments = ready.map((item) => item.attachment);
1405
2008
  return {
@@ -1433,18 +2036,18 @@ function useAttachments(options) {
1433
2036
  __name(useAttachments, "useAttachments");
1434
2037
 
1435
2038
  // src/catalog/use-agents.ts
1436
- var import_react4 = require("react");
2039
+ var import_react8 = require("react");
1437
2040
 
1438
2041
  // src/catalog/use-resource.ts
1439
- var import_react3 = require("react");
2042
+ var import_react7 = require("react");
1440
2043
  function useResource(load2, key, enabled) {
1441
- const [data, setData] = (0, import_react3.useState)(void 0);
1442
- const [isLoading, setIsLoading] = (0, import_react3.useState)(enabled);
1443
- const [error, setError] = (0, import_react3.useState)(null);
1444
- const loadRef = (0, import_react3.useRef)(load2);
2044
+ const [data, setData] = (0, import_react7.useState)(void 0);
2045
+ const [isLoading, setIsLoading] = (0, import_react7.useState)(enabled);
2046
+ const [error, setError] = (0, import_react7.useState)(null);
2047
+ const loadRef = (0, import_react7.useRef)(load2);
1445
2048
  loadRef.current = load2;
1446
- const generation = (0, import_react3.useRef)(0);
1447
- const refresh = (0, import_react3.useCallback)(async () => {
2049
+ const generation = (0, import_react7.useRef)(0);
2050
+ const refresh = (0, import_react7.useCallback)(async () => {
1448
2051
  const mine = ++generation.current;
1449
2052
  setIsLoading(true);
1450
2053
  try {
@@ -1459,7 +2062,7 @@ function useResource(load2, key, enabled) {
1459
2062
  if (mine === generation.current) setIsLoading(false);
1460
2063
  }
1461
2064
  }, []);
1462
- (0, import_react3.useEffect)(() => {
2065
+ (0, import_react7.useEffect)(() => {
1463
2066
  if (!enabled) return;
1464
2067
  void refresh();
1465
2068
  }, [
@@ -1477,10 +2080,11 @@ function useResource(load2, key, enabled) {
1477
2080
  __name(useResource, "useResource");
1478
2081
 
1479
2082
  // src/catalog/use-agents.ts
1480
- function useAgents(options) {
1481
- const { backend, enabled = true } = options;
2083
+ function useAgents(options = {}) {
2084
+ const { enabled = true } = options;
2085
+ const backend = useAgentBackend(options.backend);
1482
2086
  const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listAgents")(), "", enabled);
1483
- return (0, import_react4.useMemo)(() => {
2087
+ return (0, import_react8.useMemo)(() => {
1484
2088
  const agents = data ?? [];
1485
2089
  return {
1486
2090
  agents,
@@ -1499,11 +2103,12 @@ function useAgents(options) {
1499
2103
  __name(useAgents, "useAgents");
1500
2104
 
1501
2105
  // src/catalog/use-models.ts
1502
- var import_react5 = require("react");
1503
- function useModels(options) {
1504
- const { backend, agent, enabled = true } = options;
2106
+ var import_react9 = require("react");
2107
+ function useModels(options = {}) {
2108
+ const { agent, enabled = true } = options;
2109
+ const backend = useAgentBackend(options.backend);
1505
2110
  const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "listModels")(agent), `${agent ?? ""}`, enabled);
1506
- return (0, import_react5.useMemo)(() => {
2111
+ return (0, import_react9.useMemo)(() => {
1507
2112
  const providers = data?.providers ?? [];
1508
2113
  const models = providers.flatMap((provider) => provider.models.map((model) => ({
1509
2114
  ...model,
@@ -1533,7 +2138,7 @@ function useModels(options) {
1533
2138
  __name(useModels, "useModels");
1534
2139
 
1535
2140
  // src/quota/use-quota.ts
1536
- var import_react6 = require("react");
2141
+ var import_react10 = require("react");
1537
2142
 
1538
2143
  // src/threads/threads-events.ts
1539
2144
  var listeners = /* @__PURE__ */ new WeakMap();
@@ -1557,10 +2162,11 @@ function onThreadsEvent(backend, listener) {
1557
2162
  __name(onThreadsEvent, "onThreadsEvent");
1558
2163
 
1559
2164
  // src/quota/use-quota.ts
1560
- function useQuota(options) {
1561
- const { backend, enabled = true, pollMs } = options;
2165
+ function useQuota(options = {}) {
2166
+ const { enabled = true, pollMs } = options;
2167
+ const backend = useAgentBackend(options.backend);
1562
2168
  const { data, isLoading, error, refresh } = useResource(() => requireBackendMethod(backend, "getQuota")(), "", enabled);
1563
- (0, import_react6.useEffect)(() => {
2169
+ (0, import_react10.useEffect)(() => {
1564
2170
  if (!enabled) return;
1565
2171
  return onThreadsEvent(backend, (event) => {
1566
2172
  if (event.type === "changed") void refresh();
@@ -1570,7 +2176,7 @@ function useQuota(options) {
1570
2176
  enabled,
1571
2177
  refresh
1572
2178
  ]);
1573
- (0, import_react6.useEffect)(() => {
2179
+ (0, import_react10.useEffect)(() => {
1574
2180
  if (!enabled || pollMs === void 0 || pollMs <= 0) return;
1575
2181
  const timer = setInterval(() => void refresh(), pollMs);
1576
2182
  return () => clearInterval(timer);
@@ -1579,7 +2185,7 @@ function useQuota(options) {
1579
2185
  pollMs,
1580
2186
  refresh
1581
2187
  ]);
1582
- return (0, import_react6.useMemo)(() => {
2188
+ return (0, import_react10.useMemo)(() => {
1583
2189
  const windows = data?.windows ?? [];
1584
2190
  return {
1585
2191
  report: data,
@@ -1601,37 +2207,44 @@ function useQuota(options) {
1601
2207
  __name(useQuota, "useQuota");
1602
2208
 
1603
2209
  // src/feedback/use-message-feedback.ts
1604
- var import_react7 = require("react");
1605
- function useMessageFeedback(options) {
1606
- const latest = (0, import_react7.useRef)(options);
1607
- latest.current = options;
1608
- const [local, setLocal] = (0, import_react7.useState)(/* @__PURE__ */ new Map());
1609
- const [pending, setPending] = (0, import_react7.useState)(/* @__PURE__ */ new Set());
1610
- const [error, setError] = (0, import_react7.useState)(null);
1611
- const localRef = (0, import_react7.useRef)(local);
2210
+ var import_react11 = require("react");
2211
+ function useMessageFeedback(options = {}) {
2212
+ const backend = useAgentBackend(options.backend);
2213
+ const latest = (0, import_react11.useRef)({
2214
+ ...options,
2215
+ backend
2216
+ });
2217
+ latest.current = {
2218
+ ...options,
2219
+ backend
2220
+ };
2221
+ const [local, setLocal] = (0, import_react11.useState)(/* @__PURE__ */ new Map());
2222
+ const [pending, setPending] = (0, import_react11.useState)(/* @__PURE__ */ new Set());
2223
+ const [error, setError] = (0, import_react11.useState)(null);
2224
+ const localRef = (0, import_react11.useRef)(local);
1612
2225
  localRef.current = local;
1613
- const resolved = (0, import_react7.useRef)(/* @__PURE__ */ new Map());
1614
- const feedbackOf = (0, import_react7.useCallback)((message) => {
2226
+ const resolved = (0, import_react11.useRef)(/* @__PURE__ */ new Map());
2227
+ const feedbackOf = (0, import_react11.useCallback)((message) => {
1615
2228
  const mine = local.get(message.id);
1616
2229
  if (mine !== void 0) return mine.feedback;
1617
2230
  return metadataOf(message).feedback ?? null;
1618
2231
  }, [
1619
2232
  local
1620
2233
  ]);
1621
- const isPending = (0, import_react7.useCallback)((message) => pending.has(message.id), [
2234
+ const isPending = (0, import_react11.useCallback)((message) => pending.has(message.id), [
1622
2235
  pending
1623
2236
  ]);
1624
- const storedIdFor = (0, import_react7.useCallback)(async (message) => {
2237
+ const storedIdFor = (0, import_react11.useCallback)(async (message) => {
1625
2238
  const runId = metadataOf(message).runId;
1626
2239
  if (runId === void 0) return message.id;
1627
2240
  const known = resolved.current.get(message.id);
1628
2241
  if (known !== void 0) return known;
1629
- const { backend, threadId } = latest.current;
2242
+ const { backend: backend2, threadId } = latest.current;
1630
2243
  const thread = typeof threadId === "function" ? threadId() : threadId;
1631
2244
  if (thread === void 0) {
1632
2245
  throw new Error("useMessageFeedback: a streamed message needs `threadId` to be rated");
1633
2246
  }
1634
- const detail = await backend.getThread(thread);
2247
+ const detail = await backend2.getThread(thread);
1635
2248
  const row = [
1636
2249
  ...detail.messages
1637
2250
  ].reverse().find((candidate) => candidate.role === "assistant" && candidate.runId === runId);
@@ -1641,7 +2254,7 @@ function useMessageFeedback(options) {
1641
2254
  resolved.current.set(message.id, row.id);
1642
2255
  return row.id;
1643
2256
  }, []);
1644
- const rate = (0, import_react7.useCallback)(async (message, value, comment) => {
2257
+ const rate = (0, import_react11.useCallback)(async (message, value, comment) => {
1645
2258
  const setFeedback = requireBackendMethod(latest.current.backend, "setMessageFeedback");
1646
2259
  const had = localRef.current.get(message.id);
1647
2260
  const optimistic = value === null ? null : {
@@ -1687,7 +2300,7 @@ function useMessageFeedback(options) {
1687
2300
  }, [
1688
2301
  storedIdFor
1689
2302
  ]);
1690
- const toggle = (0, import_react7.useCallback)((message, value) => {
2303
+ const toggle = (0, import_react11.useCallback)((message, value) => {
1691
2304
  const mine = localRef.current.get(message.id);
1692
2305
  const current = mine !== void 0 ? mine.feedback : metadataOf(message).feedback ?? null;
1693
2306
  return rate(message, current?.value === value ? null : value);
@@ -1710,16 +2323,17 @@ function metadataOf(message) {
1710
2323
  __name(metadataOf, "metadataOf");
1711
2324
 
1712
2325
  // src/threads/use-threads.ts
1713
- var import_react8 = require("react");
1714
- function useThreads(options) {
1715
- const { backend, enabled = true } = options;
1716
- const [threads, setThreads] = (0, import_react8.useState)([]);
1717
- const [isLoading, setIsLoading] = (0, import_react8.useState)(enabled);
1718
- const [error, setError] = (0, import_react8.useState)(null);
1719
- const threadsRef = (0, import_react8.useRef)(threads);
2326
+ var import_react12 = require("react");
2327
+ function useThreads(options = {}) {
2328
+ const { enabled = true } = options;
2329
+ const backend = useAgentBackend(options.backend);
2330
+ const [threads, setThreads] = (0, import_react12.useState)([]);
2331
+ const [isLoading, setIsLoading] = (0, import_react12.useState)(enabled);
2332
+ const [error, setError] = (0, import_react12.useState)(null);
2333
+ const threadsRef = (0, import_react12.useRef)(threads);
1720
2334
  threadsRef.current = threads;
1721
- const generation = (0, import_react8.useRef)(0);
1722
- const refresh = (0, import_react8.useCallback)(async () => {
2335
+ const generation = (0, import_react12.useRef)(0);
2336
+ const refresh = (0, import_react12.useCallback)(async () => {
1723
2337
  const mine = ++generation.current;
1724
2338
  setIsLoading(true);
1725
2339
  try {
@@ -1736,7 +2350,7 @@ function useThreads(options) {
1736
2350
  }, [
1737
2351
  backend
1738
2352
  ]);
1739
- (0, import_react8.useEffect)(() => {
2353
+ (0, import_react12.useEffect)(() => {
1740
2354
  if (!enabled) return;
1741
2355
  void refresh();
1742
2356
  return onThreadsEvent(backend, (event) => {
@@ -1756,7 +2370,7 @@ function useThreads(options) {
1756
2370
  enabled,
1757
2371
  refresh
1758
2372
  ]);
1759
- const rename = (0, import_react8.useCallback)(async (id, title) => {
2373
+ const rename = (0, import_react12.useCallback)(async (id, title) => {
1760
2374
  const before = threadsRef.current;
1761
2375
  setThreads((current) => current.map((thread) => thread.id === id ? {
1762
2376
  ...thread,
@@ -1778,7 +2392,7 @@ function useThreads(options) {
1778
2392
  }, [
1779
2393
  backend
1780
2394
  ]);
1781
- const remove = (0, import_react8.useCallback)(async (id) => {
2395
+ const remove = (0, import_react12.useCallback)(async (id) => {
1782
2396
  const before = threadsRef.current;
1783
2397
  setThreads((current) => current.filter((thread) => thread.id !== id));
1784
2398
  try {
@@ -1852,29 +2466,11 @@ function backgroundRunsFromThread(messages) {
1852
2466
  }
1853
2467
  __name(backgroundRunsFromThread, "backgroundRunsFromThread");
1854
2468
 
1855
- // src/components/ambient-ui.ts
1856
- var import_react9 = require("react");
1857
- function sharedContext(key) {
1858
- const symbol = Symbol.for(key);
1859
- const holder = globalThis;
1860
- const existing = holder[symbol];
1861
- if (existing !== void 0) return existing;
1862
- const created = (0, import_react9.createContext)(null);
1863
- holder[symbol] = created;
1864
- return created;
1865
- }
1866
- __name(sharedContext, "sharedContext");
1867
- var AmbientRenderUiContext = sharedContext("@dudousxd/nestjs-agent-react:ambient-render-ui");
1868
- function useAmbientRenderUi() {
1869
- return (0, import_react9.useContext)(AmbientRenderUiContext);
1870
- }
1871
- __name(useAmbientRenderUi, "useAmbientRenderUi");
1872
-
1873
2469
  // src/components/chat-input.tsx
1874
- var import_react11 = __toESM(require("react"), 1);
2470
+ var import_react14 = __toESM(require("react"), 1);
1875
2471
 
1876
2472
  // src/components/use-speech-recognition.ts
1877
- var import_react10 = require("react");
2473
+ var import_react13 = require("react");
1878
2474
  function getRecognitionCtor() {
1879
2475
  if (typeof window === "undefined") return null;
1880
2476
  const scope = window;
@@ -1882,15 +2478,15 @@ function getRecognitionCtor() {
1882
2478
  }
1883
2479
  __name(getRecognitionCtor, "getRecognitionCtor");
1884
2480
  function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
1885
- const recognitionRef = (0, import_react10.useRef)(null);
1886
- const [isListening, setIsListening] = (0, import_react10.useState)(false);
1887
- const ctor = (0, import_react10.useMemo)(() => getRecognitionCtor(), []);
2481
+ const recognitionRef = (0, import_react13.useRef)(null);
2482
+ const [isListening, setIsListening] = (0, import_react13.useState)(false);
2483
+ const ctor = (0, import_react13.useMemo)(() => getRecognitionCtor(), []);
1888
2484
  const isSupported = ctor !== null;
1889
- const finalRef = (0, import_react10.useRef)(onFinalTranscript);
1890
- const interimRef = (0, import_react10.useRef)(onInterimTranscript);
2485
+ const finalRef = (0, import_react13.useRef)(onFinalTranscript);
2486
+ const interimRef = (0, import_react13.useRef)(onInterimTranscript);
1891
2487
  finalRef.current = onFinalTranscript;
1892
2488
  interimRef.current = onInterimTranscript;
1893
- (0, import_react10.useEffect)(() => {
2489
+ (0, import_react13.useEffect)(() => {
1894
2490
  if (!ctor) return;
1895
2491
  const recognition = new ctor();
1896
2492
  recognition.lang = lang;
@@ -1929,7 +2525,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
1929
2525
  ctor,
1930
2526
  lang
1931
2527
  ]);
1932
- const start = (0, import_react10.useCallback)(() => {
2528
+ const start = (0, import_react13.useCallback)(() => {
1933
2529
  const recognition = recognitionRef.current;
1934
2530
  if (!recognition) return;
1935
2531
  try {
@@ -1939,7 +2535,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
1939
2535
  console.warn("SpeechRecognition start failed", error);
1940
2536
  }
1941
2537
  }, []);
1942
- const stop = (0, import_react10.useCallback)(() => {
2538
+ const stop = (0, import_react13.useCallback)(() => {
1943
2539
  const recognition = recognitionRef.current;
1944
2540
  if (!recognition) return;
1945
2541
  try {
@@ -1958,8 +2554,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
1958
2554
 
1959
2555
  // src/components/chat-input.tsx
1960
2556
  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 }) {
1961
- const [value, setValue] = (0, import_react11.useState)("");
1962
- const [interim, setInterim] = (0, import_react11.useState)("");
2557
+ const [value, setValue] = (0, import_react14.useState)("");
2558
+ const [interim, setInterim] = (0, import_react14.useState)("");
1963
2559
  const speech = useSpeechRecognition({
1964
2560
  lang: speechLang,
1965
2561
  onFinalTranscript: /* @__PURE__ */ __name((text) => {
@@ -1970,7 +2566,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
1970
2566
  }, "onFinalTranscript"),
1971
2567
  onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
1972
2568
  });
1973
- (0, import_react11.useEffect)(() => {
2569
+ (0, import_react14.useEffect)(() => {
1974
2570
  if (!speech.isListening) setInterim("");
1975
2571
  }, [
1976
2572
  speech.isListening
@@ -1998,9 +2594,9 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
1998
2594
  const displayValue = speech.isListening && interim ? `${value}${value && !value.endsWith(" ") ? " " : ""}${interim}` : value;
1999
2595
  const showMic = enableSpeech && speech.isSupported;
2000
2596
  const showStop = isStreaming && onStop !== void 0;
2001
- return /* @__PURE__ */ import_react11.default.createElement("div", {
2597
+ return /* @__PURE__ */ import_react14.default.createElement("div", {
2002
2598
  className
2003
- }, /* @__PURE__ */ import_react11.default.createElement("textarea", {
2599
+ }, /* @__PURE__ */ import_react14.default.createElement("textarea", {
2004
2600
  className: textareaClassName,
2005
2601
  rows,
2006
2602
  value: displayValue,
@@ -2011,17 +2607,17 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
2011
2607
  }, "onChange"),
2012
2608
  onKeyDown: handleKeyDown,
2013
2609
  placeholder: placeholder ?? "Ask something (Enter to send, Shift+Enter for newline)"
2014
- }), /* @__PURE__ */ import_react11.default.createElement("button", {
2610
+ }), /* @__PURE__ */ import_react14.default.createElement("button", {
2015
2611
  type: "button",
2016
2612
  className: sendButtonClassName,
2017
2613
  onClick: submit,
2018
2614
  disabled: disabled || !value.trim()
2019
- }, sendLabel), showStop ? /* @__PURE__ */ import_react11.default.createElement("button", {
2615
+ }, sendLabel), showStop ? /* @__PURE__ */ import_react14.default.createElement("button", {
2020
2616
  type: "button",
2021
2617
  className: stopButtonClassName,
2022
2618
  onClick: /* @__PURE__ */ __name(() => void onStop(), "onClick"),
2023
2619
  "aria-label": "Stop generating"
2024
- }, stopLabel) : null, showMic ? /* @__PURE__ */ import_react11.default.createElement("button", {
2620
+ }, stopLabel) : null, showMic ? /* @__PURE__ */ import_react14.default.createElement("button", {
2025
2621
  type: "button",
2026
2622
  className: micButtonClassName,
2027
2623
  onClick: toggleMic,
@@ -2034,10 +2630,10 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
2034
2630
  __name(ChatInput, "ChatInput");
2035
2631
 
2036
2632
  // src/components/message-item.tsx
2037
- var import_react14 = __toESM(require("react"), 1);
2633
+ var import_react17 = __toESM(require("react"), 1);
2038
2634
 
2039
2635
  // src/transcript/use-chat-transcript.ts
2040
- var import_react13 = require("react");
2636
+ var import_react16 = require("react");
2041
2637
 
2042
2638
  // src/transcript/model.ts
2043
2639
  var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
@@ -2134,21 +2730,21 @@ function fillTemplate(template, context) {
2134
2730
  }).replace(/\s{2,}/g, " ").trim();
2135
2731
  }
2136
2732
  __name(fillTemplate, "fillTemplate");
2137
- function phraseFor(presentation, input, isSettled2, fallback = {
2733
+ function phraseFor(presentation, input, isSettled2, fallback2 = {
2138
2734
  running: "Working",
2139
2735
  done: "Done"
2140
2736
  }) {
2141
- if (presentation === void 0) return isSettled2 ? fallback.done : fallback.running;
2737
+ if (presentation === void 0) return isSettled2 ? fallback2.done : fallback2.running;
2142
2738
  const filled = fillTemplate(isSettled2 ? presentation.done : presentation.running, input);
2143
2739
  return filled === "" ? presentation.label : filled;
2144
2740
  }
2145
2741
  __name(phraseFor, "phraseFor");
2146
2742
 
2147
2743
  // src/presentation/result-view.ts
2148
- function isRecord(value) {
2744
+ function isRecord2(value) {
2149
2745
  return typeof value === "object" && value !== null && !Array.isArray(value);
2150
2746
  }
2151
- __name(isRecord, "isRecord");
2747
+ __name(isRecord2, "isRecord");
2152
2748
  function toText(value) {
2153
2749
  if (value === null || value === void 0) return "\u2014";
2154
2750
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
@@ -2159,7 +2755,7 @@ function toText(value) {
2159
2755
  }
2160
2756
  __name(toText, "toText");
2161
2757
  function inferResultView(output) {
2162
- if (!isRecord(output)) return void 0;
2758
+ if (!isRecord2(output)) return void 0;
2163
2759
  for (const [key, value] of Object.entries(output)) {
2164
2760
  if (!Array.isArray(value) || value.length === 0) continue;
2165
2761
  if (value.every((entry) => typeof entry === "string")) {
@@ -2168,12 +2764,12 @@ function inferResultView(output) {
2168
2764
  lines: key
2169
2765
  };
2170
2766
  }
2171
- if (value.every(isRecord)) {
2767
+ if (value.every(isRecord2)) {
2172
2768
  const first = value[0];
2173
2769
  return {
2174
2770
  kind: "table",
2175
2771
  rows: key,
2176
- columns: Object.keys(first).filter((column) => !isRecord(first[column])).map((column) => ({
2772
+ columns: Object.keys(first).filter((column) => !isRecord2(first[column])).map((column) => ({
2177
2773
  path: column,
2178
2774
  label: column
2179
2775
  }))
@@ -2549,7 +3145,7 @@ function isSettled(state) {
2549
3145
  __name(isSettled, "isSettled");
2550
3146
  function toolKind(part) {
2551
3147
  const metadata = part.toolMetadata;
2552
- return isRecord2(metadata) && typeof metadata.toolKind === "string" ? metadata.toolKind : void 0;
3148
+ return isRecord3(metadata) && typeof metadata.toolKind === "string" ? metadata.toolKind : void 0;
2553
3149
  }
2554
3150
  __name(toolKind, "toolKind");
2555
3151
  function isAwaitingApproval(part) {
@@ -2564,7 +3160,7 @@ function isAwaitingApproval(part) {
2564
3160
  __name(isAwaitingApproval, "isAwaitingApproval");
2565
3161
  function toolParentId(part) {
2566
3162
  const metadata = part.toolMetadata;
2567
- return isRecord2(metadata) && typeof metadata.parentId === "string" ? metadata.parentId : null;
3163
+ return isRecord3(metadata) && typeof metadata.parentId === "string" ? metadata.parentId : null;
2568
3164
  }
2569
3165
  __name(toolParentId, "toolParentId");
2570
3166
  function nestToolCalls(calls) {
@@ -2631,12 +3227,12 @@ function buildToolCall(part, options, approval, catalog) {
2631
3227
  __name(buildToolCall, "buildToolCall");
2632
3228
  function readElicitationRequest(part) {
2633
3229
  const input = part.input;
2634
- if (!isRecord2(input) || !Array.isArray(input.questions) || input.questions.length === 0) {
3230
+ if (!isRecord3(input) || !Array.isArray(input.questions) || input.questions.length === 0) {
2635
3231
  return null;
2636
3232
  }
2637
3233
  const questions = [];
2638
3234
  for (const candidate of input.questions) {
2639
- if (!isRecord2(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string") {
3235
+ if (!isRecord3(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string") {
2640
3236
  return null;
2641
3237
  }
2642
3238
  const input2 = (0, import_nestjs_agent_core2.readElicitationInput)(candidate.input) ?? null;
@@ -2646,7 +3242,7 @@ function readElicitationRequest(part) {
2646
3242
  }
2647
3243
  const options = [];
2648
3244
  for (const option of rawOptions) {
2649
- if (!isRecord2(option) || typeof option.value !== "string" || typeof option.label !== "string") {
3245
+ if (!isRecord3(option) || typeof option.value !== "string" || typeof option.label !== "string") {
2650
3246
  return null;
2651
3247
  }
2652
3248
  options.push({
@@ -2674,7 +3270,7 @@ function readElicitationRequest(part) {
2674
3270
  __name(readElicitationRequest, "readElicitationRequest");
2675
3271
  function readElicitationOutcome(part) {
2676
3272
  const output = part.output;
2677
- if (!isRecord2(output) || !isRecord2(output.answers) || typeof output.skipped !== "boolean") {
3273
+ if (!isRecord3(output) || !isRecord3(output.answers) || typeof output.skipped !== "boolean") {
2678
3274
  return null;
2679
3275
  }
2680
3276
  const answers = {};
@@ -2811,7 +3407,7 @@ function readApprovals(parts) {
2811
3407
  continue;
2812
3408
  }
2813
3409
  const data = part.data;
2814
- if (!isRecord2(data) || typeof data.id !== "string") {
3410
+ if (!isRecord3(data) || typeof data.id !== "string") {
2815
3411
  continue;
2816
3412
  }
2817
3413
  const approval = entry(data.id);
@@ -2867,7 +3463,7 @@ function statusFromPart(call) {
2867
3463
  __name(statusFromPart, "statusFromPart");
2868
3464
  function readUiComponent(part) {
2869
3465
  const data = part.data;
2870
- if (!isRecord2(data) || typeof data.component !== "string") {
3466
+ if (!isRecord3(data) || typeof data.component !== "string") {
2871
3467
  return null;
2872
3468
  }
2873
3469
  const id = typeof data.id === "string" ? data.id : part.id;
@@ -2877,19 +3473,19 @@ function readUiComponent(part) {
2877
3473
  return {
2878
3474
  id,
2879
3475
  component: data.component,
2880
- props: isRecord2(data.props) ? data.props : {},
3476
+ props: isRecord3(data.props) ? data.props : {},
2881
3477
  version: typeof data.version === "number" ? data.version : null,
2882
3478
  toolCallId: typeof data.toolCallId === "string" ? data.toolCallId : null
2883
3479
  };
2884
3480
  }
2885
3481
  __name(readUiComponent, "readUiComponent");
2886
- function isRecord2(value) {
3482
+ function isRecord3(value) {
2887
3483
  return typeof value === "object" && value !== null;
2888
3484
  }
2889
- __name(isRecord2, "isRecord");
3485
+ __name(isRecord3, "isRecord");
2890
3486
  function readQuery(part) {
2891
3487
  const input = part.input;
2892
- if (!isRecord2(input) || typeof input.query !== "string") {
3488
+ if (!isRecord3(input) || typeof input.query !== "string") {
2893
3489
  return null;
2894
3490
  }
2895
3491
  return input.query;
@@ -2897,12 +3493,12 @@ function readQuery(part) {
2897
3493
  __name(readQuery, "readQuery");
2898
3494
  function readPassages(part) {
2899
3495
  const output = part.output;
2900
- if (!isRecord2(output) || !Array.isArray(output.passages) || output.passages.length === 0) {
3496
+ if (!isRecord3(output) || !Array.isArray(output.passages) || output.passages.length === 0) {
2901
3497
  return null;
2902
3498
  }
2903
3499
  const passages = [];
2904
3500
  for (const candidate of output.passages) {
2905
- if (!isRecord2(candidate) || typeof candidate.id !== "string" || typeof candidate.text !== "string") {
3501
+ if (!isRecord3(candidate) || typeof candidate.id !== "string" || typeof candidate.text !== "string") {
2906
3502
  return null;
2907
3503
  }
2908
3504
  passages.push({
@@ -2912,7 +3508,7 @@ function readPassages(part) {
2912
3508
  ...typeof candidate.source === "string" ? {
2913
3509
  source: candidate.source
2914
3510
  } : {},
2915
- ...isRecord2(candidate.metadata) ? {
3511
+ ...isRecord3(candidate.metadata) ? {
2916
3512
  metadata: candidate.metadata
2917
3513
  } : {}
2918
3514
  });
@@ -3014,11 +3610,11 @@ function formatCostUsd(cost) {
3014
3610
  __name(formatCostUsd, "formatCostUsd");
3015
3611
 
3016
3612
  // src/transcript/use-stick-to-bottom.ts
3017
- var import_react12 = require("react");
3613
+ var import_react15 = require("react");
3018
3614
  function useStickToBottom({ contentKey, threshold = 32 }) {
3019
- const containerRef = (0, import_react12.useRef)(null);
3020
- const [isAtBottom, setIsAtBottom] = (0, import_react12.useState)(true);
3021
- const measure = (0, import_react12.useCallback)(() => {
3615
+ const containerRef = (0, import_react15.useRef)(null);
3616
+ const [isAtBottom, setIsAtBottom] = (0, import_react15.useState)(true);
3617
+ const measure = (0, import_react15.useCallback)(() => {
3022
3618
  const element = containerRef.current;
3023
3619
  if (!element) {
3024
3620
  return;
@@ -3028,7 +3624,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
3028
3624
  }, [
3029
3625
  threshold
3030
3626
  ]);
3031
- const scrollToBottom = (0, import_react12.useCallback)(() => {
3627
+ const scrollToBottom = (0, import_react15.useCallback)(() => {
3032
3628
  const element = containerRef.current;
3033
3629
  if (!element) {
3034
3630
  return;
@@ -3036,7 +3632,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
3036
3632
  element.scrollTop = element.scrollHeight;
3037
3633
  setIsAtBottom(true);
3038
3634
  }, []);
3039
- const setContainer = (0, import_react12.useCallback)((element) => {
3635
+ const setContainer = (0, import_react15.useCallback)((element) => {
3040
3636
  containerRef.current = element;
3041
3637
  if (element) {
3042
3638
  measure();
@@ -3044,7 +3640,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
3044
3640
  }, [
3045
3641
  measure
3046
3642
  ]);
3047
- (0, import_react12.useEffect)(() => {
3643
+ (0, import_react15.useEffect)(() => {
3048
3644
  if (isAtBottom) {
3049
3645
  scrollToBottom();
3050
3646
  }
@@ -3053,7 +3649,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
3053
3649
  isAtBottom,
3054
3650
  scrollToBottom
3055
3651
  ]);
3056
- const getContainerProps = (0, import_react12.useCallback)(() => ({
3652
+ const getContainerProps = (0, import_react15.useCallback)(() => ({
3057
3653
  ref: setContainer,
3058
3654
  onScroll: measure
3059
3655
  }), [
@@ -3075,14 +3671,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
3075
3671
  var DEFAULT_COPY_RESET_MS = 1500;
3076
3672
  function useChatTranscript(options) {
3077
3673
  const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
3078
- const latest = (0, import_react13.useRef)(options);
3674
+ const latest = (0, import_react16.useRef)(options);
3079
3675
  latest.current = options;
3080
- const [visibleCount, setVisibleCount] = (0, import_react13.useState)(initialVisibleCount);
3081
- const [stopRequested, setStopRequested] = (0, import_react13.useState)(false);
3676
+ const [visibleCount, setVisibleCount] = (0, import_react16.useState)(initialVisibleCount);
3677
+ const [stopRequested, setStopRequested] = (0, import_react16.useState)(false);
3082
3678
  const isStreaming = status === "streaming" || status === "reconnecting";
3083
3679
  const isBusy = status === "submitted" || isStreaming;
3084
3680
  const isEmpty = messages.length === 0;
3085
- (0, import_react13.useEffect)(() => {
3681
+ (0, import_react16.useEffect)(() => {
3086
3682
  if (!isBusy) {
3087
3683
  setStopRequested(false);
3088
3684
  }
@@ -3099,7 +3695,7 @@ function useChatTranscript(options) {
3099
3695
  streamingMessageId,
3100
3696
  options
3101
3697
  });
3102
- const stop = (0, import_react13.useCallback)(() => {
3698
+ const stop = (0, import_react16.useCallback)(() => {
3103
3699
  const current = latest.current;
3104
3700
  if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
3105
3701
  return;
@@ -3107,8 +3703,8 @@ function useChatTranscript(options) {
3107
3703
  setStopRequested(true);
3108
3704
  void current.onStop?.();
3109
3705
  }, []);
3110
- const loadEarlier = (0, import_react13.useCallback)(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
3111
- const showAll = (0, import_react13.useCallback)(() => setVisibleCount(latest.current.messages.length), []);
3706
+ const loadEarlier = (0, import_react16.useCallback)(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
3707
+ const showAll = (0, import_react16.useCallback)(() => setVisibleCount(latest.current.messages.length), []);
3112
3708
  const scroll = useStickToBottom({
3113
3709
  contentKey: contentSignature(messages),
3114
3710
  ...stickToBottomThreshold !== void 0 ? {
@@ -3144,7 +3740,7 @@ function useChatTranscript(options) {
3144
3740
  __name(useChatTranscript, "useChatTranscript");
3145
3741
  function useTranscriptItem(options) {
3146
3742
  const { message, isStreaming = false } = options;
3147
- const messagesRef = (0, import_react13.useRef)([
3743
+ const messagesRef = (0, import_react16.useRef)([
3148
3744
  message
3149
3745
  ]);
3150
3746
  if (messagesRef.current[0] !== message) {
@@ -3162,13 +3758,13 @@ function useTranscriptItem(options) {
3162
3758
  }
3163
3759
  __name(useTranscriptItem, "useTranscriptItem");
3164
3760
  function useTranscriptItems({ messages, visibleStart, streamingMessageId, options }) {
3165
- const [drafts, setDrafts] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
3166
- const [copied, setCopied] = (0, import_react13.useState)(() => /* @__PURE__ */ new Set());
3167
- const [openReasoning, setOpenReasoning] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
3168
- const [picks, setPicks] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
3169
- const [settling, setSettling] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
3170
- const [settleErrors, setSettleErrors] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
3171
- const latest = (0, import_react13.useRef)({
3761
+ const [drafts, setDrafts] = (0, import_react16.useState)(() => /* @__PURE__ */ new Map());
3762
+ const [copied, setCopied] = (0, import_react16.useState)(() => /* @__PURE__ */ new Set());
3763
+ const [openReasoning, setOpenReasoning] = (0, import_react16.useState)(() => /* @__PURE__ */ new Map());
3764
+ const [picks, setPicks] = (0, import_react16.useState)(() => /* @__PURE__ */ new Map());
3765
+ const [settling, setSettling] = (0, import_react16.useState)(() => /* @__PURE__ */ new Map());
3766
+ const [settleErrors, setSettleErrors] = (0, import_react16.useState)(() => /* @__PURE__ */ new Map());
3767
+ const latest = (0, import_react16.useRef)({
3172
3768
  options,
3173
3769
  drafts,
3174
3770
  picks,
@@ -3180,23 +3776,23 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3180
3776
  picks,
3181
3777
  messages
3182
3778
  };
3183
- const copyTimers = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
3184
- (0, import_react13.useEffect)(() => () => {
3779
+ const copyTimers = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
3780
+ (0, import_react16.useEffect)(() => () => {
3185
3781
  for (const timer of copyTimers.current.values()) {
3186
3782
  clearTimeout(timer);
3187
3783
  }
3188
3784
  copyTimers.current.clear();
3189
3785
  }, []);
3190
- const callbackCache = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
3191
- const reasoningToggleCache = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
3192
- const toggleReasoning = (0, import_react13.useCallback)((key, open) => {
3786
+ const callbackCache = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
3787
+ const reasoningToggleCache = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
3788
+ const toggleReasoning = (0, import_react16.useCallback)((key, open) => {
3193
3789
  setOpenReasoning((current) => {
3194
3790
  const next = new Map(current);
3195
3791
  next.set(key, open ?? !(current.get(key) ?? false));
3196
3792
  return next;
3197
3793
  });
3198
3794
  }, []);
3199
- const stableToggle = (0, import_react13.useCallback)((key) => {
3795
+ const stableToggle = (0, import_react16.useCallback)((key) => {
3200
3796
  let cached = reasoningToggleCache.current.get(key);
3201
3797
  if (!cached) {
3202
3798
  cached = /* @__PURE__ */ __name((open) => toggleReasoning(key, open), "cached");
@@ -3206,10 +3802,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3206
3802
  }, [
3207
3803
  toggleReasoning
3208
3804
  ]);
3209
- const pick = (0, import_react13.useCallback)((toolCallId, questionId, values) => {
3805
+ const pick = (0, import_react16.useCallback)((toolCallId, questionId, values) => {
3210
3806
  setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
3211
3807
  }, []);
3212
- const settle = (0, import_react13.useCallback)((toolCallId, action, send) => {
3808
+ const settle = (0, import_react16.useCallback)((toolCallId, action, send) => {
3213
3809
  setSettleErrors((current) => {
3214
3810
  if (!current.has(toolCallId)) {
3215
3811
  return current;
@@ -3233,7 +3829,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3233
3829
  failed(error);
3234
3830
  }
3235
3831
  }, []);
3236
- const answer = (0, import_react13.useCallback)((toolCallId) => {
3832
+ const answer = (0, import_react16.useCallback)((toolCallId) => {
3237
3833
  const current = latest.current;
3238
3834
  const onAnswer = current.options.onAnswer;
3239
3835
  if (!onAnswer) {
@@ -3243,7 +3839,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3243
3839
  }, [
3244
3840
  settle
3245
3841
  ]);
3246
- const skip = (0, import_react13.useCallback)((toolCallId) => {
3842
+ const skip = (0, import_react16.useCallback)((toolCallId) => {
3247
3843
  const onSkip = latest.current.options.onSkip;
3248
3844
  if (onSkip) {
3249
3845
  settle(toolCallId, "skip", () => onSkip(toolCallId));
@@ -3251,7 +3847,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3251
3847
  }, [
3252
3848
  settle
3253
3849
  ]);
3254
- const approve = (0, import_react13.useCallback)((toolCallId, options2) => {
3850
+ const approve = (0, import_react16.useCallback)((toolCallId, options2) => {
3255
3851
  const onApprove = latest.current.options.onApprove;
3256
3852
  if (onApprove) {
3257
3853
  settle(toolCallId, "approve", () => options2 === void 0 ? onApprove(toolCallId) : onApprove(toolCallId, options2));
@@ -3259,7 +3855,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3259
3855
  }, [
3260
3856
  settle
3261
3857
  ]);
3262
- const reject = (0, import_react13.useCallback)((toolCallId) => {
3858
+ const reject = (0, import_react16.useCallback)((toolCallId) => {
3263
3859
  const onReject = latest.current.options.onReject;
3264
3860
  if (onReject) {
3265
3861
  settle(toolCallId, "reject", () => onReject(toolCallId));
@@ -3267,7 +3863,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3267
3863
  }, [
3268
3864
  settle
3269
3865
  ]);
3270
- const callbacksFor = (0, import_react13.useCallback)((id) => {
3866
+ const callbacksFor = (0, import_react16.useCallback)((id) => {
3271
3867
  const cached = callbackCache.current.get(id);
3272
3868
  if (cached) {
3273
3869
  return cached;
@@ -3509,7 +4105,7 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
3509
4105
  getCreatedAt: /* @__PURE__ */ __name(() => createdAt, "getCreatedAt")
3510
4106
  } : {}
3511
4107
  });
3512
- return /* @__PURE__ */ import_react14.default.createElement(MessageItemView, {
4108
+ return /* @__PURE__ */ import_react17.default.createElement(MessageItemView, {
3513
4109
  item,
3514
4110
  ...slots
3515
4111
  });
@@ -3522,51 +4118,51 @@ function MessageItemView({ item, ...given }) {
3522
4118
  renderUi: ambientRenderUi
3523
4119
  } : given;
3524
4120
  const { classNames } = slots;
3525
- const actionRow = /* @__PURE__ */ import_react14.default.createElement("div", {
4121
+ const actionRow = /* @__PURE__ */ import_react17.default.createElement("div", {
3526
4122
  className: classNames?.actions,
3527
4123
  "data-actions-for": item.role
3528
- }, item.copy.available ? /* @__PURE__ */ import_react14.default.createElement("button", {
4124
+ }, item.copy.available ? /* @__PURE__ */ import_react17.default.createElement("button", {
3529
4125
  type: "button",
3530
4126
  onClick: item.copy.copy,
3531
4127
  className: classNames?.actionButton,
3532
4128
  title: item.copy.copied ? "Copied!" : "Copy message text"
3533
- }, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */ import_react14.default.createElement("button", {
4129
+ }, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */ import_react17.default.createElement("button", {
3534
4130
  type: "button",
3535
4131
  onClick: item.fork.run,
3536
4132
  className: classNames?.actionButton,
3537
4133
  title: "Fork thread from this message"
3538
- }, "Fork") : null, item.regenerate.available ? /* @__PURE__ */ import_react14.default.createElement("button", {
4134
+ }, "Fork") : null, item.regenerate.available ? /* @__PURE__ */ import_react17.default.createElement("button", {
3539
4135
  type: "button",
3540
4136
  onClick: item.regenerate.run,
3541
4137
  className: classNames?.actionButton,
3542
4138
  title: "Regenerate response"
3543
- }, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */ import_react14.default.createElement("span", {
4139
+ }, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */ import_react17.default.createElement("span", {
3544
4140
  className: classNames?.usage,
3545
4141
  title: `Input ${item.usage.inputTokens.toLocaleString()} \xB7 Output ${item.usage.outputTokens.toLocaleString()} tokens`
3546
- }, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */ import_react14.default.createElement("span", {
4142
+ }, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */ import_react17.default.createElement("span", {
3547
4143
  className: classNames?.timestamp,
3548
4144
  title: item.timestamp.absolute
3549
4145
  }, item.timestamp.relative) : null);
3550
4146
  if (item.edit.available) {
3551
- return /* @__PURE__ */ import_react14.default.createElement(EditableUserBubble, {
4147
+ return /* @__PURE__ */ import_react17.default.createElement(EditableUserBubble, {
3552
4148
  item,
3553
4149
  slots,
3554
4150
  actions: actionRow
3555
4151
  });
3556
4152
  }
3557
4153
  const className = joinClasses(classNames?.root, classNames?.byRole?.[item.role]);
3558
- return /* @__PURE__ */ import_react14.default.createElement("div", {
4154
+ return /* @__PURE__ */ import_react17.default.createElement("div", {
3559
4155
  className,
3560
4156
  "data-role": item.role,
3561
4157
  "data-streaming": item.isStreaming ? "true" : void 0
3562
- }, /* @__PURE__ */ import_react14.default.createElement("div", null, renderBlocks(item, slots)), actionRow);
4158
+ }, /* @__PURE__ */ import_react17.default.createElement("div", null, renderBlocks(item, slots)), actionRow);
3563
4159
  }
3564
4160
  __name(MessageItemView, "MessageItemView");
3565
4161
  function renderBlocks(item, slots) {
3566
4162
  const nodes = [];
3567
4163
  for (const block of item.blocks) {
3568
4164
  if (block.kind === "text") {
3569
- nodes.push(/* @__PURE__ */ import_react14.default.createElement("div", {
4165
+ nodes.push(/* @__PURE__ */ import_react17.default.createElement("div", {
3570
4166
  key: block.key,
3571
4167
  className: slots.classNames?.text
3572
4168
  }, slots.renderText ? slots.renderText(block.text, {
@@ -3587,7 +4183,7 @@ function renderBlocks(item, slots) {
3587
4183
  continue;
3588
4184
  }
3589
4185
  if (block.kind === "ui" && slots.renderUi) {
3590
- nodes.push(/* @__PURE__ */ import_react14.default.createElement("div", {
4186
+ nodes.push(/* @__PURE__ */ import_react17.default.createElement("div", {
3591
4187
  key: block.key,
3592
4188
  "data-slot": "ui",
3593
4189
  "data-component": block.component
@@ -3598,18 +4194,18 @@ function renderBlocks(item, slots) {
3598
4194
  }
3599
4195
  __name(renderBlocks, "renderBlocks");
3600
4196
  function renderFilesBlock(block, slots) {
3601
- return /* @__PURE__ */ import_react14.default.createElement("div", {
4197
+ return /* @__PURE__ */ import_react17.default.createElement("div", {
3602
4198
  key: block.key,
3603
4199
  className: slots.classNames?.files,
3604
4200
  "data-files": "true"
3605
- }, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */ import_react14.default.createElement("a", {
4201
+ }, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */ import_react17.default.createElement("a", {
3606
4202
  key: file.url,
3607
4203
  href: file.url,
3608
4204
  target: "_blank",
3609
4205
  rel: "noreferrer",
3610
4206
  className: slots.classNames?.file,
3611
4207
  title: file.filename ?? file.mediaType
3612
- }, file.isImage ? /* @__PURE__ */ import_react14.default.createElement("img", {
4208
+ }, file.isImage ? /* @__PURE__ */ import_react17.default.createElement("img", {
3613
4209
  src: file.url,
3614
4210
  alt: file.filename ?? "image",
3615
4211
  className: slots.classNames?.fileImage
@@ -3617,17 +4213,17 @@ function renderFilesBlock(block, slots) {
3617
4213
  }
3618
4214
  __name(renderFilesBlock, "renderFilesBlock");
3619
4215
  function renderReasoningBlock(block, slots) {
3620
- return /* @__PURE__ */ import_react14.default.createElement("div", {
4216
+ return /* @__PURE__ */ import_react17.default.createElement("div", {
3621
4217
  key: block.key,
3622
4218
  className: slots.classNames?.reasoning,
3623
4219
  "data-reasoning": "true",
3624
4220
  "data-streaming": block.isStreaming ? "true" : void 0
3625
- }, /* @__PURE__ */ import_react14.default.createElement("button", {
4221
+ }, /* @__PURE__ */ import_react17.default.createElement("button", {
3626
4222
  type: "button",
3627
4223
  className: slots.classNames?.reasoningToggle,
3628
4224
  onClick: /* @__PURE__ */ __name(() => block.toggle(), "onClick"),
3629
4225
  "aria-expanded": block.isOpen
3630
- }, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */ import_react14.default.createElement("div", {
4226
+ }, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */ import_react17.default.createElement("div", {
3631
4227
  className: slots.classNames?.reasoningText
3632
4228
  }, slots.renderReasoning ? slots.renderReasoning(block.text, {
3633
4229
  isStreaming: block.isStreaming,
@@ -3638,7 +4234,7 @@ __name(renderReasoningBlock, "renderReasoningBlock");
3638
4234
  function renderToolBlock(item, block, slots) {
3639
4235
  if (slots.renderToolGroup) {
3640
4236
  return [
3641
- /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, {
4237
+ /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, {
3642
4238
  key: block.key
3643
4239
  }, slots.renderToolGroup(block.parts, block.key))
3644
4240
  ];
@@ -3649,7 +4245,7 @@ function renderToolBlock(item, block, slots) {
3649
4245
  const renderToolPart = slots.renderToolPart;
3650
4246
  return block.parts.map((part) => {
3651
4247
  const partKey = `${item.id}-${part.toolCallId}`;
3652
- return /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, {
4248
+ return /* @__PURE__ */ import_react17.default.createElement(import_react17.default.Fragment, {
3653
4249
  key: partKey
3654
4250
  }, renderToolPart(part, partKey));
3655
4251
  });
@@ -3659,14 +4255,14 @@ function EditableUserBubble({ item, slots, actions }) {
3659
4255
  const { classNames } = slots;
3660
4256
  const { edit } = item;
3661
4257
  if (!edit.isEditing) {
3662
- return /* @__PURE__ */ import_react14.default.createElement("div", {
4258
+ return /* @__PURE__ */ import_react17.default.createElement("div", {
3663
4259
  className: joinClasses(classNames?.root, classNames?.byRole?.user),
3664
4260
  "data-role": "user"
3665
- }, /* @__PURE__ */ import_react14.default.createElement("div", {
4261
+ }, /* @__PURE__ */ import_react17.default.createElement("div", {
3666
4262
  className: classNames?.text
3667
4263
  }, slots.renderText ? slots.renderText(item.text, {
3668
4264
  isStreaming: false
3669
- }) : item.text), /* @__PURE__ */ import_react14.default.createElement("button", {
4265
+ }) : item.text), /* @__PURE__ */ import_react17.default.createElement("button", {
3670
4266
  type: "button",
3671
4267
  onClick: edit.start,
3672
4268
  className: classNames?.actionButton,
@@ -3674,18 +4270,18 @@ function EditableUserBubble({ item, slots, actions }) {
3674
4270
  }, "Edit"), actions);
3675
4271
  }
3676
4272
  const textareaProps = edit.getTextareaProps();
3677
- return /* @__PURE__ */ import_react14.default.createElement("div", {
4273
+ return /* @__PURE__ */ import_react17.default.createElement("div", {
3678
4274
  "data-editing": "true"
3679
- }, /* @__PURE__ */ import_react14.default.createElement("textarea", {
4275
+ }, /* @__PURE__ */ import_react17.default.createElement("textarea", {
3680
4276
  ...textareaProps,
3681
4277
  rows: Math.min(8, edit.draft.split("\n").length + 1),
3682
4278
  className: classNames?.editTextarea
3683
- }), /* @__PURE__ */ import_react14.default.createElement("div", {
4279
+ }), /* @__PURE__ */ import_react17.default.createElement("div", {
3684
4280
  className: classNames?.editActions
3685
- }, /* @__PURE__ */ import_react14.default.createElement("button", {
4281
+ }, /* @__PURE__ */ import_react17.default.createElement("button", {
3686
4282
  type: "button",
3687
4283
  onClick: edit.cancel
3688
- }, "Cancel"), /* @__PURE__ */ import_react14.default.createElement("button", {
4284
+ }, "Cancel"), /* @__PURE__ */ import_react17.default.createElement("button", {
3689
4285
  type: "button",
3690
4286
  onClick: edit.save,
3691
4287
  disabled: !edit.canSave
@@ -3895,11 +4491,11 @@ function createSkillsSource(options) {
3895
4491
  if (cached) {
3896
4492
  return cached;
3897
4493
  }
3898
- const listSkills = options.client.listSkills;
4494
+ const listSkills = options.backend.listSkills;
3899
4495
  if (listSkills === void 0) {
3900
4496
  return Promise.reject(new AgentBackendUnsupportedError("listSkills"));
3901
4497
  }
3902
- const pending = listSkills.call(options.client, threadId).then((entries) => entries.map(toItem)).catch((error) => {
4498
+ const pending = listSkills.call(options.backend, threadId).then((entries) => entries.map(toItem)).catch((error) => {
3903
4499
  byThread.delete(key);
3904
4500
  throw error;
3905
4501
  });
@@ -3929,35 +4525,35 @@ function toItem(entry) {
3929
4525
  __name(toItem, "toItem");
3930
4526
 
3931
4527
  // src/composer/use-composer-autocomplete.ts
3932
- var import_react15 = require("react");
4528
+ var import_react18 = require("react");
3933
4529
  function useComposerAutocomplete(options) {
3934
4530
  const { value, sources, acceptOnTab = true } = options;
3935
- const latest = (0, import_react15.useRef)(options);
4531
+ const latest = (0, import_react18.useRef)(options);
3936
4532
  latest.current = options;
3937
- const inputRef = (0, import_react15.useRef)(null);
3938
- const [caret, setCaret] = (0, import_react15.useState)(value.length);
3939
- const [items, setItems] = (0, import_react15.useState)([]);
3940
- const [isLoading, setLoading] = (0, import_react15.useState)(false);
3941
- const [error, setError] = (0, import_react15.useState)(null);
3942
- const [activeIndex, setActiveIndex] = (0, import_react15.useState)(0);
3943
- const [dismissedIndex, setDismissedIndex] = (0, import_react15.useState)(null);
4533
+ const inputRef = (0, import_react18.useRef)(null);
4534
+ const [caret, setCaret] = (0, import_react18.useState)(value.length);
4535
+ const [items, setItems] = (0, import_react18.useState)([]);
4536
+ const [isLoading, setLoading] = (0, import_react18.useState)(false);
4537
+ const [error, setError] = (0, import_react18.useState)(null);
4538
+ const [activeIndex, setActiveIndex] = (0, import_react18.useState)(0);
4539
+ const [dismissedIndex, setDismissedIndex] = (0, import_react18.useState)(null);
3944
4540
  const safeCaret = Math.min(caret, value.length);
3945
- const match = (0, import_react15.useMemo)(() => findActiveTrigger(value, safeCaret, sources), [
4541
+ const match = (0, import_react18.useMemo)(() => findActiveTrigger(value, safeCaret, sources), [
3946
4542
  value,
3947
4543
  safeCaret,
3948
4544
  sources
3949
4545
  ]);
3950
4546
  const isActive = match !== null && dismissedIndex !== match.index;
3951
- const matchRef = (0, import_react15.useRef)(match);
4547
+ const matchRef = (0, import_react18.useRef)(match);
3952
4548
  matchRef.current = match;
3953
- const caretRef = (0, import_react15.useRef)(safeCaret);
4549
+ const caretRef = (0, import_react18.useRef)(safeCaret);
3954
4550
  caretRef.current = safeCaret;
3955
- const itemsRef = (0, import_react15.useRef)(items);
4551
+ const itemsRef = (0, import_react18.useRef)(items);
3956
4552
  itemsRef.current = items;
3957
- const activeIndexRef = (0, import_react15.useRef)(activeIndex);
4553
+ const activeIndexRef = (0, import_react18.useRef)(activeIndex);
3958
4554
  activeIndexRef.current = activeIndex;
3959
4555
  const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
3960
- (0, import_react15.useEffect)(() => {
4556
+ (0, import_react18.useEffect)(() => {
3961
4557
  const current = matchRef.current;
3962
4558
  if (requestKey === null || current === null) {
3963
4559
  setItems([]);
@@ -4005,25 +4601,25 @@ function useComposerAutocomplete(options) {
4005
4601
  ]);
4006
4602
  const isOpen = isActive;
4007
4603
  const activeItem = isOpen ? items[activeIndex] ?? null : null;
4008
- const reactId = (0, import_react15.useId)();
4604
+ const reactId = (0, import_react18.useId)();
4009
4605
  const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
4010
- const optionId = (0, import_react15.useCallback)((index) => `${listboxId}-option-${index}`, [
4606
+ const optionId = (0, import_react18.useCallback)((index) => `${listboxId}-option-${index}`, [
4011
4607
  listboxId
4012
4608
  ]);
4013
- const highlight = (0, import_react15.useCallback)((index) => {
4609
+ const highlight = (0, import_react18.useCallback)((index) => {
4014
4610
  const total = itemsRef.current.length;
4015
4611
  if (total === 0) return;
4016
4612
  setActiveIndex((index % total + total) % total);
4017
4613
  }, []);
4018
- const moveHighlight = (0, import_react15.useCallback)((delta) => highlight(activeIndexRef.current + delta), [
4614
+ const moveHighlight = (0, import_react18.useCallback)((delta) => highlight(activeIndexRef.current + delta), [
4019
4615
  highlight
4020
4616
  ]);
4021
- const dismiss = (0, import_react15.useCallback)(() => {
4617
+ const dismiss = (0, import_react18.useCallback)(() => {
4022
4618
  const current = matchRef.current;
4023
4619
  if (current) setDismissedIndex(current.index);
4024
4620
  }, []);
4025
- const pendingCaret = (0, import_react15.useRef)(null);
4026
- const accept = (0, import_react15.useCallback)((item) => {
4621
+ const pendingCaret = (0, import_react18.useRef)(null);
4622
+ const accept = (0, import_react18.useCallback)((item) => {
4027
4623
  const current = matchRef.current;
4028
4624
  if (!current) return;
4029
4625
  const chosen = item ?? itemsRef.current[activeIndexRef.current];
@@ -4034,16 +4630,16 @@ function useComposerAutocomplete(options) {
4034
4630
  setDismissedIndex(null);
4035
4631
  pendingCaret.current = edit.caret;
4036
4632
  }, []);
4037
- (0, import_react15.useLayoutEffect)(() => {
4633
+ (0, import_react18.useLayoutEffect)(() => {
4038
4634
  const position = pendingCaret.current;
4039
4635
  if (position === null) return;
4040
4636
  pendingCaret.current = null;
4041
4637
  inputRef.current?.setSelectionRange(position, position);
4042
4638
  });
4043
- const readCaret = (0, import_react15.useCallback)((element) => {
4639
+ const readCaret = (0, import_react18.useCallback)((element) => {
4044
4640
  setCaret(element.selectionStart ?? element.value.length);
4045
4641
  }, []);
4046
- const onKeyDown = (0, import_react15.useCallback)((event) => {
4642
+ const onKeyDown = (0, import_react18.useCallback)((event) => {
4047
4643
  if (!isOpen) return;
4048
4644
  const hasItems = itemsRef.current.length > 0;
4049
4645
  switch (event.key) {
@@ -4081,23 +4677,23 @@ function useComposerAutocomplete(options) {
4081
4677
  dismiss,
4082
4678
  moveHighlight
4083
4679
  ]);
4084
- const onChange = (0, import_react15.useCallback)((event) => {
4680
+ const onChange = (0, import_react18.useCallback)((event) => {
4085
4681
  readCaret(event.target);
4086
4682
  const next = findActiveTrigger(event.target.value, event.target.selectionStart ?? event.target.value.length, latest.current.sources);
4087
4683
  setDismissedIndex((current) => current !== null && next?.index === current ? current : null);
4088
4684
  }, [
4089
4685
  readCaret
4090
4686
  ]);
4091
- const onSelect = (0, import_react15.useCallback)((event) => readCaret(event.currentTarget), [
4687
+ const onSelect = (0, import_react18.useCallback)((event) => readCaret(event.currentTarget), [
4092
4688
  readCaret
4093
4689
  ]);
4094
- const onClick = (0, import_react15.useCallback)((event) => readCaret(event.currentTarget), [
4690
+ const onClick = (0, import_react18.useCallback)((event) => readCaret(event.currentTarget), [
4095
4691
  readCaret
4096
4692
  ]);
4097
- const setInput = (0, import_react15.useCallback)((element) => {
4693
+ const setInput = (0, import_react18.useCallback)((element) => {
4098
4694
  inputRef.current = element;
4099
4695
  }, []);
4100
- const getInputProps = (0, import_react15.useCallback)(() => ({
4696
+ const getInputProps = (0, import_react18.useCallback)(() => ({
4101
4697
  ref: setInput,
4102
4698
  onChange,
4103
4699
  onKeyDown,
@@ -4125,7 +4721,7 @@ function useComposerAutocomplete(options) {
4125
4721
  activeIndex,
4126
4722
  optionId
4127
4723
  ]);
4128
- const getListboxProps = (0, import_react15.useCallback)(() => ({
4724
+ const getListboxProps = (0, import_react18.useCallback)(() => ({
4129
4725
  id: listboxId,
4130
4726
  role: "listbox",
4131
4727
  "aria-label": match?.source.label ?? match?.source.id ?? "Suggestions"
@@ -4133,7 +4729,7 @@ function useComposerAutocomplete(options) {
4133
4729
  listboxId,
4134
4730
  match
4135
4731
  ]);
4136
- const getOptionProps = (0, import_react15.useCallback)((index) => ({
4732
+ const getOptionProps = (0, import_react18.useCallback)((index) => ({
4137
4733
  id: optionId(index),
4138
4734
  role: "option",
4139
4735
  "aria-selected": index === activeIndex
@@ -4167,7 +4763,7 @@ function isPromise(value) {
4167
4763
  __name(isPromise, "isPromise");
4168
4764
 
4169
4765
  // src/presentation/use-tool-catalog.ts
4170
- var import_react16 = require("react");
4766
+ var import_react19 = require("react");
4171
4767
  var shared = /* @__PURE__ */ new WeakMap();
4172
4768
  function load(client, agent) {
4173
4769
  let byAgent = shared.get(client);
@@ -4189,13 +4785,14 @@ function load(client, agent) {
4189
4785
  return request;
4190
4786
  }
4191
4787
  __name(load, "load");
4192
- function useToolCatalog(options) {
4193
- const { client, agent, enabled = true } = options;
4194
- const [entries, setEntries] = (0, import_react16.useState)([]);
4195
- const [isLoading, setLoading] = (0, import_react16.useState)(enabled);
4196
- const [error, setError] = (0, import_react16.useState)(null);
4197
- const [generation, setGeneration] = (0, import_react16.useState)(0);
4198
- (0, import_react16.useEffect)(() => {
4788
+ function useToolCatalog(options = {}) {
4789
+ const { agent, enabled = true } = options;
4790
+ const client = useAgentBackend(options.backend);
4791
+ const [entries, setEntries] = (0, import_react19.useState)([]);
4792
+ const [isLoading, setLoading] = (0, import_react19.useState)(enabled);
4793
+ const [error, setError] = (0, import_react19.useState)(null);
4794
+ const [generation, setGeneration] = (0, import_react19.useState)(0);
4795
+ (0, import_react19.useEffect)(() => {
4199
4796
  if (!enabled) {
4200
4797
  setLoading(false);
4201
4798
  return;
@@ -4221,14 +4818,14 @@ function useToolCatalog(options) {
4221
4818
  enabled,
4222
4819
  generation
4223
4820
  ]);
4224
- const refresh = (0, import_react16.useCallback)(() => {
4821
+ const refresh = (0, import_react19.useCallback)(() => {
4225
4822
  shared.get(client)?.delete(agent ?? "");
4226
4823
  setGeneration((current) => current + 1);
4227
4824
  }, [
4228
4825
  client,
4229
4826
  agent
4230
4827
  ]);
4231
- const catalog = (0, import_react16.useMemo)(() => toolCatalogFrom(entries), [
4828
+ const catalog = (0, import_react19.useMemo)(() => toolCatalogFrom(entries), [
4232
4829
  entries
4233
4830
  ]);
4234
4831
  return {
@@ -4242,7 +4839,7 @@ function useToolCatalog(options) {
4242
4839
  __name(useToolCatalog, "useToolCatalog");
4243
4840
 
4244
4841
  // src/approvals/countdown.ts
4245
- var import_react17 = require("react");
4842
+ var import_react20 = require("react");
4246
4843
  function approvalCountdown(expiresAt, now = Date.now()) {
4247
4844
  const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
4248
4845
  if (!Number.isFinite(deadline)) {
@@ -4260,10 +4857,10 @@ function approvalCountdown(expiresAt, now = Date.now()) {
4260
4857
  __name(approvalCountdown, "approvalCountdown");
4261
4858
  function useApprovalCountdown(expiresAt, options = {}) {
4262
4859
  const { intervalMs = 1e3 } = options;
4263
- const nowRef = (0, import_react17.useRef)(options.now ?? Date.now);
4860
+ const nowRef = (0, import_react20.useRef)(options.now ?? Date.now);
4264
4861
  nowRef.current = options.now ?? Date.now;
4265
- const [state, setState] = (0, import_react17.useState)(() => approvalCountdown(expiresAt, nowRef.current()));
4266
- (0, import_react17.useEffect)(() => {
4862
+ const [state, setState] = (0, import_react20.useState)(() => approvalCountdown(expiresAt, nowRef.current()));
4863
+ (0, import_react20.useEffect)(() => {
4267
4864
  const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
4268
4865
  const first = read();
4269
4866
  setState(first);
@@ -4510,41 +5107,27 @@ function sumUsage(rows) {
4510
5107
  __name(sumUsage, "sumUsage");
4511
5108
 
4512
5109
  // src/use-agent-chat.ts
4513
- var import_react18 = require("@ai-sdk/react");
4514
- var import_react19 = require("react");
4515
- function useAgentChat(options) {
4516
- const latest = (0, import_react19.useRef)(options);
5110
+ var import_react21 = require("@ai-sdk/react");
5111
+ var import_react22 = require("react");
5112
+ function useAgentChat(options = {}) {
5113
+ const latest = (0, import_react22.useRef)(options);
4517
5114
  latest.current = options;
4518
- const [runId, setRunId] = (0, import_react19.useState)(options.resumeRunId);
4519
- const runIdRef = (0, import_react19.useRef)(runId);
5115
+ const [runId, setRunId] = (0, import_react22.useState)(options.resumeRunId);
5116
+ const runIdRef = (0, import_react22.useRef)(runId);
4520
5117
  runIdRef.current = runId;
4521
- const settlingRunIdRef = (0, import_react19.useRef)(void 0);
4522
- const autoResumeRunIdRef = (0, import_react19.useRef)(void 0);
4523
- const [autoResume, setAutoResume] = (0, import_react19.useState)(false);
4524
- const [activeRunId, setActiveRunId] = (0, import_react19.useState)(null);
4525
- const regenerateNext = (0, import_react19.useRef)(false);
4526
- const createdThreadId = (0, import_react19.useRef)(void 0);
4527
- const client = (0, import_react19.useMemo)(() => {
4528
- if (options.backend) return options.backend;
4529
- if (options.client) return options.client;
4530
- return new AgentClient({
4531
- ...options.baseUrl !== void 0 ? {
4532
- baseUrl: options.baseUrl
4533
- } : {},
4534
- ...options.credentials !== void 0 ? {
4535
- credentials: options.credentials
4536
- } : {},
4537
- ...options.fetch !== void 0 ? {
4538
- fetch: options.fetch
4539
- } : {},
4540
- getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
4541
- });
4542
- }, []);
4543
- const [connection, setConnection] = (0, import_react19.useState)({
5118
+ const settlingRunIdRef = (0, import_react22.useRef)(void 0);
5119
+ const autoResumeRunIdRef = (0, import_react22.useRef)(void 0);
5120
+ const [autoResume, setAutoResume] = (0, import_react22.useState)(false);
5121
+ const [activeRunId, setActiveRunId] = (0, import_react22.useState)(null);
5122
+ const regenerateNext = (0, import_react22.useRef)(false);
5123
+ const createdThreadId = (0, import_react22.useRef)(void 0);
5124
+ const resolved = useAgentBackend(options.backend);
5125
+ const client = (0, import_react22.useRef)(resolved).current;
5126
+ const [connection, setConnection] = (0, import_react22.useState)({
4544
5127
  status: "live"
4545
5128
  });
4546
- const resyncAfterSettle = (0, import_react19.useRef)(false);
4547
- (0, import_react19.useEffect)(() => {
5129
+ const resyncAfterSettle = (0, import_react22.useRef)(false);
5130
+ (0, import_react22.useEffect)(() => {
4548
5131
  if (!options.resume || options.threadId === void 0) return;
4549
5132
  let cancelled = false;
4550
5133
  const threadId = options.threadId;
@@ -4564,7 +5147,7 @@ function useAgentChat(options) {
4564
5147
  options.resume,
4565
5148
  options.threadId
4566
5149
  ]);
4567
- const transport = (0, import_react19.useMemo)(() => {
5150
+ const transport = (0, import_react22.useMemo)(() => {
4568
5151
  function onMeta(meta) {
4569
5152
  settlingRunIdRef.current = meta.runId;
4570
5153
  setRunId(meta.runId);
@@ -4619,8 +5202,8 @@ function useAgentChat(options) {
4619
5202
  }, "onAttemptStart")
4620
5203
  });
4621
5204
  }, []);
4622
- const backgroundRef = (0, import_react19.useRef)(() => Promise.resolve());
4623
- const chat = (0, import_react18.useChat)({
5205
+ const backgroundRef = (0, import_react22.useRef)(() => Promise.resolve());
5206
+ const chat = (0, import_react21.useChat)({
4624
5207
  transport,
4625
5208
  resume: options.resumeRunId !== void 0 || autoResume,
4626
5209
  ...options.threadId !== void 0 ? {
@@ -4668,7 +5251,7 @@ function useAgentChat(options) {
4668
5251
  }
4669
5252
  }, "onFinish")
4670
5253
  });
4671
- const chatRef = (0, import_react19.useRef)(chat);
5254
+ const chatRef = (0, import_react22.useRef)(chat);
4672
5255
  chatRef.current = chat;
4673
5256
  async function resyncFromThread() {
4674
5257
  const threadId = latest.current.threadId ?? createdThreadId.current;
@@ -4680,11 +5263,11 @@ function useAgentChat(options) {
4680
5263
  }
4681
5264
  }
4682
5265
  __name(resyncFromThread, "resyncFromThread");
4683
- const turnInFlight = (0, import_react19.useRef)(false);
4684
- const isTurnInFlight = (0, import_react19.useCallback)(() => turnInFlight.current || transport.isAttemptLive, [
5266
+ const turnInFlight = (0, import_react22.useRef)(false);
5267
+ const isTurnInFlight = (0, import_react22.useCallback)(() => turnInFlight.current || transport.isAttemptLive, [
4685
5268
  transport
4686
5269
  ]);
4687
- const sendMessage = (0, import_react19.useCallback)(async (...args) => {
5270
+ const sendMessage = (0, import_react22.useCallback)(async (...args) => {
4688
5271
  const blocked = latest.current.blocked;
4689
5272
  if (blocked != null) throw new QuotaBlockedError(blocked);
4690
5273
  if (isTurnInFlight()) return;
@@ -4697,15 +5280,15 @@ function useAgentChat(options) {
4697
5280
  }, [
4698
5281
  isTurnInFlight
4699
5282
  ]);
4700
- const addToolResult = (0, import_react19.useCallback)(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
5283
+ const addToolResult = (0, import_react22.useCallback)(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
4701
5284
  tool,
4702
5285
  toolCallId,
4703
5286
  output
4704
5287
  }), []);
4705
- const [threads, setThreads] = (0, import_react19.useState)([]);
4706
- const [quota, setQuota] = (0, import_react19.useState)(null);
4707
- const [backgroundRuns, setBackgroundRuns] = (0, import_react19.useState)([]);
4708
- const refreshBackground = (0, import_react19.useCallback)(async () => {
5288
+ const [threads, setThreads] = (0, import_react22.useState)([]);
5289
+ const [quota, setQuota] = (0, import_react22.useState)(null);
5290
+ const [backgroundRuns, setBackgroundRuns] = (0, import_react22.useState)([]);
5291
+ const refreshBackground = (0, import_react22.useCallback)(async () => {
4709
5292
  const threadId = latest.current.threadId ?? createdThreadId.current;
4710
5293
  if (threadId === void 0) {
4711
5294
  return;
@@ -4730,7 +5313,7 @@ function useAgentChat(options) {
4730
5313
  ]);
4731
5314
  backgroundRef.current = refreshBackground;
4732
5315
  const isWorking = backgroundRuns.some((run) => run.status === "running");
4733
- (0, import_react19.useEffect)(() => {
5316
+ (0, import_react22.useEffect)(() => {
4734
5317
  if (options.background !== true || options.threadId === void 0) {
4735
5318
  return;
4736
5319
  }
@@ -4740,7 +5323,7 @@ function useAgentChat(options) {
4740
5323
  options.threadId,
4741
5324
  refreshBackground
4742
5325
  ]);
4743
- (0, import_react19.useEffect)(() => {
5326
+ (0, import_react22.useEffect)(() => {
4744
5327
  const every = latest.current.backgroundPollMs ?? 5e3;
4745
5328
  if (latest.current.background !== true || !isWorking || every <= 0) {
4746
5329
  return;
@@ -4751,26 +5334,26 @@ function useAgentChat(options) {
4751
5334
  isWorking,
4752
5335
  refreshBackground
4753
5336
  ]);
4754
- const loadThreads = (0, import_react19.useCallback)(async () => {
5337
+ const loadThreads = (0, import_react22.useCallback)(async () => {
4755
5338
  const list = await client.listThreads();
4756
5339
  setThreads(list);
4757
5340
  return list;
4758
5341
  }, [
4759
5342
  client
4760
5343
  ]);
4761
- const loadThread = (0, import_react19.useCallback)((id) => client.getThread(id), [
5344
+ const loadThread = (0, import_react22.useCallback)((id) => client.getThread(id), [
4762
5345
  client
4763
5346
  ]);
4764
- const deleteThread = (0, import_react19.useCallback)(async (id) => {
5347
+ const deleteThread = (0, import_react22.useCallback)(async (id) => {
4765
5348
  await client.deleteThread(id);
4766
5349
  setThreads((current) => current.filter((thread) => thread.id !== id));
4767
5350
  }, [
4768
5351
  client
4769
5352
  ]);
4770
- const forkThread = (0, import_react19.useCallback)((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
5353
+ const forkThread = (0, import_react22.useCallback)((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
4771
5354
  client
4772
5355
  ]);
4773
- const renameThread = (0, import_react19.useCallback)(async (id, title) => {
5356
+ const renameThread = (0, import_react22.useCallback)(async (id, title) => {
4774
5357
  await client.updateThread(id, {
4775
5358
  title
4776
5359
  });
@@ -4781,24 +5364,24 @@ function useAgentChat(options) {
4781
5364
  }, [
4782
5365
  client
4783
5366
  ]);
4784
- const promoteThread = (0, import_react19.useCallback)(async (id) => {
5367
+ const promoteThread = (0, import_react22.useCallback)(async (id) => {
4785
5368
  await requireBackendMethod(client, "promoteThread")(id);
4786
5369
  await loadThreads();
4787
5370
  }, [
4788
5371
  client,
4789
5372
  loadThreads
4790
5373
  ]);
4791
- const truncateFromMessage = (0, import_react19.useCallback)((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
5374
+ const truncateFromMessage = (0, import_react22.useCallback)((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
4792
5375
  client
4793
5376
  ]);
4794
- const loadQuota = (0, import_react19.useCallback)(async () => {
5377
+ const loadQuota = (0, import_react22.useCallback)(async () => {
4795
5378
  const today = await requireBackendMethod(client, "getQuotaToday")();
4796
5379
  setQuota(today);
4797
5380
  return today;
4798
5381
  }, [
4799
5382
  client
4800
5383
  ]);
4801
- const cancel = (0, import_react19.useCallback)(async () => {
5384
+ const cancel = (0, import_react22.useCallback)(async () => {
4802
5385
  chatRef.current.stop();
4803
5386
  const activeRunId2 = runIdRef.current;
4804
5387
  if (activeRunId2) {
@@ -4810,7 +5393,7 @@ function useAgentChat(options) {
4810
5393
  }, [
4811
5394
  client
4812
5395
  ]);
4813
- const approve = (0, import_react19.useCallback)(async ({ toolCallId, remember, via }) => {
5396
+ const approve = (0, import_react22.useCallback)(async ({ toolCallId, remember, via }) => {
4814
5397
  await requireBackendMethod(client, "approveToolCall")({
4815
5398
  toolCallId,
4816
5399
  ...remember === true ? {
@@ -4823,7 +5406,7 @@ function useAgentChat(options) {
4823
5406
  }, [
4824
5407
  client
4825
5408
  ]);
4826
- const reject = (0, import_react19.useCallback)(async ({ toolCallId, reason, via }) => {
5409
+ const reject = (0, import_react22.useCallback)(async ({ toolCallId, reason, via }) => {
4827
5410
  await requireBackendMethod(client, "rejectToolCall")({
4828
5411
  toolCallId,
4829
5412
  ...reason !== void 0 ? {
@@ -4836,7 +5419,7 @@ function useAgentChat(options) {
4836
5419
  }, [
4837
5420
  client
4838
5421
  ]);
4839
- const answer = (0, import_react19.useCallback)(async ({ toolCallId, answers }) => {
5422
+ const answer = (0, import_react22.useCallback)(async ({ toolCallId, answers }) => {
4840
5423
  await requireBackendMethod(client, "answerToolCall")({
4841
5424
  toolCallId,
4842
5425
  ...answers !== void 0 ? {
@@ -4846,14 +5429,14 @@ function useAgentChat(options) {
4846
5429
  }, [
4847
5430
  client
4848
5431
  ]);
4849
- const skip = (0, import_react19.useCallback)(async ({ toolCallId }) => {
5432
+ const skip = (0, import_react22.useCallback)(async ({ toolCallId }) => {
4850
5433
  await requireBackendMethod(client, "skipToolCall")({
4851
5434
  toolCallId
4852
5435
  });
4853
5436
  }, [
4854
5437
  client
4855
5438
  ]);
4856
- const regenerate = (0, import_react19.useCallback)(() => {
5439
+ const regenerate = (0, import_react22.useCallback)(() => {
4857
5440
  const blocked = latest.current.blocked;
4858
5441
  if (blocked != null) throw new QuotaBlockedError(blocked);
4859
5442
  if (isTurnInFlight()) return;
@@ -4870,7 +5453,7 @@ function useAgentChat(options) {
4870
5453
  isWorking,
4871
5454
  refresh: refreshBackground
4872
5455
  };
4873
- const setThreadModel = (0, import_react19.useCallback)(async (model) => {
5456
+ const setThreadModel = (0, import_react22.useCallback)(async (model) => {
4874
5457
  const threadId = latest.current.threadId ?? createdThreadId.current;
4875
5458
  if (threadId === void 0) {
4876
5459
  throw new Error("setThreadModel: this chat has no thread yet");
@@ -4884,7 +5467,7 @@ function useAgentChat(options) {
4884
5467
  }, [
4885
5468
  client
4886
5469
  ]);
4887
- const getThreadId = (0, import_react19.useCallback)(() => latest.current.threadId ?? createdThreadId.current, []);
5470
+ const getThreadId = (0, import_react22.useCallback)(() => latest.current.threadId ?? createdThreadId.current, []);
4888
5471
  const status = connection.status === "reconnecting" ? "reconnecting" : chat.status;
4889
5472
  return {
4890
5473
  ...chat,
@@ -4904,10 +5487,8 @@ function useAgentChat(options) {
4904
5487
  */
4905
5488
  getThreadId,
4906
5489
  setThreadModel,
4907
- /** The backend this chat talks to — pass it to `useThreads`, `useMessageFeedback`, … */
5490
+ /** The backend this chat talks to — the same one every other hook under the provider uses. */
4908
5491
  backend: client,
4909
- /** Same object as {@link backend}; kept for callers that read it under its old name. */
4910
- client,
4911
5492
  threads,
4912
5493
  loadThreads,
4913
5494
  loadThread,
@@ -4937,20 +5518,13 @@ var QuotaBlockedError = class extends Error {
4937
5518
  this.name = "QuotaBlockedError";
4938
5519
  }
4939
5520
  };
4940
- async function mergeHeaders(options) {
4941
- const dynamic = await options.getHeaders?.() ?? {};
4942
- return {
4943
- ...options.headers,
4944
- ...dynamic
4945
- };
4946
- }
4947
- __name(mergeHeaders, "mergeHeaders");
4948
5521
  // Annotate the CommonJS export names for ESM import in node:
4949
5522
  0 && (module.exports = {
4950
5523
  AgentBackendUnsupportedError,
4951
5524
  AgentChatTransport,
4952
5525
  AgentClient,
4953
5526
  AgentHttpError,
5527
+ AgentProvider,
4954
5528
  AmbientRenderUiContext,
4955
5529
  ChatInput,
4956
5530
  DEFAULT_SPEECH_LANG,
@@ -4996,6 +5570,7 @@ __name(mergeHeaders, "mergeHeaders");
4996
5570
  storedThreadToUiMessages,
4997
5571
  toolCallState,
4998
5572
  toolCatalogFrom,
5573
+ useAgentBackend,
4999
5574
  useAgentChat,
5000
5575
  useAgents,
5001
5576
  useAmbientRenderUi,