@ukiahinsure/a2ui-react-adapter 0.1.17 → 0.1.19

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.d.ts CHANGED
@@ -1,9 +1,23 @@
1
- import { A as A2UIClientAdapter, a as A2UISurfaceMetadata, b as A2UISessionController, c as A2UIRoomLike } from './session-BcHSjUlD.js';
2
- export { d as A2UIActionDeliveryStatus, e as A2UIActionResult, f as A2UIActionState, g as A2UICapabilityEnvelope, h as A2UIClientActionEnvelope, i as A2UIClientAdapterOptions, j as A2UIClientErrorEnvelope, k as A2UIClientErrorEvent, l as A2UIEditingSnapshot, m as A2UIFieldControl, n as A2UIFieldDescriptor, o as A2UIFieldInteractionField, p as A2UIFieldInteractionGroup, q as A2UIFieldValue, r as A2UIPendingAction, s as A2UIRendererActionEvent, t as A2UIServerEnvelope, u as A2UISessionControllerOptions, v as A2UISessionSnapshot, w as A2UISessionStatus, x as A2UIStreamParticipant, y as A2UISurfaceStructure, z as A2UITabDescriptor, B as A2UITrustedServerParticipant, C as A2UI_CAPABILITIES_TOPIC, D as A2UI_CLIENT_TOPIC, E as A2UI_PROTOCOL_VERSION, F as A2UI_SERVER_TOPIC, G as AckEnvelope, H as AckFieldError, I as AdapterSurface, J as CLIENT_ACTIONS, K as CLIENT_ERROR_CODES, L as ClientAction, M as ClientErrorCode, N as ENVELOPE_VERSION, O as MAX_ENVELOPE_BYTES, P as ParticipantRole, S as SectionNavigation, Q as SnapshotEnvelope, R as SurfaceUpdateEnvelope } from './session-BcHSjUlD.js';
1
+ import { A as A2UIClientAdapter, a as A2UISurfaceMetadata, b as A2UISessionController, c as A2UIRoomLike } from './session-BnvcVx-k.js';
2
+ export { d as A2UIActionDeliveryStatus, e as A2UIActionResult, f as A2UIActionState, g as A2UICapabilityEnvelope, h as A2UIClientActionEnvelope, i as A2UIClientAdapterOptions, j as A2UIClientErrorEnvelope, k as A2UIClientErrorEvent, l as A2UIEditingSnapshot, m as A2UIFieldControl, n as A2UIFieldDescriptor, o as A2UIFieldInteractionField, p as A2UIFieldInteractionGroup, q as A2UIFieldUpdateEvent, r as A2UIFieldValue, s as A2UIPendingAction, t as A2UIRendererActionEvent, u as A2UIServerEnvelope, v as A2UISessionControllerOptions, w as A2UISessionSnapshot, x as A2UISessionStatus, y as A2UIStreamParticipant, z as A2UISurfaceStructure, B as A2UITabDescriptor, C as A2UITrustedServerParticipant, D as A2UI_CAPABILITIES_TOPIC, E as A2UI_CLIENT_TOPIC, F as A2UI_PROTOCOL_VERSION, G as A2UI_SERVER_TOPIC, H as AckEnvelope, I as AckFieldError, J as AdapterSurface, K as CLIENT_ACTIONS, L as CLIENT_ERROR_CODES, M as ClientAction, N as ClientErrorCode, O as ENVELOPE_VERSION, P as MAX_ENVELOPE_BYTES, Q as ParticipantRole, S as SectionNavigation, R as SnapshotEnvelope, T as SurfaceUpdateEnvelope } from './session-BnvcVx-k.js';
3
3
  import { ReactNode } from 'react';
4
4
 
5
5
  /** Accessible host around the official A2UI v0.9.1 React surface. */
6
6
 
