dooers-agents-client 0.9.0 → 0.9.2

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/main.cjs CHANGED
@@ -246,6 +246,8 @@ function toWireContentPart(p) {
246
246
  ref_id: p.refId
247
247
  };
248
248
  if (p.duration != null) w.duration = p.duration;
249
+ if (p.filename?.trim()) w.filename = p.filename.trim();
250
+ if (p.mimeType?.trim()) w.mime_type = p.mimeType.trim();
249
251
  if (p.url) w.url = p.url;
250
252
  return w;
251
253
  }
@@ -254,6 +256,8 @@ function toWireContentPart(p) {
254
256
  type: "image",
255
257
  ref_id: p.refId
256
258
  };
259
+ if (p.filename?.trim()) w.filename = p.filename.trim();
260
+ if (p.mimeType?.trim()) w.mime_type = p.mimeType.trim();
257
261
  if (p.url) w.url = p.url;
258
262
  return w;
259
263
  }
@@ -262,6 +266,8 @@ function toWireContentPart(p) {
262
266
  type: "document",
263
267
  ref_id: p.refId
264
268
  };
269
+ if (p.filename?.trim()) w.filename = p.filename.trim();
270
+ if (p.mimeType?.trim()) w.mime_type = p.mimeType.trim();
265
271
  if (p.url) w.url = p.url;
266
272
  return w;
267
273
  }
