@vinaverse/react-native 0.1.0-alpha.4 → 0.1.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,15 @@
1
+ import { useAgentRuntime, useAgentConversation, useAgentName, useAgentLauncher, useAgentFeatures } from '@vinaverse/react/agent';
2
+ export { AgentRuntimeProvider, greetedKey, useAgentConversation, useAgentFeatures, useAgentLauncher, useAgentName, useAgentProfile, useAgentRuntime, useAgentStatus } from '@vinaverse/react/agent';
1
3
  import { FlashList } from '@shopify/flash-list';
2
4
  import { useCopy, useConversationSelector, useStreamingText, formatMoney, formatTimeRange, formatDate, bannedWordsIn, CopyProvider } from '@vinaverse/react';
3
- import { Pressable, ActivityIndicator, Text, View, Image, TextInput, AccessibilityInfo, Linking, useColorScheme, useWindowDimensions, AppState, Platform, KeyboardAvoidingView } from 'react-native';
4
- import { createContext, memo, useCallback, useState, useRef, useMemo, useEffect, useContext } from 'react';
5
+ import { Pressable, ActivityIndicator, Text, View, Image, TextInput, AccessibilityInfo, Linking, useColorScheme, useWindowDimensions, AppState, Platform, KeyboardAvoidingView, Keyboard, Animated } from 'react-native';
6
+ import { readCard } from '@vinaverse/client/agent';
7
+ import { createContext, memo, useMemo, useCallback, useState, useRef, useEffect, useContext } from 'react';
5
8
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
9
  import { contrastRatio, colors, size, motion, radius, space, font, contrastProblems } from '@vinaverse/tokens';
7
10
  import { codePoints, MAX_TEXT, answerProblem } from '@vinaverse/client/conversation';
8
11
 
9
- // src/cards/CardCarousel.tsx
12
+ // src/index.ts
10
13
  var ChatContext = createContext(null);
11
14
  function ChatContextProvider(props) {
12
15
  return /* @__PURE__ */ jsx(ChatContext.Provider, { value: props.value, children: props.children });
@@ -189,6 +192,12 @@ function ratingText(valuePpm, locale) {
189
192
  return value.toFixed(1);
190
193
  }
191
194
  }