7
+ /**
8
+ * The agent changed what the form shows: it filled or corrected field values
9
+ * (`field-value`), or moved the conversation to a new current field group
10
+ * (`current-group`). `element` is the rendered container for the first
11
+ * affected field (the whole choice group or date editor, not one option), so
12
+ * hosts can scroll to it for any control type.
13
+ */
14
+ interface A2UIAgentUpdateEvent {
15
+ reason: "field-value" | "current-group";
16
+ surfaceId: string;
17
+ fields: readonly string[];
18
+ groupId?: string;
19
+ element?: HTMLElement;
20
+ }
7
21
  interface A2UISurfaceHostProps {
8
22
  adapter: A2UIClientAdapter;
9
23
  /** Render a specific surface; defaults to the adapter's current surface. */
@@ -25,8 +39,10 @@ interface A2UISurfaceHostProps {
25
39
  noSurfaceFallback?: ReactNode;
26
40
  /** Shown when the surface fails to render. */
27
41
  errorFallback?: ReactNode;
42
+ /** Called after the DOM reflects an agent-driven field or group change. */
43
+ onAgentUpdate?: (event: A2UIAgentUpdateEvent) => void;
28
44
  }
29
- declare function A2UISurfaceHost({ adapter, surfaceId, surfaceMetadata, sessionController, hostId, ariaLabel, disabled, busy, invalidFields, validationSummaryId, noSurfaceFallback, errorFallback, }: A2UISurfaceHostProps): ReactNode;
45
+ declare function A2UISurfaceHost({ adapter, surfaceId, surfaceMetadata, sessionController, hostId, ariaLabel, disabled, busy, invalidFields, validationSummaryId, noSurfaceFallback, errorFallback, onAgentUpdate, }: A2UISurfaceHostProps): ReactNode;
30
46
 
31
47
  /** Explicit room-ownership helper backed by backend-issued runtime material. */
32
48
 
@@ -48,4 +64,4 @@ interface A2UIJoinedRoom {
48
64
  */
49
65
  declare function joinA2UIRoom(tokenProvider: A2UITokenProvider): Promise<A2UIJoinedRoom>;
50
66
 
51
- export { A2UIClientAdapter, type A2UIJoinedRoom, A2UIRoomLike, type A2UIRuntimeMaterial, A2UISessionController, A2UISurfaceHost, type A2UISurfaceHostProps, A2UISurfaceMetadata, type A2UITokenProvider, joinA2UIRoom };
67
+ export { type A2UIAgentUpdateEvent, A2UIClientAdapter, type A2UIJoinedRoom, A2UIRoomLike, type A2UIRuntimeMaterial, A2UISessionController, A2UISurfaceHost, type A2UISurfaceHostProps, A2UISurfaceMetadata, type A2UITokenProvider, joinA2UIRoom };
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-AOBRTDAU.js";
11
11
 
12
12
  // src/adapter.ts
13
- import { basicCatalog } from "@a2ui/react/v0_9";
13
+ import { basicCatalog as basicCatalog2 } from "@a2ui/react/v0_9";
14
14
  import {
15
15
  A2uiError,
16
16
  Catalog,
@@ -18,11 +18,44 @@ import {
18
18
  MessageProcessor
19
19
  } from "@a2ui/web_core/v0_9";
20
20
 
21
+ // src/HospitalChoice.tsx
22
+ import { useId } from "react";
23
+ import { basicCatalog, createComponentImplementation } from "@a2ui/react/v0_9";
24
+ import { ChoicePickerApi } from "@a2ui/web_core/v0_9/basic_catalog";
25
+ import { jsx, jsxs } from "react/jsx-runtime";
26
+ var OriginalChoice = basicCatalog.components.get("ChoicePicker").render;
27
+ var HospitalChoice = createComponentImplementation(ChoicePickerApi, ({ props, context, buildChild }) => {
28
+ const id = useId();
29
+ if (props.label !== "hospital_preference") {
30
+ return /* @__PURE__ */ jsx(OriginalChoice, { context, buildChild });
31
+ }
32
+ const selected = Array.isArray(props.value) ? props.value[0] ?? "" : "";
33
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
34
+ /* @__PURE__ */ jsx("label", { htmlFor: id, children: "Hospital preference" }),
35
+ /* @__PURE__ */ jsxs(
36
+ "select",
37
+ {
38
+ id,
39
+ "data-a2ui-field": "hospital_preference",
40
+ value: selected,
41
+ required: true,
42
+ style: { padding: "0.5rem", border: "var(--a2ui-border)", borderRadius: "var(--a2ui-border-radius)" },
43
+ onChange: (event) => props.setValue(event.currentTarget.value ? [event.currentTarget.value] : []),
44
+ children: [
45
+ /* @__PURE__ */ jsx("option", { value: "", children: "Choose Prefer or Avoid" }),
46
+ /* @__PURE__ */ jsx("option", { value: "Prefer", children: "Prefer" }),
47
+ /* @__PURE__ */ jsx("option", { value: "Avoid", children: "Avoid" })
48
+ ]
49
+ }
50
+ )
51
+ ] });
52
+ });
53
+
21
54
  // src/DateTimeInput.tsx