@@ -272,6 +278,35 @@ function toWireContentPart(p) {
272
278
  var MAX_RECONNECT_ATTEMPTS = 5;
273
279
  var RECONNECT_DELAYS = [1e3, 2e3, 4e3, 8e3, 16e3];
274
280
  var SEND_MESSAGE_TIMEOUT = 3e4;
281
+ function blobPartFilename(blob, override) {
282
+ const o = (override ?? "").trim();
283
+ if (o) return o;
284
+ const t = (blob.type || "").toLowerCase();
285
+ if (t.includes("webm")) return "recording.webm";
286
+ if (t.includes("ogg")) return "recording.ogg";
287
+ if (t.includes("mpeg") || t.includes("mp3")) return "recording.mp3";
288
+ if (t.includes("mp4") || t.includes("m4a") || t.includes("aac")) return "recording.m4a";
289
+ if (t.startsWith("audio/")) return `recording.${t.split("/")[1]?.split("+")[0] || "bin"}`;
290
+ return "recording.bin";
291
+ }
292
+ async function readHttpErrorMessage(response) {
293
+ const raw = await response.text().catch(() => "") || "";
294
+ const trimmed = raw.trim();
295
+ if (!trimmed) {
296
+ return `Upload failed: ${response.status} ${response.statusText}`.trim();
297
+ }
298
+ try {
299
+ const j = JSON.parse(trimmed);
300
+ const d = j.detail;
301
+ if (typeof d === "string") return d;
302
+ if (Array.isArray(d) && d.length > 0) {
303
+ const first = d[0];
304
+ if (first && typeof first.msg === "string") return first.msg;
305
+ }
306
+ } catch {
307
+ }
308
+ return trimmed.length > 300 ? `${trimmed.slice(0, 300)}\u2026` : trimmed;
309
+ }
275
310
  var AgentServerClient = class {
276
311
  wsUrl;
277
312
  constructor(apiMessagesUrl) {
@@ -365,6 +400,12 @@ var AgentClient = class {
365
400
  url = "";
366
401
  httpBaseUrl = "";
367
402
  agentId = "";
403
+ /** Mirrors ``AgentProvider`` ``agentId`` so HTTP uploads work before WS ``connect`` completes. */
404
+ uploadAgentId = "";
405
+ /** Current chat thread id for ``POST /uploads`` (aligns GCS path with ``hydrate_thread_events``). */
406
+ uploadThreadId = "";
407
+ /** Optional run id for ``POST /uploads`` (metadata only). */
408
+ uploadRunId = "";
368
409
  uploadUrl;
369
410
  config = {
370
411
  organizationId: "",
@@ -379,7 +420,7 @@ var AgentClient = class {
379
420
  subscriptionRefs = /* @__PURE__ */ new Map();
380
421
  // Track optimistic events for reconciliation
381
422
  pendingOptimistic = /* @__PURE__ */ new Map();
382
- // Pending message promises — resolved when event.append arrives with matching clientEventId
423
+ // Pending message promises — keyed by outbound frame id (same as client_event_id for sends).
383
424
  pendingMessages = /* @__PURE__ */ new Map();
384
425
  // Track last event ID per thread for gap recovery on reconnect
385
426
  lastEventIds = /* @__PURE__ */ new Map();
@@ -397,14 +438,40 @@ var AgentClient = class {
397
438
  setUploadUrl(url) {
398
439
  this.uploadUrl = url;
399
440
  }
400
- async upload(file) {
441
+ /** Sync from ``AgentProvider`` ``agentId``; used for ``POST /uploads`` ``agent_id`` (non-WS). */
442
+ setUploadAgentId(agentId) {
443
+ this.uploadAgentId = (agentId ?? "").trim();
444
+ }
445
+ /** Sync active thread id for chat uploads (must match persisted thread for signed URL keys). */
446
+ setUploadThreadId(threadId) {
447
+ this.uploadThreadId = (threadId ?? "").trim();
448
+ }
449
+ setUploadRunId(runId) {
450
+ this.uploadRunId = (runId ?? "").trim();
451
+ }
452
+ async upload(file, options) {
401
453
  if (!this.uploadUrl) {
402
454
  throw new Error("uploadUrl not configured");
403
455
  }
456
+ const aid = (this.uploadAgentId || this.agentId || "").trim();
457
+ if (!aid) {
458
+ throw new Error("agentId is required for upload (set AgentProvider agentId)");
459
+ }
404
460
  const formData = new FormData();
405
- formData.append("file", file);
406
- if (this.agentId) {
407
- formData.append("agent_id", this.agentId);
461
+ if (file instanceof File) {
462
+ const partName = options?.filename?.trim() || file.name.trim() || "upload";
463
+ formData.append("file", file, partName);
464
+ } else {
465
+ formData.append("file", file, blobPartFilename(file, options?.filename));
466
+ }
467
+ formData.append("agent_id", aid);
468
+ const tid = this.uploadThreadId.trim();
469
+ if (tid) {
470
+ formData.append("thread_id", tid);
471
+ }
472
+ const rid = this.uploadRunId.trim();
473
+ if (rid) {
474
+ formData.append("run_id", rid);
408
475
  }
409
476
  const headers = {};
410
477
  if (this.config.authToken) {
@@ -416,7 +483,8 @@ var AgentClient = class {
416
483
  headers
417
484
  });
418
485
  if (!response.ok) {
419
- throw new Error(`Upload failed: ${response.status} ${response.statusText}`);
486
+ const detail = await readHttpErrorMessage(response);
487
+ throw new Error(detail);
420
488
  }
421
489
  const result = await response.json();
422
490
  return {
@@ -430,6 +498,7 @@ var AgentClient = class {
430
498
  connect(url, agentId, config) {
431
499
  this.url = apiMessagesUrlToWebSocketUrl(url);
432
500
  this.agentId = agentId;
501
+ this.uploadAgentId = agentId.trim();
433
502
  this.config = config ?? { organizationId: "", workspaceId: "", userId: "" };
434
503
  this.isIntentionallyClosed = false;
435
504
  try {
@@ -445,16 +514,29 @@ var AgentClient = class {
445
514
  this.callbacks.setConnectionStatus("connecting");
446
515
  this.createConnection();
447
516
  }
517
+ /** Clear the last in-chat send error banner (see ``connection.sendError``). */
518
+ clearSendError() {
519
+ this.callbacks.setSendError(null);
520
+ }
521
+ abortPendingMessages(reason) {
522
+ for (const [clientEventId, pending] of this.pendingMessages) {
523
+ clearTimeout(pending.timer);
524
+ const opt = this.pendingOptimistic.get(clientEventId);
525
+ if (opt?.threadId) {
526
+ this.callbacks.removeOptimistic(opt.threadId, clientEventId);
527
+ }
528
+ this.pendingOptimistic.delete(clientEventId);
529
+ pending.reject(new Error(reason));
530
+ }
531
+ this.pendingMessages.clear();
532
+ }
448
533
  disconnect() {
449
534
  this.isIntentionallyClosed = true;
450
535
  if (this.reconnectTimer) {
451
536
  clearTimeout(this.reconnectTimer);
452
537
  this.reconnectTimer = null;
453
538
  }
454
- for (const [, pending] of this.pendingMessages) {
455
- clearTimeout(pending.timer);
456
- }
457
- this.pendingMessages.clear();
539
+ this.abortPendingMessages("Disconnected");
458
540
  if (this.ws) {
459
541
  this.ws.onopen = null;
460
542
  this.ws.onmessage = null;
@@ -546,6 +628,7 @@ var AgentClient = class {
546
628
  }
547
629
  // --- Messaging ---
548
630
  sendMessage(params) {
631
+ this.callbacks.setSendError(null);
549
632
  const clientEventId = crypto.randomUUID();
550
633
  const content = params.content ? params.content.map(toWireContentPart) : [{ type: "text", text: params.text ?? "" }];
551
634
  const displayContent = params.content ? params.content.map((p) => {
@@ -553,11 +636,27 @@ var AgentClient = class {
553
636
  case "text":
554
637
  return { type: "text", text: p.text };
555
638
  case "audio":
556
- return { type: "audio", duration: p.duration };
639
+ return {
640
+ type: "audio",
641
+ duration: p.duration,
642
+ ...p.url ? { url: p.url } : {},
643
+ ...p.mimeType ? { mimeType: p.mimeType } : {},
644
+ ...p.filename ? { filename: p.filename } : {}
645
+ };
557
646
  case "image":
558
- return { type: "image" };
647
+ return {
648
+ type: "image",
649
+ ...p.url ? { url: p.url } : {},
650
+ ...p.mimeType ? { mimeType: p.mimeType } : {},
651
+ ...p.filename ? { filename: p.filename } : {}
652
+ };
559
653
  case "document":
560
- return { type: "document" };
654
+ return {
655
+ type: "document",
656
+ ...p.url ? { url: p.url } : {},
657
+ ...p.mimeType ? { mimeType: p.mimeType } : {},
658
+ ...p.filename ? { filename: p.filename } : {}
659
+ };
561
660
  default:
562
661
  return { type: "text", text: "" };
563
662
  }
@@ -601,23 +700,32 @@ var AgentClient = class {
601
700
  if (params.metadata) {
602
701
  payload.metadata = params.metadata;
603
702
  }
604
- this.send("event.create", payload);
703
+ this.sendRaw({
704
+ id: clientEventId,
705
+ type: "event.create",
706
+ payload
707
+ });
605
708
  return promise;
606
709
  }
607
710
  sendFormResponse(params) {
711
+ this.callbacks.setSendError(null);
608
712
  const clientEventId = crypto.randomUUID();
609
713
  const promise = this.createPendingPromise(clientEventId);
610
- this.send("event.create", {
611
- thread_id: params.threadId,
612
- client_event_id: clientEventId,
613
- event: {
614
- type: "form.response",
615
- actor: "user",
616
- content: [],
617
- data: {
618
- form_event_id: params.formEventId,
619
- cancelled: params.cancelled,
620
- values: params.values
714
+ this.sendRaw({
715
+ id: clientEventId,
716
+ type: "event.create",
717
+ payload: {
718
+ thread_id: params.threadId,
719
+ client_event_id: clientEventId,
720
+ event: {
721
+ type: "form.response",
722
+ actor: "user",
723
+ content: [],
724
+ data: {
725
+ form_event_id: params.formEventId,
726
+ cancelled: params.cancelled,
727
+ values: params.values
728
+ }
621
729
  }
622
730
  }
623
731
  });
@@ -627,14 +735,20 @@ var AgentClient = class {
627
735
  createPendingPromise(clientEventId) {
628
736
  return new Promise((resolve, reject) => {
629
737
  const timer = setTimeout(() => {
738
+ const opt = this.pendingOptimistic.get(clientEventId);
739
+ if (opt?.threadId) {
740
+ this.callbacks.removeOptimistic(opt.threadId, clientEventId);
741
+ }
742
+ this.pendingOptimistic.delete(clientEventId);
630
743
  this.pendingMessages.delete(clientEventId);
631
744
  reject(new Error("Request timed out waiting for server response"));
632
745
  }, SEND_MESSAGE_TIMEOUT);
633
- this.pendingMessages.set(clientEventId, { resolve, timer });
746
+ this.pendingMessages.set(clientEventId, { resolve, reject, timer });
634
747
  });
635
748
  }
636
749
  createConnection() {
637
750
  if (this.ws) {
751
+ this.abortPendingMessages("Connection lost; reconnecting");
638
752
  this.ws.onopen = null;
639
753
  this.ws.onmessage = null;
640
754
  this.ws.onclose = null;
@@ -702,9 +816,26 @@ var AgentClient = class {
702
816
  this.callbacks.setConnectionStatus("error", frame.payload.error?.message);
703
817
  }
704
818
  } else if (!frame.payload.ok && frame.payload.error) {
819
+ const ackId = frame.payload.ack_id;
820
+ const err = frame.payload.error;
821
+ if (ackId) {
822
+ const pending = this.pendingMessages.get(ackId);
823
+ if (pending) {
824
+ clearTimeout(pending.timer);
825
+ this.pendingMessages.delete(ackId);
826
+ const msg = err.message || "Request rejected";
827
+ const opt = this.pendingOptimistic.get(ackId);
828
+ if (opt?.threadId) {
829
+ this.callbacks.removeOptimistic(opt.threadId, ackId);
830
+ }
831
+ this.pendingOptimistic.delete(ackId);
832
+ pending.reject(new Error(msg));
833
+ this.callbacks.setSendError(msg);
834
+ }
835
+ }
705
836
  this.onError?.({
706
- code: frame.payload.error.code,
707
- message: frame.payload.error.message,
837
+ code: err.code,
838
+ message: err.message,
708
839
  frameType: "ack"
709
840
  });
710
841
  }
@@ -741,6 +872,7 @@ var AgentClient = class {
741
872
  case "event.append": {
742
873
  const events = this.resolveEventUrls(frame.payload.events.map(toThreadEvent));
743
874
  const resolvedClientEventIds = [];
875
+ const pendingIdsToResolve = [];
744
876
  for (const event of events) {
745
877
  if (event.clientEventId && this.pendingOptimistic.has(event.clientEventId)) {
746
878
  resolvedClientEventIds.push(event.clientEventId);
@@ -750,8 +882,7 @@ var AgentClient = class {
750
882
  const pendingMessage = this.pendingMessages.get(event.clientEventId);
751
883
  if (pendingMessage) {
752
884
  clearTimeout(pendingMessage.timer);
753
- pendingMessage.resolve({ threadId: frame.payload.thread_id });
754
- this.pendingMessages.delete(event.clientEventId);
885
+ pendingIdsToResolve.push(event.clientEventId);
755
886
  }
756
887
  }
757
888
  }
@@ -764,6 +895,14 @@ var AgentClient = class {
764
895
  } else {
765
896
  this.callbacks.onEventAppend(frame.payload.thread_id, events);
766
897
  }
898
+ const tid = frame.payload.thread_id;
899
+ for (const id of pendingIdsToResolve) {
900
+ const pending = this.pendingMessages.get(id);
901
+ if (pending) {
902
+ pending.resolve({ threadId: tid });
903
+ this.pendingMessages.delete(id);
904
+ }
905
+ }
767
906
  break;
768
907
  }
769
908
  case "event.list.result": {
@@ -816,6 +955,7 @@ var AgentClient = class {
816
955
  }
817
956
  scheduleReconnect() {
818
957
  if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
958
+ this.abortPendingMessages("Connection lost after maximum retries");
819
959
  this.callbacks.setReconnectFailed();
820
960
  this.callbacks.setConnectionStatus("error", "Connection lost after maximum retries");
821
961
  return;
@@ -850,6 +990,43 @@ var AgentClient = class {
850
990
  });
851
991
  }
852
992
  };
993
+ function mergeDisplayContentParts(prev, next) {
994
+ if (!next?.length) return prev;
995
+ if (!prev?.length) return next;
996
+ const out = [];
997
+ const len = Math.max(prev.length, next.length);
998
+ for (let i = 0; i < len; i++) {
999
+ const p = prev[i];
1000
+ const n = next[i];
1001
+ if (!n) {
1002
+ if (p) out.push(p);
1003
+ continue;
1004
+ }
1005
+ if (!p) {
1006
+ out.push(n);
1007
+ continue;
1008
+ }
1009
+ if (p.type !== n.type) {
1010
+ out.push(n);
1011
+ continue;
1012
+ }
1013
+ if (n.type === "image" || n.type === "audio" || n.type === "document") {
1014
+ const url = n.url ?? ("url" in p ? p.url : void 0);
1015
+ out.push({ ...p, ...n, ...url ? { url } : {} });
1016
+ continue;
1017
+ }
1018
+ out.push(n);
1019
+ }
1020
+ return out;
1021
+ }
1022
+ function mergeThreadEventById(prev, next) {
1023
+ const content = mergeDisplayContentParts(prev.content, next.content);
1024
+ return {
1025
+ ...prev,
1026
+ ...next,
1027
+ ...content !== void 0 ? { content } : {}
1028
+ };
1029
+ }
853
1030
  function extractFormStates(events, existing) {
854
1031
  let result = existing;
855
1032
  for (const e of events) {
@@ -872,6 +1049,7 @@ function createAgentStore() {
872
1049
  connection: {
873
1050
  status: "idle",
874
1051
  error: null,
1052
+ sendError: null,
875
1053
  reconnectAttempts: 0,
876
1054
  reconnectFailed: false
877
1055
  },
@@ -900,7 +1078,15 @@ function createAgentStore() {
900
1078
  loadingThreads: /* @__PURE__ */ new Set(),
901
1079
  actions: {
902
1080
  setConnectionStatus: (status, error) => set((s) => ({
903
- connection: { ...s.connection, status, error: error ?? null }
1081
+ connection: {
1082
+ ...s.connection,
1083
+ status,
1084
+ error: error ?? null,
1085
+ ...status === "connected" ? { sendError: null } : {}
1086
+ }
1087
+ })),
1088
+ setSendError: (message) => set((s) => ({
1089
+ connection: { ...s.connection, sendError: message }
904
1090
  })),
905
1091
  setReconnectFailed: () => set((s) => ({
906
1092
  connection: { ...s.connection, reconnectFailed: true }
@@ -988,8 +1174,13 @@ function createAgentStore() {
988
1174
  mergedEvents = snapshotEvents;
989
1175
  } else {
990
1176
  const existingIds = new Set(existing.map((e) => e.id));
1177
+ const snapById = new Map(snapshotEvents.map((e) => [e.id, e]));
1178
+ const mergedExisting = existing.map((e) => {
1179
+ const snap = snapById.get(e.id);
1180
+ return snap ? mergeThreadEventById(e, snap) : e;
1181
+ });
991
1182
  const newFromSnapshot = snapshotEvents.filter((e) => !existingIds.has(e.id));
992
- mergedEvents = newFromSnapshot.length > 0 ? [...existing, ...newFromSnapshot] : existing;
1183
+ mergedEvents = newFromSnapshot.length > 0 ? [...mergedExisting, ...newFromSnapshot] : mergedExisting;
993
1184
  }
994
1185
  const optimistic = { ...s.optimistic };
995
1186
  const optimisticKeys = { ...s.optimisticKeys };
@@ -1013,7 +1204,8 @@ function createAgentStore() {
1013
1204
  const appends = [];
1014
1205
  for (const e of newEvents) {
1015
1206
  if (existingIds.has(e.id)) {
1016
- updates.set(e.id, e);
1207
+ const prev = existing.find((x) => x.id === e.id);
1208
+ updates.set(e.id, mergeThreadEventById(prev, e));
1017
1209
  } else {
1018
1210
  appends.push(e);
1019
1211
  }
@@ -1027,6 +1219,10 @@ function createAgentStore() {
1027
1219
  reconcileEvents: (threadId, newEvents, resolvedClientEventIds) => set((s) => {
1028
1220
  const existing = s.events[threadId] ?? [];
1029
1221
  const existingIds = new Set(existing.map((e) => e.id));
1222
+ const mergedExisting = newEvents.length > 0 ? existing.map((e) => {
1223
+ const up = newEvents.find((n) => n.id === e.id);
1224
+ return up ? mergeThreadEventById(e, up) : e;
1225
+ }) : existing;
1030
1226
  const unique = newEvents.filter((e) => !existingIds.has(e.id));
1031
1227
  let optEvents = s.optimistic[threadId] ?? [];
1032
1228
  let optKeys = s.optimisticKeys[threadId] ?? [];
@@ -1040,7 +1236,7 @@ function createAgentStore() {
1040
1236
  }
1041
1237
  }
1042
1238
  return {
1043
- events: { ...s.events, [threadId]: [...existing, ...unique] },
1239
+ events: { ...s.events, [threadId]: [...mergedExisting, ...unique] },
1044
1240
  optimistic: { ...s.optimistic, [threadId]: optEvents },
1045
1241
  optimisticKeys: { ...s.optimisticKeys, [threadId]: optKeys }
1046
1242
  };
@@ -1090,7 +1286,10 @@ function createAgentStore() {
1090
1286
  const subscriptions = new Set(s.subscriptions);
1091
1287
  subscriptions.add(threadId);
1092
1288
  const loadingThreads = new Set(s.loadingThreads);
1093
- loadingThreads.add(threadId);
1289
+ const alreadyHadEvents = (s.events[threadId]?.length ?? 0) > 0;
1290
+ if (!alreadyHadEvents) {
1291
+ loadingThreads.add(threadId);
1292
+ }
1094
1293
  return { subscriptions, loadingThreads };
1095
1294
  }),
1096
1295
  removeSubscription: (threadId) => set((s) => {
@@ -1234,6 +1433,9 @@ function AgentProvider({
1234
1433
  react.useEffect(() => {
1235
1434
  clientRef.current?.setUploadUrl(uploadUrl);
1236
1435
  }, [uploadUrl]);
1436
+ react.useEffect(() => {
1437
+ clientRef.current?.setUploadAgentId(agentId);
1438
+ }, [agentId]);
1237
1439
  const identityIdsKey = identityIds?.join(",") ?? "";
1238
1440
  react.useEffect(() => {
1239
1441
  if (!url || !agentId) return;
@@ -1403,9 +1605,13 @@ function useConnection() {
1403
1605
  const { client } = useAgentContext();
1404
1606
  const status = useStore((s) => s.connection.status);
1405
1607
  const error = useStore((s) => s.connection.error);
1608
+ const sendError = useStore((s) => s.connection.sendError);
1406
1609
  const reconnectFailed = useStore((s) => s.connection.reconnectFailed);
1407
1610
  const reconnect = react.useCallback(() => client.retry(), [client]);
1408
- return { status, error, reconnectFailed, reconnect };
1611
+ const dismissSendError = react.useCallback(() => {
1612
+ client.clearSendError();
1613
+ }, [client]);
1614
+ return { status, error, sendError, dismissSendError, reconnectFailed, reconnect };
1409
1615
  }
1410
1616
  function useFeedback(targetId, targetType = "event") {
1411
1617
  const { client } = useAgentContext();
@@ -1534,11 +1740,15 @@ function useFormFileUpload() {
1534
1740
  setIsUploading(true);
1535
1741
  setError(null);
1536
1742
  try {
1743
+ const aid = (params.agentId || "").trim();
1744
+ if (!aid) {
1745
+ throw new Error("agentId is required for upload");
1746
+ }
1537
1747
  const formData = new FormData();
1538
1748
  formData.append("file", params.file);
1539
1749
  formData.append("field_id", params.fieldId);
1540
1750
  formData.append("source", "chat");
1541
- formData.append("agent_id", params.agentId);
1751
+ formData.append("agent_id", aid);
1542
1752
  formData.append("run_id", params.runId);
1543
1753
  formData.append("thread_id", params.threadId);
1544
1754
  const response = await fetch(params.uploadUrl, {
@@ -1690,11 +1900,11 @@ function useUpload() {
1690
1900
  const [isUploading, setIsUploading] = react.useState(false);
1691
1901
  const activeCountRef = react.useRef(0);
1692
1902
  const upload = react.useCallback(
1693
- async (file) => {
1903
+ async (file, options) => {
1694
1904
  activeCountRef.current++;
1695
1905
  setIsUploading(true);
1696
1906
  try {
1697
- return await client.upload(file);
1907
+ return await client.upload(file, options);
1698
1908
  } finally {
1699
1909
  activeCountRef.current--;
1700
1910
  if (activeCountRef.current === 0) {
@@ -1714,6 +1924,7 @@ exports.isSettingsFieldGroup = isSettingsFieldGroup;
1714
1924
  exports.toFormElement = toFormElement;
1715
1925
  exports.toFormEventData = toFormEventData;
1716
1926
  exports.toFormResponseEventData = toFormResponseEventData;
1927
+ exports.useAgentContext = useAgentContext;
1717
1928
  exports.useAnalytics = useAnalytics;
1718
1929
  exports.useAudioRecorder = useAudioRecorder;
1719
1930
  exports.useConnection = useConnection;