195
+ function allowedImage(url, hosts) {
196
+ const safe = safeImage(url);
197
+ if (safe === null || !hosts) return safe;
198
+ const host = /^https:\/\/([^/:?#]+)/i.exec(safe)?.[1]?.toLowerCase();
199
+ return host && hosts.some((h) => h.toLowerCase() === host) ? safe : null;
200
+ }
192
201
  function safeImage(url) {
193
202
  return url && /^https:\/\//i.test(url) ? url : null;
194
203
  }
@@ -336,10 +345,13 @@ function LinksCard(props) {
336
345
  function ListingCard(props) {
337
346
  const card = cardOf(props.card);
338
347
  const { locale, t } = useCopy();
339
- const { slots, timeZone } = useChat();
348
+ const { slots, timeZone, handlers, imagePolicy } = useChat();
340
349
  const { colors: colors2, radius: radius2, space: space2, font: font2 } = useTheme();
341
350
  const [failed, setFailed] = useState(null);
342
- const photoUrl = safeImage(card.images?.[0]?.url ?? card.image_url);
351
+ const photoUrl = allowedImage(
352
+ card.images?.[0]?.url ?? card.image_url,
353
+ imagePolicy?.hosts
354
+ );
343
355
  const hero = photoUrl === failed ? null : photoUrl;
344
356
  const Img = slots.Image ?? Image;
345
357
  const rating = card.rating ? `\u2605 ${ratingText(card.rating.value_ppm, locale)} (${card.rating.count})` : null;
@@ -353,11 +365,55 @@ function ListingCard(props) {
353
365
  const next = card.next_available ? t("nextAvailable", {
354
366
  time: formatTimeRange(card.next_available, void 0, locale, timeZone)
355
367
  }) : null;
368
+ const ref = card.ref;
369
+ const onOpenTarget = handlers.current?.onOpenTarget;
370
+ const open = ref && onOpenTarget && !props.restored ? () => onOpenTarget({ type: ref.type, id: ref.id }, props.card) : null;
356
371
  const photo = {
357
372
  width: "100%",
358
- aspectRatio: 1.6,
373
+ aspectRatio: imagePolicy?.aspectRatio ?? 1.6,
359
374
  borderRadius: radius2.md
360
375
  };
376
+ const top = /* @__PURE__ */ jsxs(Fragment, { children: [
377
+ hero ? /* @__PURE__ */ jsx(
378
+ Img,
379
+ {
380
+ source: { uri: hero },
381
+ onError: () => setFailed(hero),
382
+ style: { ...photo, backgroundColor: colors2.surface },
383
+ accessible: false,
384
+ testID: `vinaverse-photo-${card.id}`
385
+ }
386
+ ) : imagePolicy?.Placeholder ? /* @__PURE__ */ jsx(View, { style: photo, testID: `vinaverse-placeholder-${card.id}`, children: /* @__PURE__ */ jsx(imagePolicy.Placeholder, { title: card.title }) }) : /* @__PURE__ */ jsx(
387
+ View,
388
+ {
389
+ accessible: false,
390
+ importantForAccessibility: "no-hide-descendants",
391
+ testID: `vinaverse-monogram-${card.id}`,
392
+ style: {
393
+ ...photo,
394
+ backgroundColor: colors2.surface,
395
+ alignItems: "center",
396
+ justifyContent: "center"
397
+ },
398
+ children: /* @__PURE__ */ jsx(
399
+ Text,
400
+ {
401
+ style: {
402
+ color: colors2.textMuted,
403
+ fontSize: font2.size.xl,
404
+ fontWeight: "600"
405
+ },
406
+ children: monogram(card.title)
407
+ }
408
+ )
409
+ }
410
+ ),
411
+ /* @__PURE__ */ jsxs(View, { style: { gap: space2.xxs }, children: [
412
+ /* @__PURE__ */ jsx(Title, { numberOfLines: 2, children: card.title }),
413
+ card.subtitle ? /* @__PURE__ */ jsx(Body, { muted: true, children: card.subtitle }) : null,
414
+ rating || price ? /* @__PURE__ */ jsx(Body, { muted: true, children: [rating, price].filter(Boolean).join(" \xB7 ") }) : null
415
+ ] })
416
+ ] });
361
417
  return /* @__PURE__ */ jsxs(
362
418
  CardFrame,
363
419
  {
@@ -365,45 +421,17 @@ function ListingCard(props) {
365
421
  restored: props.restored,
366
422
  testID: `vinaverse-card-${card.id}`,
367
423
  children: [
368
- hero ? /* @__PURE__ */ jsx(
369
- Img,
424
+ open ? /* @__PURE__ */ jsx(
425
+ Pressable,
370
426
  {
371
- source: { uri: hero },
372
- onError: () => setFailed(hero),
373
- style: { ...photo, backgroundColor: colors2.surface },
374
- accessible: false,
375
- testID: `vinaverse-photo-${card.id}`
376
- }
377
- ) : /* @__PURE__ */ jsx(
378
- View,
379
- {
380
- accessible: false,
381
- importantForAccessibility: "no-hide-descendants",
382
- testID: `vinaverse-monogram-${card.id}`,
383
- style: {
384
- ...photo,
385
- backgroundColor: colors2.surface,
386
- alignItems: "center",
387
- justifyContent: "center"
388
- },
389
- children: /* @__PURE__ */ jsx(
390
- Text,
391
- {
392
- style: {
393
- color: colors2.textMuted,
394
- fontSize: font2.size.xl,
395
- fontWeight: "600"
396
- },
397
- children: monogram(card.title)
398
- }
399
- )
427
+ accessibilityRole: "link",
428
+ accessibilityLabel: card.title,
429
+ onPress: open,
430
+ style: { gap: space2.sm },
431
+ testID: `vinaverse-open-${card.id}`,
432
+ children: top
400
433
  }
401
- ),
402
- /* @__PURE__ */ jsxs(View, { style: { gap: space2.xxs }, children: [
403
- /* @__PURE__ */ jsx(Title, { numberOfLines: 2, children: card.title }),
404
- card.subtitle ? /* @__PURE__ */ jsx(Body, { muted: true, children: card.subtitle }) : null,
405
- rating || price ? /* @__PURE__ */ jsx(Body, { muted: true, children: [rating, price].filter(Boolean).join(" \xB7 ") }) : null
406
- ] }),
434
+ ) : top,
407
435
  card.body ? /* @__PURE__ */ jsx(Body, { children: card.body }) : null,
408
436
  /* @__PURE__ */ jsx(Badges, { badges: next ? [next, ...card.badges ?? []] : card.badges }),
409
437
  props.restored ? null : /* @__PURE__ */ jsx(CardActions, { ...props })
@@ -1295,7 +1323,8 @@ var CardView = memo(function CardView2(props) {
1295
1323
  const { card, busy } = props.item;
1296
1324
  const Default = defaultCard(card.kind);
1297
1325
  const Custom = slots.cards?.[card.kind];
1298
- const own = { card, busy, restored: props.item.restored === true };
1326
+ const read = useMemo(() => readCard(card.card), [card]);
1327
+ const own = { card, read, busy, restored: props.item.restored === true };
1299
1328
  return Custom ? /* @__PURE__ */ jsx(Custom, { ...own, Default }) : /* @__PURE__ */ jsx(Default, { ...own });
1300
1329
  });
1301
1330
  var keyOf = (item) => item.key;
@@ -1349,6 +1378,38 @@ var ActivityLine = memo(function ActivityLine2() {
1349
1378
  }
1350
1379
  );
1351
1380
  });
1381
+ function useNativeLifecycle(store) {
1382
+ useEffect(() => {
1383
+ const apply = (state) => store.setForeground(state === "active");
1384
+ apply(AppState.currentState);
1385
+ const subscription = AppState.addEventListener("change", apply);
1386
+ return () => subscription.remove();
1387
+ }, [store]);
1388
+ }
1389
+ function useReducedMotion() {
1390
+ const [reduced, setReduced] = useState(false);
1391
+ useEffect(() => {
1392
+ let live = true;
1393
+ AccessibilityInfo.isReduceMotionEnabled().then(
1394
+ (value) => {
1395
+ if (live) setReduced(value);
1396
+ },
1397
+ () => void 0
1398
+ );
1399
+ const subscription = AccessibilityInfo.addEventListener(
1400
+ "reduceMotionChanged",
1401
+ setReduced
1402
+ );
1403
+ return () => {
1404
+ live = false;
1405
+ subscription.remove();
1406
+ };
1407
+ }, []);
1408
+ return reduced;
1409
+ }
1410
+ function announce(text) {
1411
+ if (text) AccessibilityInfo.announceForAccessibility(text);
1412
+ }
1352
1413
  var Avatar = memo(function Avatar2(props) {
1353
1414
  const { colors: colors2, size: size3, font: font2 } = useTheme();
1354
1415
  const { slots } = useChat();
@@ -1461,37 +1522,6 @@ var ChatHeader = memo(function ChatHeader2() {
1461
1522
  };
1462
1523
  return Header ? /* @__PURE__ */ jsx(Header, { ...props, Default: DefaultHeader }) : /* @__PURE__ */ jsx(DefaultHeader, { ...props });
1463
1524
  });
1464
- var ChatSkeleton = memo(function ChatSkeleton2() {
1465
- const { colors: colors2, radius: radius2, space: space2 } = useTheme();
1466
- const row = (width, end) => /* @__PURE__ */ jsx(
1467
- View,
1468
- {
1469
- style: {
1470
- alignSelf: end ? "flex-end" : "flex-start",
1471
- width,
1472
- height: 40,
1473
- borderRadius: radius2.lg,
1474
- backgroundColor: colors2.surface,
1475
- marginHorizontal: space2.lg,
1476
- marginTop: space2.md
1477
- }
1478
- }
1479
- );
1480
- return /* @__PURE__ */ jsxs(
1481
- View,
1482
- {
1483
- accessible: true,
1484
- accessibilityRole: "progressbar",
1485
- accessibilityState: { busy: true },
1486
- testID: "vinaverse-skeleton",
1487
- children: [
1488
- row("62%", false),
1489
- row("45%", true),
1490
- row("70%", false)
1491
- ]
1492
- }
1493
- );
1494
- });
1495
1525
  function DefaultComposer(props) {
1496
1526
  const { t, direction } = useCopy();
1497
1527
  const { colors: colors2, radius: radius2, space: space2, font: font2, size: size3 } = useTheme();
@@ -1633,23 +1663,37 @@ var DisclosureBar = memo(function DisclosureBar2() {
1633
1663
  }
1634
1664
  );
1635
1665
  });
1636
- function FailureActionButton(props) {
1637
- const { handlers, failureAction } = useChat();
1638
- const { t } = useCopy();
1639
- if (!failureAction) return null;
1640
- return /* @__PURE__ */ jsx(
1641
- Button,
1666
+ var ChatSkeleton = memo(function ChatSkeleton2() {
1667
+ const { colors: colors2, radius: radius2, space: space2 } = useTheme();
1668
+ const row = (width, end) => /* @__PURE__ */ jsx(
1669
+ View,
1642
1670
  {
1643
- label: failureAction.label ?? t("talkToPerson"),
1644
- variant: "text",
1645
- onPress: () => handlers.current.failureAction?.onPress(props.state)
1671
+ style: {
1672
+ alignSelf: end ? "flex-end" : "flex-start",
1673
+ width,
1674
+ height: 40,
1675
+ borderRadius: radius2.lg,
1676
+ backgroundColor: colors2.surface,
1677
+ marginHorizontal: space2.lg,
1678
+ marginTop: space2.md
1679
+ }
1646
1680
  }
1647
1681
  );
1648
- }
1649
- function FailureSlot(props) {
1650
- const { slot: Slot, state, Default } = props;
1651
- return Slot ? /* @__PURE__ */ jsx(Slot, { state, Default }) : /* @__PURE__ */ jsx(Default, { state });
1652
- }
1682
+ return /* @__PURE__ */ jsxs(
1683
+ View,
1684
+ {
1685
+ accessible: true,
1686
+ accessibilityRole: "progressbar",
1687
+ accessibilityState: { busy: true },
1688
+ testID: "vinaverse-skeleton",
1689
+ children: [
1690
+ row("62%", false),
1691
+ row("45%", true),
1692
+ row("70%", false)
1693
+ ]
1694
+ }
1695
+ );
1696
+ });
1653
1697
  function DefaultBubble(props) {
1654
1698
  const { colors: colors2, radius: radius2, space: space2, font: font2 } = useTheme();
1655
1699
  const role = props.item.role;
@@ -1771,37 +1815,22 @@ function Frame(props) {
1771
1815
  }
1772
1816
  );
1773
1817
  }
1774
- function useNativeLifecycle(store) {
1775
- useEffect(() => {
1776
- const apply = (state) => store.setForeground(state === "active");
1777
- apply(AppState.currentState);
1778
- const subscription = AppState.addEventListener("change", apply);
1779
- return () => subscription.remove();
1780
- }, [store]);
1781
- }
1782
- function useReducedMotion() {
1783
- const [reduced, setReduced] = useState(false);
1784
- useEffect(() => {
1785
- let live = true;
1786
- AccessibilityInfo.isReduceMotionEnabled().then(
1787
- (value) => {
1788
- if (live) setReduced(value);
1789
- },
1790
- () => void 0
1791
- );
1792
- const subscription = AccessibilityInfo.addEventListener(
1793
- "reduceMotionChanged",
1794
- setReduced
1795
- );
1796
- return () => {
1797
- live = false;
1798
- subscription.remove();
1799
- };
1800
- }, []);
1801
- return reduced;
1818
+ function FailureActionButton(props) {
1819
+ const { handlers, failureAction } = useChat();
1820
+ const { t } = useCopy();
1821
+ if (!failureAction) return null;
1822
+ return /* @__PURE__ */ jsx(
1823
+ Button,
1824
+ {
1825
+ label: failureAction.label ?? t("talkToPerson"),
1826
+ variant: "text",
1827
+ onPress: () => handlers.current.failureAction?.onPress(props.state)
1828
+ }
1829
+ );
1802
1830
  }
1803
- function announce(text) {
1804
- if (text) AccessibilityInfo.announceForAccessibility(text);
1831
+ function FailureSlot(props) {
1832
+ const { slot: Slot, state, Default } = props;
1833
+ return Slot ? /* @__PURE__ */ jsx(Slot, { state, Default }) : /* @__PURE__ */ jsx(Default, { state });
1805
1834
  }
1806
1835
  var SystemRow = memo(function SystemRow2(props) {
1807
1836
  const { t } = useCopy();
@@ -1969,17 +1998,27 @@ var Row = memo(function Row2(props) {
1969
1998
  return item.state === "streaming" ? /* @__PURE__ */ jsx(StreamingBubble, { item, showAuthor: props.showAuthor }) : /* @__PURE__ */ jsx(MessageBubble, { item, showAuthor: props.showAuthor });
1970
1999
  });
1971
2000
  var MessageList = memo(function MessageList2() {
1972
- const { store, slots } = useChat();
2001
+ const { store, slots, starters, handlers, imagePolicy } = useChat();
1973
2002
  const { t } = useCopy();
1974
2003
  const { space: space2 } = useTheme();
1975
2004
  const reducedMotion = useReducedMotion();
1976
2005
  const items = useConversationSelector(store, (v) => v.items);
2006
+ usePrefetchPhotos(items, handlers.current?.prefetchImage, imagePolicy?.hosts);
1977
2007
  const opening = useConversationSelector(
1978
2008
  store,
1979
2009
  (v) => v.status === "starting" || v.status === "connecting"
1980
2010
  );
1981
2011
  const agentName = useConversationSelector(store, (v) => v.agent.name);
1982
- const welcome = useConversationSelector(store, (v) => v.welcome);
2012
+ const served = useConversationSelector(store, (v) => v.welcome);
2013
+ const welcome = useMemo(
2014
+ () => served ?? (starters?.length ? {
2015
+ text: t("welcomeFallback", {
2016
+ agent: agentName ?? t("agentFallbackName")
2017
+ }),
2018
+ chips: [...starters]
2019
+ } : null),
2020
+ [served, starters, t, agentName]
2021
+ );
1983
2022
  useAnnounceReplies(items);
1984
2023
  const Group = slots.CardGroup;
1985
2024
  const runsRef = useRef(/* @__PURE__ */ new Map());
@@ -2005,8 +2044,12 @@ var MessageList = memo(function MessageList2() {
2005
2044
  []
2006
2045
  );
2007
2046
  const onChip = useCallback(
2008
- (message) => void store.send(message),
2009
- [store]
2047
+ (message) => {
2048
+ store.send(message);
2049
+ const chip = welcome?.chips.find((c) => c.message === message);
2050
+ if (chip) handlers.current?.onChip?.(chip);
2051
+ },
2052
+ [store, welcome, handlers]
2010
2053
  );
2011
2054
  const Empty = slots.EmptyState;
2012
2055
  const empty = opening ? /* @__PURE__ */ jsx(ChatSkeleton, {}) : Empty ? /* @__PURE__ */ jsx(
@@ -2038,10 +2081,25 @@ var MessageList = memo(function MessageList2() {
2038
2081
  const List = slots.ListComponent;
2039
2082
  return List ? /* @__PURE__ */ jsx(List, { ...props }) : /* @__PURE__ */ jsx(FlashList, { ...props });
2040
2083
  });
2084
+ function usePrefetchPhotos(items, prefetch, hosts) {
2085
+ const done = useRef(/* @__PURE__ */ new Set());
2086
+ useEffect(() => {
2087
+ if (!prefetch) return;
2088
+ for (const item of items) {
2089
+ if (item.type !== "card") continue;
2090
+ const card = item.card.card;
2091
+ const url = allowedImage(card.images?.[0]?.url ?? card.image_url, hosts);
2092
+ if (url && !done.current.has(url)) {
2093
+ done.current.add(url);
2094
+ prefetch(url);
2095
+ }
2096
+ }
2097
+ }, [items, prefetch, hosts]);
2098
+ }
2041
2099
  function useAnnounceReplies(items) {
2042
2100
  const seen = useRef(void 0);
2043
2101
  const { t } = useCopy();
2044
- const { store } = useChat();
2102
+ const { store, handlers } = useChat();
2045
2103
  useEffect(() => {
2046
2104
  const last = items.at(-1);
2047
2105
  if (seen.current === void 0) {
@@ -2054,8 +2112,8 @@ function useAnnounceReplies(items) {
2054
2112
  const author = last.role === "staff" ? t("staffLabel", {
2055
2113
  by: store.getSnapshot().takeover?.by || t("staffFallbackRole")
2056
2114
  }) : store.getSnapshot().agent.name ?? t("agentFallbackName");
2057
- announce(`${author}: ${last.text}`);
2058
- }, [items, t, store]);
2115
+ (handlers.current?.announce ?? announce)(`${author}: ${last.text}`);
2116
+ }, [items, t, store, handlers]);
2059
2117
  }
2060
2118
  var CONNECTING_DELAY = motion.bannerDelay;
2061
2119
  var StatusBanner = memo(function StatusBanner2() {
@@ -2156,7 +2214,14 @@ function Banner(props) {
2156
2214
  );
2157
2215
  }
2158
2216
  function VinaverseChatProvider(props) {
2159
- const { conversation, components, agentAvatar, timeZone } = props;
2217
+ const {
2218
+ conversation,
2219
+ components,
2220
+ agentAvatar,
2221
+ timeZone,
2222
+ starters,
2223
+ imagePolicy
2224
+ } = props;
2160
2225
  const handlers = useRef(props);
2161
2226
  handlers.current = props;
2162
2227
  const slots = useStableSlots(components);
@@ -2173,9 +2238,19 @@ function VinaverseChatProvider(props) {
2173
2238
  slots,
2174
2239
  agentAvatar,
2175
2240
  timeZone,
2176
- failureAction
2241
+ failureAction,
2242
+ starters,
2243
+ imagePolicy
2177
2244
  }),
2178
- [conversation, slots, agentAvatar, timeZone, failureAction]
2245
+ [
2246
+ conversation,
2247
+ slots,
2248
+ agentAvatar,
2249
+ timeZone,
2250
+ failureAction,
2251
+ starters,
2252
+ imagePolicy
2253
+ ]
2179
2254
  );
2180
2255
  useNativeLifecycle(conversation);
2181
2256
  useEffect(() => {
@@ -2201,7 +2276,9 @@ function VinaverseChat(props) {
2201
2276
  keyboardVerticalOffset: props.keyboardVerticalOffset ?? 0,
2202
2277
  keyboardBehavior: props.keyboardBehavior ?? (Platform.OS === "ios" ? "padding" : "none"),
2203
2278
  style: props.style,
2204
- onError: props.onWarning
2279
+ onError: props.onWarning,
2280
+ suggestion: props.suggestion ?? null,
2281
+ footer: props.footer
2205
2282
  }
2206
2283
  ) });
2207
2284
  }
@@ -2227,11 +2304,27 @@ function Layout(props) {
2227
2304
  /* @__PURE__ */ jsx(DisclosureBar, {}),
2228
2305
  /* @__PURE__ */ jsx(StatusBanner, {}),
2229
2306
  /* @__PURE__ */ jsx(View, { style: { flex: 1 }, children: /* @__PURE__ */ jsx(MessageList, {}) }),
2230
- /* @__PURE__ */ jsx(Composer, { ...reportError ? { onError: reportError } : {} })
2307
+ props.suggestion ? /* @__PURE__ */ jsx(Suggestion, { chip: props.suggestion }) : null,
2308
+ /* @__PURE__ */ jsx(Composer, { ...reportError ? { onError: reportError } : {} }),
2309
+ props.footer
2231
2310
  ]
2232
2311
  }
2233
2312
  );
2234
2313
  }
2314
+ function Suggestion(props) {
2315
+ const { store, handlers } = useChat();
2316
+ const { space: space2 } = useTheme();
2317
+ return /* @__PURE__ */ jsx(View, { style: { paddingHorizontal: space2.lg, alignItems: "flex-start" }, children: /* @__PURE__ */ jsx(
2318
+ Button,
2319
+ {
2320
+ label: props.chip.label,
2321
+ onPress: () => {
2322
+ store.send(props.chip.message);
2323
+ handlers.current?.onChip?.(props.chip);
2324
+ }
2325
+ }
2326
+ ) });
2327
+ }
2235
2328
  function useStableSlots(slots) {
2236
2329
  const held = useRef({});
2237
2330
  const next = slots ?? {};
@@ -2250,7 +2343,590 @@ function sameSlots(a, b) {
2250
2343
  }
2251
2344
  return true;
2252
2345
  }
2346
+ function AgentChat(props) {
2347
+ const {
2348
+ agentKey,
2349
+ place,
2350
+ entryPoint,
2351
+ askAbout,
2352
+ onContact,
2353
+ onOpenPrivacy,
2354
+ components,
2355
+ agentName,
2356
+ opener,
2357
+ ...chat
2358
+ } = props;
2359
+ const runtime = useAgentRuntime();
2360
+ const { conversation, state, startNew } = useAgentConversation(agentKey, {
2361
+ place: place ?? null,
2362
+ entryPoint: entryPoint ?? null
2363
+ });
2364
+ const store = conversation.store;
2365
+ const spoke = useConversationSelector(
2366
+ store,
2367
+ (v) => v.items.some((i) => i.type === "message" && i.role === "person")
2368
+ );
2369
+ const { Ended, Unreachable, UnavailableScreen, Footer, ...slots } = components ?? {};
2370
+ const copy = useMemo(
2371
+ () => agentName ? { ...props.copy, agentFallbackName: agentName } : props.copy,
2372
+ [agentName, props.copy]
2373
+ );
2374
+ const events = {
2375
+ onOpenTarget: chat.onOpenTarget ? (target, card) => {
2376
+ runtime.emit({
2377
+ type: "target_opened",
2378
+ key: conversation.key,
2379
+ cardId: card.id,
2380
+ kind: target.type
2381
+ });
2382
+ chat.onOpenTarget?.(target, card);
2383
+ } : void 0,
2384
+ onOpenLink: chat.onOpenLink ? (link, card) => {
2385
+ runtime.emit({
2386
+ type: "link_opened",
2387
+ key: conversation.key,
2388
+ cardId: card.id,
2389
+ kind: card.kind
2390
+ });
2391
+ chat.onOpenLink?.(link, card);
2392
+ } : void 0,
2393
+ onChip: (chip) => {
2394
+ runtime.emit({ type: "chip_tapped", key: conversation.key });
2395
+ chat.onChip?.(chip);
2396
+ }
2397
+ };
2398
+ const shared = {
2399
+ ...chat,
2400
+ ...events.onOpenTarget ? { onOpenTarget: events.onOpenTarget } : {},
2401
+ ...events.onOpenLink ? { onOpenLink: events.onOpenLink } : {},
2402
+ onChip: events.onChip,
2403
+ ...copy ? { copy } : {},
2404
+ ...onContact && !chat.failureAction ? { failureAction: { onPress: () => onContact() } } : {},
2405
+ conversation: store,
2406
+ components: slots
2407
+ };
2408
+ if (state.failure === "ended")
2409
+ return /* @__PURE__ */ jsx(VinaverseChatProvider, { ...shared, children: /* @__PURE__ */ jsx(Centered, { children: Ended ? /* @__PURE__ */ jsx(
2410
+ Ended,
2411
+ {
2412
+ onStartNew: startNew,
2413
+ code: state.code,
2414
+ Default: DefaultEnded
2415
+ }
2416
+ ) : /* @__PURE__ */ jsx(DefaultEnded, { onStartNew: startNew, code: state.code }) }) });
2417
+ if (state.failure === "unreachable")
2418
+ return /* @__PURE__ */ jsx(VinaverseChatProvider, { ...shared, children: /* @__PURE__ */ jsx(Centered, { children: Unreachable ? /* @__PURE__ */ jsx(
2419
+ Unreachable,
2420
+ {
2421
+ onRetry: conversation.retry,
2422
+ reason: state.reason,
2423
+ Default: DefaultUnreachable
2424
+ }
2425
+ ) : /* @__PURE__ */ jsx(
2426
+ DefaultUnreachable,
2427
+ {
2428
+ onRetry: conversation.retry,
2429
+ reason: state.reason
2430
+ }
2431
+ ) }) });
2432
+ if (state.failure === "unavailable") {
2433
+ const own = {
2434
+ reason: state.reason,
2435
+ code: state.code,
2436
+ onContact,
2437
+ onRetry: conversation.retry
2438
+ };
2439
+ return /* @__PURE__ */ jsx(VinaverseChatProvider, { ...shared, children: /* @__PURE__ */ jsx(Centered, { children: UnavailableScreen ? /* @__PURE__ */ jsx(UnavailableScreen, { ...own, Default: DefaultUnavailableScreen }) : /* @__PURE__ */ jsx(DefaultUnavailableScreen, { ...own }) }) });
2440
+ }
2441
+ return /* @__PURE__ */ jsx(
2442
+ VinaverseChat,
2443
+ {
2444
+ ...shared,
2445
+ suggestion: opener && !spoke ? opener : state.moved && askAbout ? { label: askAbout, message: askAbout } : null,
2446
+ footer: Footer === null ? null : /* @__PURE__ */ jsx(
2447
+ FooterFor,
2448
+ {
2449
+ store,
2450
+ state,
2451
+ rate: conversation.rate,
2452
+ Footer,
2453
+ onOpenPrivacy
2454
+ }
2455
+ )
2456
+ }
2457
+ );
2458
+ }
2459
+ function FooterFor(props) {
2460
+ const turnId = useConversationSelector(props.store, newestWholeReply);
2461
+ const own = {
2462
+ turnId,
2463
+ rating: turnId ? props.state.ratings.get(turnId) : void 0,
2464
+ onRate: (rating) => {
2465
+ if (turnId) props.rate(turnId, rating);
2466
+ },
2467
+ onOpenPrivacy: props.onOpenPrivacy
2468
+ };
2469
+ const { Footer } = props;
2470
+ return Footer ? /* @__PURE__ */ jsx(Footer, { ...own, Default: AgentFooter }) : /* @__PURE__ */ jsx(AgentFooter, { ...own });
2471
+ }
2472
+ function newestWholeReply(view) {
2473
+ for (let i = view.items.length - 1; i >= 0; i--) {
2474
+ const item = view.items[i];
2475
+ if (item?.type !== "message" || item.role !== "agent") continue;
2476
+ const whole = item.state === "sent" && !item.partial && !item.refusal && item.key.startsWith("a:");
2477
+ return whole ? item.key.slice(2) : null;
2478
+ }
2479
+ return null;
2480
+ }
2481
+ function Centered(props) {
2482
+ const { colors: colors2, space: space2 } = useTheme();
2483
+ return /* @__PURE__ */ jsx(
2484
+ View,
2485
+ {
2486
+ style: {
2487
+ flex: 1,
2488
+ alignItems: "center",
2489
+ justifyContent: "center",
2490
+ padding: space2.xl,
2491
+ backgroundColor: colors2.background
2492
+ },
2493
+ children: props.children
2494
+ }
2495
+ );
2496
+ }
2497
+ function Notice(props) {
2498
+ const { colors: colors2, space: space2, font: font2 } = useTheme();
2499
+ return /* @__PURE__ */ jsxs(
2500
+ View,
2501
+ {
2502
+ accessibilityRole: "alert",
2503
+ style: { alignItems: "center", gap: space2.md },
2504
+ children: [
2505
+ /* @__PURE__ */ jsx(
2506
+ Text,
2507
+ {
2508
+ style: {
2509
+ color: colors2.text,
2510
+ fontSize: font2.size.lg,
2511
+ fontWeight: "600",
2512
+ textAlign: "center"
2513
+ },
2514
+ children: props.title
2515
+ }
2516
+ ),
2517
+ /* @__PURE__ */ jsx(
2518
+ Text,
2519
+ {
2520
+ style: {
2521
+ color: colors2.textMuted,
2522
+ fontSize: font2.size.md,
2523
+ textAlign: "center"
2524
+ },
2525
+ children: props.body
2526
+ }
2527
+ ),
2528
+ props.action && props.onPress ? /* @__PURE__ */ jsx(
2529
+ Button,
2530
+ {
2531
+ label: props.action,
2532
+ variant: "primary",
2533
+ onPress: props.onPress
2534
+ }
2535
+ ) : null
2536
+ ]
2537
+ }
2538
+ );
2539
+ }
2540
+ function DefaultEnded(props) {
2541
+ const { t } = useCopy();
2542
+ return /* @__PURE__ */ jsx(
2543
+ Notice,
2544
+ {
2545
+ title: t("agentEnded"),
2546
+ body: t("agentEndedBody"),
2547
+ action: t("agentStartOver"),
2548
+ onPress: props.onStartNew
2549
+ }
2550
+ );
2551
+ }
2552
+ function DefaultUnavailableScreen(props) {
2553
+ const { t } = useCopy();
2554
+ const name = useAgentName(t("agentFallbackName"));
2555
+ const title = t("agentOff", { agent: name });
2556
+ return /* @__PURE__ */ jsx(
2557
+ Notice,
2558
+ {
2559
+ title: title.charAt(0).toUpperCase() + title.slice(1),
2560
+ body: t("agentOffBody"),
2561
+ ...props.onContact ? { action: t("talkToPerson"), onPress: props.onContact } : {}
2562
+ }
2563
+ );
2564
+ }
2565
+ function DefaultUnreachable(props) {
2566
+ const { t } = useCopy();
2567
+ const name = useAgentName(t("agentFallbackName"));
2568
+ return /* @__PURE__ */ jsx(
2569
+ Notice,
2570
+ {
2571
+ title: t("agentUnreachable", { agent: name }),
2572
+ body: t("agentUnreachableBody"),
2573
+ action: t("tryAgain"),
2574
+ onPress: props.onRetry
2575
+ }
2576
+ );
2577
+ }
2578
+ function AgentFooter(props) {
2579
+ const { t } = useCopy();
2580
+ const { colors: colors2, space: space2, font: font2 } = useTheme();
2581
+ const muted = { color: colors2.textMuted, fontSize: font2.size.sm };
2582
+ return /* @__PURE__ */ jsxs(
2583
+ View,
2584
+ {
2585
+ style: {
2586
+ flexDirection: "row",
2587
+ flexWrap: "wrap",
2588
+ alignItems: "center",
2589
+ gap: space2.xs,
2590
+ paddingHorizontal: space2.lg
2591
+ },
2592
+ children: [
2593
+ props.turnId === null ? null : props.rating ? /* @__PURE__ */ jsx(Text, { style: muted, children: t("helpfulThanks") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2594
+ /* @__PURE__ */ jsx(Text, { style: muted, children: t("helpful") }),
2595
+ /* @__PURE__ */ jsx(
2596
+ Button,
2597
+ {
2598
+ label: t("helpfulYes"),
2599
+ variant: "text",
2600
+ onPress: () => props.onRate("up")
2601
+ }
2602
+ ),
2603
+ /* @__PURE__ */ jsx(
2604
+ Button,
2605
+ {
2606
+ label: t("helpfulNo"),
2607
+ variant: "text",
2608
+ onPress: () => props.onRate("down")
2609
+ }
2610
+ )
2611
+ ] }),
2612
+ props.onOpenPrivacy ? /* @__PURE__ */ jsx(
2613
+ Button,
2614
+ {
2615
+ label: t("privacy"),
2616
+ variant: "text",
2617
+ role: "link",
2618
+ onPress: props.onOpenPrivacy
2619
+ }
2620
+ ) : null
2621
+ ]
2622
+ }
2623
+ );
2624
+ }
2625
+ var LAUNCHER_SIZE = 56;
2626
+ function AgentLauncher(props) {
2627
+ return /* @__PURE__ */ jsx(CopyProvider, { locale: props.locale, copy: props.copy, children: /* @__PURE__ */ jsx(ThemeProvider, { theme: props.theme, colorScheme: props.colorScheme, children: /* @__PURE__ */ jsx(Launcher, { ...props }) }) });
2628
+ }
2629
+ function useKeyboardShown() {
2630
+ const [shown, setShown] = useState(false);
2631
+ useEffect(() => {
2632
+ const show = Keyboard.addListener("keyboardDidShow", () => setShown(true));
2633
+ const hide = Keyboard.addListener("keyboardDidHide", () => setShown(false));
2634
+ return () => {
2635
+ show.remove();
2636
+ hide.remove();
2637
+ };
2638
+ }, []);
2639
+ return shown;
2640
+ }
2641
+ function Launcher(props) {
2642
+ const { t } = useCopy();
2643
+ const name = useAgentName(t("agentFallbackName"));
2644
+ const keyboard = useKeyboardShown();
2645
+ const reducedMotion = useReducedMotion();
2646
+ const { route = null, routes, mode } = props;
2647
+ const visible = props.hidden !== true && !(keyboard && props.hideWithKeyboard !== false) && (!routes || route !== null && routes.includes(route));
2648
+ const launcher = useAgentLauncher({
2649
+ subject: props.subject,
2650
+ mode,
2651
+ visible,
2652
+ onOpen: () => props.onOpen({ route, mode }),
2653
+ ...props.storage ? { storage: props.storage } : {},
2654
+ ...props.storageKey ? { storageKey: props.storageKey } : {},
2655
+ ...props.delayMs === void 0 ? {} : { delayMs: props.delayMs }
2656
+ });
2657
+ const text = typeof props.greeting === "function" ? props.greeting(mode) : props.greeting ?? t("launcherGreeting", { agent: name });
2658
+ const say = props.announce ?? announce;
2659
+ const said = useRef(false);
2660
+ useEffect(() => {
2661
+ if (!launcher.greets) {
2662
+ said.current = false;
2663
+ return;
2664
+ }
2665
+ if (said.current) return;
2666
+ said.current = true;
2667
+ say(text);
2668
+ }, [launcher.greets, text, say]);
2669
+ if (!launcher.shows) return null;
2670
+ const edge = props.placement?.edge ?? "right";
2671
+ const look = props.appearance ?? {};
2672
+ const greeting = {
2673
+ text,
2674
+ closeLabel: t("close"),
2675
+ onOpen: launcher.open,
2676
+ onClose: launcher.dismiss,
2677
+ tail: look.tail !== false,
2678
+ edge
2679
+ };
2680
+ const button = {
2681
+ label: t("launcherOpen", { agent: name }),
2682
+ name,
2683
+ onPress: launcher.open,
2684
+ Mark: props.Mark,
2685
+ ring: look.ring ?? null,
2686
+ shadow: look.shadow !== false
2687
+ };
2688
+ const { Greeting, Button: Button3, Entrance } = props.components ?? {};
2689
+ const enter = (part, children) => Entrance ? /* @__PURE__ */ jsx(
2690
+ Entrance,
2691
+ {
2692
+ part,
2693
+ reducedMotion,
2694
+ Default: LauncherEntrance,
2695
+ children
2696
+ }
2697
+ ) : /* @__PURE__ */ jsx(LauncherEntrance, { part, reducedMotion, children });
2698
+ return /* @__PURE__ */ jsxs(
2699
+ View,
2700
+ {
2701
+ pointerEvents: "box-none",
2702
+ style: [
2703
+ {
2704
+ position: "absolute",
2705
+ bottom: props.placement?.bottom ?? 16,
2706
+ [edge]: props.placement?.inset ?? 16,
2707
+ alignItems: edge === "right" ? "flex-end" : "flex-start",
2708
+ gap: 8
2709
+ },
2710
+ props.style
2711
+ ],
2712
+ testID: "vinaverse-launcher",
2713
+ children: [
2714
+ launcher.greets ? enter(
2715
+ "greeting",
2716
+ Greeting ? /* @__PURE__ */ jsx(Greeting, { ...greeting, Default: LauncherGreeting }) : /* @__PURE__ */ jsx(LauncherGreeting, { ...greeting })
2717
+ ) : null,
2718
+ enter(
2719
+ "button",
2720
+ Button3 ? /* @__PURE__ */ jsx(Button3, { ...button, Default: LauncherButton }) : /* @__PURE__ */ jsx(LauncherButton, { ...button })
2721
+ )
2722
+ ]
2723
+ }
2724
+ );
2725
+ }
2726
+ function LauncherEntrance(props) {
2727
+ const { motion: motion3 } = useTheme();
2728
+ const shown = useRef(new Animated.Value(props.reducedMotion ? 1 : 0)).current;
2729
+ useEffect(() => {
2730
+ if (props.reducedMotion) {
2731
+ shown.setValue(1);
2732
+ return;
2733
+ }
2734
+ const run = Animated.timing(shown, {
2735
+ toValue: 1,
2736
+ duration: motion3.normal,
2737
+ useNativeDriver: true
2738
+ });
2739
+ run.start();
2740
+ return () => run.stop();
2741
+ }, [shown, props.reducedMotion, motion3.normal]);
2742
+ return /* @__PURE__ */ jsx(
2743
+ Animated.View,
2744
+ {
2745
+ pointerEvents: "box-none",
2746
+ style: {
2747
+ opacity: shown,
2748
+ transform: [
2749
+ {
2750
+ scale: shown.interpolate({
2751
+ inputRange: [0, 1],
2752
+ outputRange: [0.9, 1]
2753
+ })
2754
+ }
2755
+ ]
2756
+ },
2757
+ testID: `vinaverse-launcher-entrance-${props.part}`,
2758
+ children: props.children
2759
+ }
2760
+ );
2761
+ }
2762
+ function LauncherGreeting(props) {
2763
+ const { colors: colors2, radius: radius2, space: space2, font: font2 } = useTheme();
2764
+ return /* @__PURE__ */ jsxs(
2765
+ View,
2766
+ {
2767
+ style: {
2768
+ maxWidth: 296,
2769
+ flexDirection: "row",
2770
+ alignItems: "flex-start",
2771
+ borderRadius: radius2.lg,
2772
+ backgroundColor: colors2.text
2773
+ },
2774
+ testID: "vinaverse-launcher-greeting",
2775
+ children: [
2776
+ props.tail ? /* @__PURE__ */ jsx(
2777
+ View,
2778
+ {
2779
+ accessible: false,
2780
+ style: {
2781
+ position: "absolute",
2782
+ bottom: -5,
2783
+ [props.edge]: LAUNCHER_SIZE / 2 - 6,
2784
+ width: 12,
2785
+ height: 12,
2786
+ backgroundColor: colors2.text,
2787
+ transform: [{ rotate: "45deg" }]
2788
+ },
2789
+ testID: "vinaverse-launcher-tail"
2790
+ }
2791
+ ) : null,
2792
+ /* @__PURE__ */ jsx(
2793
+ Pressable,
2794
+ {
2795
+ accessibilityRole: "button",
2796
+ accessibilityLabel: props.text,
2797
+ onPress: props.onOpen,
2798
+ style: {
2799
+ flexShrink: 1,
2800
+ paddingVertical: space2.sm,
2801
+ paddingLeft: space2.md
2802
+ },
2803
+ children: /* @__PURE__ */ jsx(Text, { style: { color: colors2.background, fontSize: font2.size.md }, children: props.text })
2804
+ }
2805
+ ),
2806
+ /* @__PURE__ */ jsx(
2807
+ Pressable,
2808
+ {
2809
+ accessibilityRole: "button",
2810
+ accessibilityLabel: props.closeLabel,
2811
+ onPress: props.onClose,
2812
+ style: {
2813
+ minWidth: 44,
2814
+ minHeight: 44,
2815
+ alignItems: "center",
2816
+ justifyContent: "center"
2817
+ },
2818
+ testID: "vinaverse-launcher-close",
2819
+ children: /* @__PURE__ */ jsx(Text, { style: { color: colors2.background, fontSize: font2.size.md }, children: "\xD7" })
2820
+ }
2821
+ )
2822
+ ]
2823
+ }
2824
+ );
2825
+ }
2826
+ function LauncherButton(props) {
2827
+ const { colors: colors2, font: font2 } = useTheme();
2828
+ const { Mark, ring } = props;
2829
+ return /* @__PURE__ */ jsx(
2830
+ Pressable,
2831
+ {
2832
+ accessibilityRole: "button",
2833
+ accessibilityLabel: props.label,
2834
+ onPress: props.onPress,
2835
+ style: ({ pressed }) => ({
2836
+ width: LAUNCHER_SIZE,
2837
+ height: LAUNCHER_SIZE,
2838
+ borderRadius: LAUNCHER_SIZE / 2,
2839
+ alignItems: "center",
2840
+ justifyContent: "center",
2841
+ backgroundColor: colors2.primary,
2842
+ opacity: pressed ? 0.85 : 1,
2843
+ ...ring ? { borderWidth: ring.width, borderColor: ring.color } : {},
2844
+ ...props.shadow ? {
2845
+ elevation: 6,
2846
+ shadowColor: "#000",
2847
+ shadowOpacity: 0.2,
2848
+ shadowRadius: 8,
2849
+ shadowOffset: { width: 0, height: 3 }
2850
+ } : {}
2851
+ }),
2852
+ testID: "vinaverse-launcher-button",
2853
+ children: Mark ? /* @__PURE__ */ jsx(Mark, { size: 34, color: colors2.onPrimary }) : /* @__PURE__ */ jsx(
2854
+ Text,
2855
+ {
2856
+ style: {
2857
+ color: colors2.onPrimary,
2858
+ fontSize: font2.size.lg,
2859
+ fontWeight: "600"
2860
+ },
2861
+ children: (props.name.trim()[0] ?? "?").toUpperCase()
2862
+ }
2863
+ )
2864
+ }
2865
+ );
2866
+ }
2867
+ function AskAboutRow(props) {
2868
+ return /* @__PURE__ */ jsx(CopyProvider, { locale: props.locale, copy: props.copy, children: /* @__PURE__ */ jsx(ThemeProvider, { theme: props.theme, colorScheme: props.colorScheme, children: /* @__PURE__ */ jsx(Row3, { ...props }) }) });
2869
+ }
2870
+ function Row3(props) {
2871
+ const { t } = useCopy();
2872
+ const { colors: colors2, radius: radius2, space: space2, font: font2 } = useTheme();
2873
+ const name = useAgentName(t("agentFallbackName"));
2874
+ const { available } = useAgentFeatures();
2875
+ const [shows, setShows] = useState(null);
2876
+ if (shows === null && available) setShows(true);
2877
+ if (!shows) return null;
2878
+ const { Mark } = props;
2879
+ return /* @__PURE__ */ jsxs(
2880
+ Pressable,
2881
+ {
2882
+ accessibilityRole: "button",
2883
+ accessibilityLabel: props.body ? `${props.title}. ${props.body}` : props.title,
2884
+ onPress: props.onPress,
2885
+ style: ({ pressed }) => ({
2886
+ flexDirection: "row",
2887
+ alignItems: "center",
2888
+ gap: space2.md,
2889
+ padding: space2.md,
2890
+ borderRadius: radius2.lg,
2891
+ backgroundColor: colors2.surface,
2892
+ opacity: pressed ? 0.85 : 1
2893
+ }),
2894
+ testID: "vinaverse-ask-about",
2895
+ children: [
2896
+ /* @__PURE__ */ jsx(
2897
+ View,
2898
+ {
2899
+ style: {
2900
+ width: 36,
2901
+ height: 36,
2902
+ borderRadius: 18,
2903
+ alignItems: "center",
2904
+ justifyContent: "center",
2905
+ backgroundColor: colors2.primary
2906
+ },
2907
+ children: Mark ? /* @__PURE__ */ jsx(Mark, { size: 22, color: colors2.onPrimary }) : /* @__PURE__ */ jsx(Text, { style: { color: colors2.onPrimary, fontWeight: "600" }, children: (name.trim()[0] ?? "?").toUpperCase() })
2908
+ }
2909
+ ),
2910
+ /* @__PURE__ */ jsxs(View, { style: { flex: 1, gap: space2.xxs }, children: [
2911
+ /* @__PURE__ */ jsx(
2912
+ Text,
2913
+ {
2914
+ style: {
2915
+ color: colors2.text,
2916
+ fontSize: font2.size.md,
2917
+ fontWeight: "600"
2918
+ },
2919
+ children: props.title
2920
+ }
2921
+ ),
2922
+ props.body ? /* @__PURE__ */ jsx(Text, { style: { color: colors2.textMuted, fontSize: font2.size.sm }, children: props.body }) : null
2923
+ ] }),
2924
+ /* @__PURE__ */ jsx(Text, { style: { color: colors2.textMuted, fontSize: font2.size.lg }, children: "\u203A" })
2925
+ ]
2926
+ }
2927
+ );
2928
+ }
2253
2929
 
2254
- export { ActivityLine, Avatar, Button, CardActions, CardCarousel, CardFrame, CardView, ChatHeader, ChatSkeleton, Composer, DefaultBubble, DefaultComposer, DefaultHeader, DefaultTurnFailed, DefaultUnavailable, DisclosureBar, FailureActionButton, InfoCard, LinksCard, ListingCard, MessageBubble, MessageList, NextStepCard, ProposalCard, QuestionCard, Row, StatusBanner, StreamingBubble, SystemRow, ThemeProvider, TimeSlotsCard, VinaverseChat, VinaverseChatProvider, Welcome, announce, answerText, carousels, createTheme, defaultCard, fieldText, itemType, monogram, ratingText, themeProblems, useChat, useNativeLifecycle, useReducedMotion, useTheme };
2930
+ export { ActivityLine, AgentChat, AgentFooter, AgentLauncher, AskAboutRow, Avatar, Button, CardActions, CardCarousel, CardFrame, CardView, ChatHeader, ChatSkeleton, Composer, DefaultBubble, DefaultComposer, DefaultEnded, DefaultHeader, DefaultTurnFailed, DefaultUnavailable, DefaultUnavailableScreen, DefaultUnreachable, DisclosureBar, FailureActionButton, InfoCard, LAUNCHER_SIZE, LauncherButton, LauncherEntrance, LauncherGreeting, LinksCard, ListingCard, MessageBubble, MessageList, NextStepCard, ProposalCard, QuestionCard, Row, StatusBanner, StreamingBubble, SystemRow, ThemeProvider, TimeSlotsCard, VinaverseChat, VinaverseChatProvider, Welcome, allowedImage, announce, answerText, carousels, createTheme, defaultCard, fieldText, itemType, monogram, newestWholeReply, ratingText, themeProblems, useChat, useKeyboardShown, useNativeLifecycle, useReducedMotion, useTheme };
2255
2931
  //# sourceMappingURL=index.js.map
2256
2932
  //# sourceMappingURL=index.js.map