22
- import { useId, useLayoutEffect, useRef, useState } from "react";
23
- import { createComponentImplementation } from "@a2ui/react/v0_9";
55
+ import { useId as useId2, useLayoutEffect, useRef, useState } from "react";
56
+ import { createComponentImplementation as createComponentImplementation2 } from "@a2ui/react/v0_9";
24
57
  import { DateTimeInputApi } from "@a2ui/web_core/v0_9/basic_catalog";
25
- import { jsx, jsxs } from "react/jsx-runtime";
58
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
26
59
  var inputStyle = {
27
60
  backgroundColor: "var(--a2ui-datetimeinput-background, var(--a2ui-color-input, #fff))",
28
61
  color: "var(--a2ui-datetimeinput-color, var(--a2ui-color-on-input, #333))",
@@ -50,7 +83,7 @@ function displayDate(value) {
50
83
  return iso ? `${iso.slice(5, 7)}/${iso.slice(8, 10)}/${iso.slice(0, 4)}` : value;
51
84
  }
52
85
  function DateOnlyInput(props) {
53
- const id = useId();
86
+ const id = useId2();
54
87
  const [draft, setDraft] = useState(() => displayDate(props.value || ""));
55
88
  const [pickerOpen, setPickerOpen] = useState(false);
56
89
  const published = useRef(props.value || "");
@@ -76,10 +109,10 @@ function DateOnlyInput(props) {
76
109
  published.current = value;
77
110
  props.setValue(value);
78
111
  };
79
- return /* @__PURE__ */ jsxs("div", { "data-a2ui-date-editor": "true", style: { display: "flex", flexDirection: "column", gap: "var(--a2ui-spacing-xs, 0.25rem)" }, children: [
80
- props.label && /* @__PURE__ */ jsx("label", { htmlFor: id, style: labelStyle, children: props.label }),
81
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "0.25rem", position: "relative" }, children: [
82
- /* @__PURE__ */ jsx(
112
+ return /* @__PURE__ */ jsxs2("div", { "data-a2ui-date-editor": "true", style: { display: "flex", flexDirection: "column", gap: "var(--a2ui-spacing-xs, 0.25rem)" }, children: [
113
+ props.label && /* @__PURE__ */ jsx2("label", { htmlFor: id, style: labelStyle, children: props.label }),
114
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "0.25rem", position: "relative" }, children: [
115
+ /* @__PURE__ */ jsx2(
83
116
  "input",
84
117
  {
85
118
  ref: inputRef,
@@ -97,7 +130,7 @@ function DateOnlyInput(props) {
97
130
  style: { ...inputStyle, minWidth: 0, flex: 1 }
98
131
  }
99
132
  ),
100
- /* @__PURE__ */ jsx(
133
+ /* @__PURE__ */ jsx2(
101
134
  "button",
102
135
  {
103
136
  type: "button",
@@ -117,7 +150,7 @@ function DateOnlyInput(props) {
117
150
  children: "\u25A6"
118
151
  }
119
152
  ),
120
- /* @__PURE__ */ jsx(
153
+ /* @__PURE__ */ jsx2(
121
154
  "input",
122
155
  {
123
156
  ref: pickerRef,
@@ -140,15 +173,15 @@ function DateOnlyInput(props) {
140
173
  ] });
141
174
  }
142
175
  function NativeTimeInput(props) {
143
- const id = useId();
176
+ const id = useId2();
144
177
  const inputRef = useRef(null);
145
178
  const initialValue = useRef(props.value || "");
146
179
  useLayoutEffect(() => {
147
180
  if (inputRef.current && inputRef.current.value !== (props.value || "")) inputRef.current.value = props.value || "";
148
181
  }, [props.value]);
149
- return /* @__PURE__ */ jsxs("div", { children: [
150
- props.label && /* @__PURE__ */ jsx("label", { htmlFor: id, style: labelStyle, children: props.label }),
151
- /* @__PURE__ */ jsx(
182
+ return /* @__PURE__ */ jsxs2("div", { children: [
183
+ props.label && /* @__PURE__ */ jsx2("label", { htmlFor: id, style: labelStyle, children: props.label }),
184
+ /* @__PURE__ */ jsx2(
152
185
  "input",
153
186
  {
154
187
  ref: inputRef,
@@ -163,19 +196,19 @@ function NativeTimeInput(props) {
163
196
  )
164
197
  ] });
165
198
  }
166
- var DateTimeInput = createComponentImplementation(
199
+ var DateTimeInput = createComponentImplementation2(
167
200
  DateTimeInputApi,
168
- ({ props }) => props.enableDate && !props.enableTime ? /* @__PURE__ */ jsx(DateOnlyInput, { ...props }) : /* @__PURE__ */ jsx(NativeTimeInput, { ...props })
201
+ ({ props }) => props.enableDate && !props.enableTime ? /* @__PURE__ */ jsx2(DateOnlyInput, { ...props }) : /* @__PURE__ */ jsx2(NativeTimeInput, { ...props })
169
202
  );
170
203
 
171
204
  // src/adapter.ts
172
205
  var editableDateCatalog = new Catalog(
173
- basicCatalog.id,
174
- [...basicCatalog.components.values()].map(
175
- (component) => component.name === DateTimeInput.name ? DateTimeInput : component
206
+ basicCatalog2.id,
207
+ [...basicCatalog2.components.values()].map(
208
+ (component) => component.name === DateTimeInput.name ? DateTimeInput : component.name === HospitalChoice.name ? HospitalChoice : component
176
209
  ),
177
- [...basicCatalog.functions.values()],
178
- basicCatalog.themeSchema
210
+ [...basicCatalog2.functions.values()],
211
+ basicCatalog2.themeSchema
179
212
  );
180
213
  var RENDERER_NAME = "a2ui_react_adapter";
181
214
  var RENDERER_VERSION = "0.1.0";
@@ -187,6 +220,7 @@ var A2UIClientAdapter = class {
187
220
  #listeners = /* @__PURE__ */ new Set();
188
221
  #actionListeners = /* @__PURE__ */ new Set();
189
222
  #errorListeners = /* @__PURE__ */ new Set();
223
+ #fieldUpdateListeners = /* @__PURE__ */ new Set();
190
224
  #surfaceOrder = [];
191
225
  #structureBySurface = /* @__PURE__ */ new Map();
192
226
  #persistedListRowsByPath = /* @__PURE__ */ new Map();
@@ -203,7 +237,7 @@ var A2UIClientAdapter = class {
203
237
  }
204
238
  /** Catalog ids this adapter will announce in capability envelopes. */
205
239
  get supportedCatalogIds() {
206
- return [basicCatalog.id];
240
+ return [basicCatalog2.id];
207
241
  }
208
242
  get lastSeq() {
209
243
  return this.#lastSeq;
@@ -387,6 +421,10 @@ var A2UIClientAdapter = class {
387
421
  this.#errorListeners.add(listener);
388
422
  return () => this.#errorListeners.delete(listener);
389
423
  };
424
+ subscribeFieldUpdates = (listener) => {
425
+ this.#fieldUpdateListeners.add(listener);
426
+ return () => this.#fieldUpdateListeners.delete(listener);
427
+ };
390
428
  /** Monotonic change counter for `useSyncExternalStore`. */
391
429
  getVersion = () => this.#version;
392
430
  dispose() {
@@ -403,6 +441,7 @@ var A2UIClientAdapter = class {
403
441
  this.#listeners.clear();
404
442
  this.#actionListeners.clear();
405
443
  this.#errorListeners.clear();
444
+ this.#fieldUpdateListeners.clear();
406
445
  }
407
446
  #applySurfaceEnvelope(envelope) {
408
447
  const validated = A2uiMessageListSchema.safeParse(envelope.messages);
@@ -469,6 +508,12 @@ var A2UIClientAdapter = class {
469
508
  );
470
509
  return false;
471
510
  }
511
+ const changedFields = envelope.kind === "snapshot" ? [] : changedFieldNames(
512
+ previous,
513
+ candidate,
514
+ envelope.surfaceId,
515
+ nextStructure.get(envelope.surfaceId)
516
+ );
472
517
  this.#processor = candidate;
473
518
  this.#surfaceOrder = [...candidate.model.surfacesMap.keys()];
474
519
  this.#structureBySurface = nextStructure;
@@ -485,8 +530,20 @@ var A2UIClientAdapter = class {
485
530
  );
486
531
  previous.model.dispose();
487
532
  this.#notify();
533
+ if (changedFields.length > 0) {
534
+ this.#emitFieldUpdate({
535
+ surfaceId: envelope.surfaceId,
536
+ fields: changedFields
537
+ });
538
+ }
488
539
  return true;
489
540
  }
541
+ #emitFieldUpdate(event) {
542
+ this.#options.onFieldUpdate?.(event);
543
+ for (const listener of this.#fieldUpdateListeners) {
544
+ listener(event);
545
+ }
546
+ }
490
547
  #createProcessor() {
491
548
  return new MessageProcessor(
492
549
  [editableDateCatalog],
@@ -1676,6 +1733,25 @@ function cloneJsonArray(value) {
1676
1733
  function isFieldValue(value) {
1677
1734
  return value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value);
1678
1735
  }
1736
+ function changedFieldNames(previous, candidate, surfaceId, structure) {
1737
+ const before = previous.model.getSurface(surfaceId);
1738
+ const after = candidate.model.getSurface(surfaceId);
1739
+ if (before === void 0 || after === void 0 || structure === void 0) {
1740
+ return [];
1741
+ }
1742
+ const fields = /* @__PURE__ */ new Set();
1743
+ for (const { field } of structure.fieldsByComponent.values()) {
1744
+ const path = fieldPointer(field);
1745
+ const next = after.dataModel.get(path);
1746
+ if (hasFieldValue(next) && !fieldValueEquivalent(before.dataModel.get(path), next)) {
1747
+ fields.add(field);
1748
+ }
1749
+ }
1750
+ return [...fields];
1751
+ }
1752
+ function hasFieldValue(value) {
1753
+ return Array.isArray(value) ? value.length > 0 : value !== void 0 && value !== null && value !== "";
1754
+ }
1679
1755
  function fieldValueEquivalent(left, right) {
1680
1756
  if (Array.isArray(left) && Array.isArray(right)) {
1681
1757
  return left.length === right.length && left.every((value, index) => Object.is(value, right[index]));
@@ -1714,13 +1790,14 @@ function classifyProcessingError(error) {
1714
1790
  // src/SurfaceHost.tsx
1715
1791
  import {
1716
1792
  Component,
1717
- useId as useId2,
1793
+ useEffect,
1794
+ useId as useId3,
1718
1795
  useLayoutEffect as useLayoutEffect2,
1719
1796
  useRef as useRef2,
1720
1797
  useSyncExternalStore
1721
1798
  } from "react";
1722
1799
  import { A2uiSurface } from "@a2ui/react/v0_9";
1723
- import { jsx as jsx2 } from "react/jsx-runtime";
1800
+ import { jsx as jsx3 } from "react/jsx-runtime";
1724
1801
  function A2UISurfaceHost({
1725
1802
  adapter,
1726
1803
  surfaceId,
@@ -1733,7 +1810,8 @@ function A2UISurfaceHost({
1733
1810
  invalidFields = [],
1734
1811
  validationSummaryId,
1735
1812
  noSurfaceFallback,
1736
- errorFallback
1813
+ errorFallback,
1814
+ onAgentUpdate
1737
1815
  }) {
1738
1816
  const version = useSyncExternalStore(
1739
1817
  adapter.subscribe,
@@ -1747,17 +1825,31 @@ function A2UISurfaceHost({
1747
1825
  readSessionSnapshot,
1748
1826
  readSessionSnapshot
1749
1827
  );
1750
- const generatedId = useId2().replaceAll(":", "");
1828
+ const generatedId = useId3().replaceAll(":", "");
1751
1829
  const rootRef = useRef2(null);
1752
1830
  const lastFocusedState = useRef2(void 0);
1753
1831
  const lastViewedSection = useRef2(void 0);
1754
1832
  const lastValidationKey = useRef2("");
1833
+ const pendingFieldUpdates = useRef2(/* @__PURE__ */ new Map());
1834
+ const lastCurrentGroupId = useRef2(void 0);
1835
+ const onAgentUpdateRef = useRef2(onAgentUpdate);
1836
+ onAgentUpdateRef.current = onAgentUpdate;
1755
1837
  const resolvedSurfaceMetadata = surfaceMetadata ?? controllerSnapshot?.surface ?? null;
1756
1838
  const editing = controllerSnapshot?.editing ?? editingForSurface(resolvedSurfaceMetadata);
1757
1839
  const surface = surfaceId === void 0 ? adapter.currentSurface : adapter.getSurface(surfaceId);
1758
1840
  const structure = surface === void 0 ? EMPTY_STRUCTURE : adapter.getSurfaceStructure(surface.id);
1759
1841
  const focusKey = surface === void 0 ? void 0 : `${surface.id}:${resolvedSurfaceMetadata?.activeStateId ?? "surface"}`;
1760
1842
  const frameId = hostId ?? `a2ui-surface-${generatedId}`;
1843
+ useEffect(
1844
+ () => adapter.subscribeFieldUpdates((event) => {
1845
+ const pending = pendingFieldUpdates.current.get(event.surfaceId) ?? /* @__PURE__ */ new Set();
1846
+ for (const field of event.fields) {
1847
+ pending.add(field);
1848
+ }
1849
+ pendingFieldUpdates.current.set(event.surfaceId, pending);
1850
+ }),
1851
+ [adapter]
1852
+ );
1761
1853
  useLayoutEffect2(() => {
1762
1854
  const root = rootRef.current;
1763
1855
  if (root === null || surface === void 0) {
@@ -1800,6 +1892,42 @@ function A2UISurfaceHost({
1800
1892
  ),
1801
1893
  setInteractionDisabled(root, disabled || busy)
1802
1894
  ];
1895
+ reportAgentUpdates();
1896
+ };
1897
+ const reportAgentUpdates = () => {
1898
+ const changedFields = [
1899
+ ...pendingFieldUpdates.current.get(surface.id) ?? []
1900
+ ];
1901
+ pendingFieldUpdates.current.clear();
1902
+ const currentGroup = resolvedSurfaceMetadata?.fieldInteractions.find(
1903
+ (group) => group.mode === "current"
1904
+ );
1905
+ const previousGroupId = lastCurrentGroupId.current;
1906
+ if (currentGroup !== void 0) {
1907
+ lastCurrentGroupId.current = currentGroup.groupId;
1908
+ }
1909
+ const report = onAgentUpdateRef.current;
1910
+ if (report === void 0) {
1911
+ return;
1912
+ }
1913
+ if (changedFields.length > 0) {
1914
+ report({
1915
+ reason: "field-value",
1916
+ surfaceId: surface.id,
1917
+ fields: changedFields,
1918
+ element: agentUpdateElement(root, changedFields, structure.fields)
1919
+ });
1920
+ }
1921
+ if (currentGroup !== void 0 && previousGroupId !== void 0 && currentGroup.groupId !== previousGroupId) {
1922
+ const fields = currentGroup.fields.map((binding) => binding.field);
1923
+ report({
1924
+ reason: "current-group",
1925
+ surfaceId: surface.id,
1926
+ fields,
1927
+ groupId: currentGroup.groupId,
1928
+ element: agentUpdateElement(root, fields, structure.fields)
1929
+ });
1930
+ }
1803
1931
  };
1804
1932
  const scheduleControlRefresh = () => {
1805
1933
  queueMicrotask(refreshControls);
@@ -1860,9 +1988,9 @@ function A2UISurfaceHost({
1860
1988
  version
1861
1989
  ]);
1862
1990
  if (surface === void 0) {
1863
- return noSurfaceFallback ?? /* @__PURE__ */ jsx2("div", { "data-a2ui-host": "no-surface", role: "status", "aria-live": "polite", children: "Your conversation continues by voice." });
1991
+ return noSurfaceFallback ?? /* @__PURE__ */ jsx3("div", { "data-a2ui-host": "no-surface", role: "status", "aria-live": "polite", children: "Your conversation continues by voice." });
1864
1992
  }
1865
- return /* @__PURE__ */ jsx2(
1993
+ return /* @__PURE__ */ jsx3(
1866
1994
  "div",
1867
1995
  {
1868
1996
  ref: rootRef,
@@ -1875,13 +2003,13 @@ function A2UISurfaceHost({
1875
2003
  "aria-busy": busy || void 0,
1876
2004
  "aria-disabled": disabled || busy || void 0,
1877
2005
  tabIndex: -1,
1878
- children: /* @__PURE__ */ jsx2(
2006
+ children: /* @__PURE__ */ jsx3(
1879
2007
  SurfaceErrorBoundary,
1880
2008
  {
1881
2009
  adapter,
1882
2010
  surface,
1883
- fallback: errorFallback ?? /* @__PURE__ */ jsx2("div", { "data-a2ui-host": "render-error", role: "alert", children: "This step can't be shown right now. Please continue by voice." }),
1884
- children: /* @__PURE__ */ jsx2(A2uiSurface, { surface })
2011
+ fallback: errorFallback ?? /* @__PURE__ */ jsx3("div", { "data-a2ui-host": "render-error", role: "alert", children: "This step can't be shown right now. Please continue by voice." }),
2012
+ children: /* @__PURE__ */ jsx3(A2uiSurface, { surface })
1885
2013
  },
1886
2014
  surface.id
1887
2015
  )
@@ -1924,6 +2052,33 @@ function focusProgressTarget(root, metadata, invalidFields) {
1924
2052
  });
1925
2053
  }
1926
2054
  }
2055
+ function agentUpdateElement(root, fields, descriptors) {
2056
+ const controls = [
2057
+ ...root.querySelectorAll("[data-a2ui-field]")
2058
+ ];
2059
+ for (const field of fields) {
2060
+ const control = controls.find(
2061
+ (candidate) => candidate.dataset.a2uiField === field
2062
+ );
2063
+ if (control !== void 0) {
2064
+ return control.closest("[data-a2ui-date-editor]") ?? control.closest('[role="radiogroup"]') ?? control;
2065
+ }
2066
+ const descriptor = descriptors.find(
2067
+ (candidate) => candidate.field === field
2068
+ );
2069
+ const labels = /* @__PURE__ */ new Set([displayFieldLabel(field)]);
2070
+ if (descriptor !== void 0) {
2071
+ labels.add(descriptor.label);
2072
+ }
2073
+ const label = [
2074
+ ...root.querySelectorAll("label, strong, legend")
2075
+ ].find((candidate) => labels.has(candidate.textContent?.trim() ?? ""));
2076
+ if (label?.parentElement != null && root.contains(label.parentElement)) {
2077
+ return label.parentElement;
2078
+ }
2079
+ }
2080
+ return void 0;
2081
+ }
1927
2082
  function isControlDisabled(control) {
1928
2083
  return control.getAttribute("aria-disabled") === "true" || "disabled" in control && control.disabled === true;
1929
2084
  }
@@ -2175,7 +2330,7 @@ var SurfaceErrorBoundary = class extends Component {
2175
2330
  }
2176
2331
  render() {
2177
2332
  if (this.state.failedSurfaceId !== void 0) {
2178
- return /* @__PURE__ */ jsx2(
2333
+ return /* @__PURE__ */ jsx3(
2179
2334
  "div",
2180
2335
  {
2181
2336
  "data-a2ui-error-boundary": "true",
@@ -2393,7 +2548,7 @@ function blockInvalidActionControls(root) {
2393
2548
  };
2394
2549
  }
2395
2550
  function firstInvalidInput(root) {
2396
- return [...root.querySelectorAll("input[data-a2ui-field]")].filter((input) => input.type !== "radio" && !isControlDisabled(input)).find((input) => !input.checkValidity());
2551
+ return [...root.querySelectorAll("input[data-a2ui-field], select[data-a2ui-field]")].filter((input) => input.type !== "radio" && !isControlDisabled(input)).find((input) => !input.checkValidity());
2397
2552
  }
2398
2553
  function findFieldControls(root, field) {
2399
2554
  const labels = [...root.querySelectorAll("label")];
@@ -2867,11 +3022,23 @@ function renderSavedLoopEditInputs(editButton, row, orderedFields, summaryFields
2867
3022
  continue;
2868
3023
  }
2869
3024
  let input = value.querySelector(
2870
- "input[data-a2ui-loop-edit-input='true']"
3025
+ "[data-a2ui-loop-edit-input='true']"
2871
3026
  );
2872
3027
  if (input === null) {
2873
- input = row.ownerDocument.createElement("input");
2874
- input.type = "text";
3028
+ if (fieldName === "hospital_preference") {
3029
+ const select = row.ownerDocument.createElement("select");
3030
+ for (const choice of ["", "Prefer", "Avoid"]) {
3031
+ const option = row.ownerDocument.createElement("option");
3032
+ option.value = choice;
3033
+ option.textContent = choice || "Choose Prefer or Avoid";
3034
+ select.appendChild(option);
3035
+ }
3036
+ select.required = true;
3037
+ input = select;
3038
+ } else {
3039
+ input = row.ownerDocument.createElement("input");
3040
+ input.type = "text";
3041
+ }
2875
3042
  input.name = fieldName;
2876
3043
  input.setAttribute("aria-label", displayFieldLabel(fieldName));
2877
3044
  input.dataset.a2uiLoopEditInput = "true";
@@ -2897,7 +3064,7 @@ function renderSavedLoopEditInputs(editButton, row, orderedFields, summaryFields
2897
3064
  setText(editButton, "Save");
2898
3065
  if (focusFirstInput) {
2899
3066
  row.querySelector(
2900
- "input[data-a2ui-loop-edit-input='true']"
3067
+ "[data-a2ui-loop-edit-input='true']"
2901
3068
  )?.focus();
2902
3069
  }
2903
3070
  }
@@ -2919,7 +3086,7 @@ function savedLoopRowInputValues(orderedFields, summaryFields) {
2919
3086
  orderedFields.forEach((field, index) => {
2920
3087
  const fieldName = summaryFields[index];
2921
3088
  const input = field.querySelector(
2922
- "input[data-a2ui-loop-edit-input='true']"
3089
+ "[data-a2ui-loop-edit-input='true']"
2923
3090
  );
2924
3091
  const value = field.querySelector(
2925
3092
  "[data-a2ui-loop-cell='value']"
@@ -3001,7 +3168,7 @@ function normalizedLoopSummaryFields(fields) {
3001
3168
  if (hasPharmacyFields) {
3002
3169
  return pharmacyFields.filter((field) => withoutInternal.includes(field));
3003
3170
  }
3004
- const hospitalFields = ["hospital_name", "hospital_city_state"];
3171
+ const hospitalFields = ["hospital_name", "hospital_city_state", "hospital_preference"];
3005
3172
  const hasHospitalFields = hospitalFields.some(
3006
3173
  (field) => withoutInternal.includes(field)
3007
3174
  );
@@ -3117,7 +3284,8 @@ var LOOP_FIELD_LABELS = /* @__PURE__ */ new Map([
3117
3284
  ["pharmacy type", "pharmacy_type"],
3118
3285
  ["pharmacy address", "pharmacy_address"],
3119
3286
  ["hospital name", "hospital_name"],
3120
- ["hospital city state", "hospital_city_state"]
3287
+ ["hospital city state", "hospital_city_state"],
3288
+ ["hospital preference", "hospital_preference"]
3121
3289
  ]);
3122
3290
  function isSavedLoopSummary(element) {
3123
3291
  if (element.children.length > 0) {