@vinaverse/react-native 0.1.0-alpha.12 → 0.1.0-alpha.13

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.
Files changed (56) hide show
  1. package/README.md +16 -3
  2. package/dist/ask.cjs +10 -5
  3. package/dist/ask.d.cts +35 -5
  4. package/dist/ask.d.ts +35 -5
  5. package/dist/ask.js +3 -2
  6. package/dist/chat.cjs +69 -69
  7. package/dist/chat.d.cts +44 -8
  8. package/dist/chat.d.ts +44 -8
  9. package/dist/chat.js +3 -3
  10. package/dist/{chunk-XAG2P447.cjs → chunk-272ACDLI.cjs} +248 -104
  11. package/dist/chunk-272ACDLI.cjs.map +1 -0
  12. package/dist/{chunk-EFEXTVIT.js → chunk-35A77CNF.js} +11 -3
  13. package/dist/chunk-35A77CNF.js.map +1 -0
  14. package/dist/{chunk-NMKJ7LIJ.cjs → chunk-35T5QPMT.cjs} +31 -7
  15. package/dist/chunk-35T5QPMT.cjs.map +1 -0
  16. package/dist/{chunk-7KPCO443.js → chunk-GFD4T3IA.js} +28 -4
  17. package/dist/chunk-GFD4T3IA.js.map +1 -0
  18. package/dist/{chunk-2J2LIJLW.js → chunk-MCVW6TZD.js} +113 -33
  19. package/dist/chunk-MCVW6TZD.js.map +1 -0
  20. package/dist/{chunk-KSHDF3MG.js → chunk-QSMMC4RZ.js} +216 -74
  21. package/dist/chunk-QSMMC4RZ.js.map +1 -0
  22. package/dist/{chunk-POJP52GE.js → chunk-TY4TISCR.js} +4 -4
  23. package/dist/chunk-TY4TISCR.js.map +1 -0
  24. package/dist/{chunk-6QYDPGRS.cjs → chunk-UMCOOQT6.cjs} +11 -3
  25. package/dist/chunk-UMCOOQT6.cjs.map +1 -0
  26. package/dist/{chunk-MG32E4JI.cjs → chunk-VWAAUCE3.cjs} +11 -11
  27. package/dist/chunk-VWAAUCE3.cjs.map +1 -0
  28. package/dist/{chunk-4PXQ7DEY.cjs → chunk-YVCMKSJG.cjs} +140 -60
  29. package/dist/chunk-YVCMKSJG.cjs.map +1 -0
  30. package/dist/{context-gHCLFsJh.d.ts → context-B4ctXjm5.d.cts} +22 -1
  31. package/dist/{context-gHCLFsJh.d.cts → context-B4ctXjm5.d.ts} +22 -1
  32. package/dist/history.cjs +52 -48
  33. package/dist/history.cjs.map +1 -1
  34. package/dist/history.d.cts +12 -3
  35. package/dist/history.d.ts +12 -3
  36. package/dist/history.js +13 -9
  37. package/dist/history.js.map +1 -1
  38. package/dist/index.cjs +83 -78
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +3 -3
  41. package/dist/index.d.ts +3 -3
  42. package/dist/index.js +6 -5
  43. package/dist/index.js.map +1 -1
  44. package/dist/launcher.cjs +10 -10
  45. package/dist/launcher.js +2 -2
  46. package/package.json +7 -7
  47. package/dist/chunk-2J2LIJLW.js.map +0 -1
  48. package/dist/chunk-4PXQ7DEY.cjs.map +0 -1
  49. package/dist/chunk-6QYDPGRS.cjs.map +0 -1
  50. package/dist/chunk-7KPCO443.js.map +0 -1
  51. package/dist/chunk-EFEXTVIT.js.map +0 -1
  52. package/dist/chunk-KSHDF3MG.js.map +0 -1
  53. package/dist/chunk-MG32E4JI.cjs.map +0 -1
  54. package/dist/chunk-NMKJ7LIJ.cjs.map +0 -1
  55. package/dist/chunk-POJP52GE.js.map +0 -1
  56. package/dist/chunk-XAG2P447.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/AskAboutRow.tsx"],"names":["jsx","CopyProvider","ThemeProvider","useCopy","useTheme","useAgentName","useAgentRuntime","useAgentStatus","useAgentSweep","useState","askAboutKey","anchorRef","jsxs","Pressable","View","Text","entryLabel"],"mappings":"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","file":"chunk-35T5QPMT.cjs","sourcesContent":["// \"Ask the agent about this\" on one of the app's own pages (a professional's, a space's, a booking's): a row that opens\n// a conversation of that object's own, the agent told the place before the chat opens. It shows only when the agent is\n// available, decided once as the page draws, from the status already read, so it never appears or disappears under\n// content the person is reading.\nimport {\n type AgentAnchorRef,\n type AgentAnchorType,\n type AgentEntry,\n type AgentKey,\n type AskAboutPlace,\n anchorRef,\n askAboutKey,\n entryLabel,\n} from '@vinaverse/client/agent';\nimport { type CopyOverrides, CopyProvider, useCopy } from '@vinaverse/react';\nimport {\n useAgentName,\n useAgentRuntime,\n useAgentStatus,\n} from '@vinaverse/react/agent';\nimport { type ComponentType, type ReactNode, useState } from 'react';\nimport { Pressable, Text, View } from 'react-native';\nimport { useAgentSweep } from '../platform.js';\nimport {\n type ColorSchemeSetting,\n type ThemeOverrides,\n ThemeProvider,\n useTheme,\n} from '../theme.js';\n\n/** The row's look beyond the theme. */\nexport interface AskAboutRowAppearance {\n /** A tint behind the row; default the theme's `surface`. */\n readonly background?: string;\n /** The chevron at the row's end. Default true. */\n readonly chevron?: boolean;\n}\n\n/** What the row hands back on a press: everything `<AgentChat {...open} />` needs to open the object's conversation. */\nexport interface AskAboutOpen {\n readonly entryPoint: 'ask';\n /** The app's key on the object's own thread (`askAboutKey`): each object its own conversation. */\n readonly agentKey: AgentKey;\n /** The place as given, its `preview` included (AgentChat draws it, and never sends it). */\n readonly place: AskAboutPlace;\n /** The question offered first, before the person says anything; null without one. */\n readonly askAbout: string | null;\n /** `ask_about`, with the app's label (at most 60 code points); sent only with the runtime's `sendAnchor`. */\n readonly entry: AgentEntry;\n /**\n * The object, for the contract's anchor (contracts#86); null when its type is not one of the contract's\n * (`AgentAnchorType`; pass `anchorType` for an app word such as \"space\"). Sent only with the runtime's `sendAnchor`.\n */\n readonly anchor: AgentAnchorRef | null;\n}\n\nexport interface AskAboutRowProps {\n /** \"Ask Example Agent about Riley Sample\". */\n readonly title: string;\n readonly body?: string;\n /** The app's key as it holds it (its mode as it is): the row puts the object's thread on it. Keep it stable. */\n readonly agentKey: AgentKey;\n /** The screen and the object on it; `preview` draws the object in the chat until the agent's verified card comes. */\n readonly place: AskAboutPlace;\n /** A question about the object, offered first in the chat as a chip the person taps; never sent in their name. */\n readonly question?: string;\n /**\n * The app's own word for this way in, for analytics: cut to 60 code points at a whole character (`entryLabel`).\n * Default: the place's screen.\n */\n readonly entryLabel?: string;\n /** The contract's type for the object, when the app's `place.entity.type` is a word of its own (\"space\"). */\n readonly anchorType?: AgentAnchorType;\n /** The person asks: the runtime was told the place for the object's key; open `<AgentChat {...open} />`. */\n readonly onPress: (open: AskAboutOpen) => void;\n /** The app's brand mark at the row's start; default the agent name's first letter. */\n readonly Mark?: ComponentType<{\n readonly size: number;\n readonly color: string;\n }>;\n readonly appearance?: AskAboutRowAppearance;\n readonly locale?: string;\n readonly copy?: CopyOverrides;\n readonly theme?: ThemeOverrides;\n readonly colorScheme?: ColorSchemeSetting;\n /** The row's test id. Default `vinaverse-ask-about`. */\n readonly testID?: string;\n}\n\nexport function AskAboutRow(props: AskAboutRowProps): ReactNode {\n return (\n <CopyProvider locale={props.locale} copy={props.copy}>\n <ThemeProvider theme={props.theme} colorScheme={props.colorScheme}>\n <Row {...props} />\n </ThemeProvider>\n </CopyProvider>\n );\n}\n\nfunction Row(props: AskAboutRowProps): ReactNode {\n const { t } = useCopy();\n const { colors, radius, space, font } = useTheme();\n const name = useAgentName(t('agentFallbackName'));\n const runtime = useAgentRuntime();\n useAgentStatus(); // reads the status when none is held, for the pages after this one\n useAgentSweep(runtime);\n // Decided once, as the page draws, from the status already read: an agent unknown or unavailable then stays away for\n // the visit, and the row is never added under content the person is reading.\n const [shows] = useState(() => !!runtime.getStatus()?.available);\n if (!shows) return null;\n const { Mark, appearance: look } = props;\n const press = () => {\n const { preview: _, ...place } = props.place;\n const agentKey = askAboutKey(props.agentKey, place);\n const open: AskAboutOpen = {\n entryPoint: 'ask',\n agentKey,\n place: props.place,\n askAbout: props.question ?? null,\n entry: entryOf(props.entryLabel ?? place.screen),\n anchor: anchorRef(props.anchorType ?? place.entity.type, place.entity.id),\n };\n // Told before the chat opens, so its first session already knows where the person asks from.\n runtime.peek(agentKey).tell({\n place,\n entryPoint: 'ask',\n anchor: open.anchor,\n entry: open.entry,\n });\n props.onPress(open);\n };\n return (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel={\n props.body ? `${props.title}. ${props.body}` : props.title\n }\n onPress={press}\n style={({ pressed }) => ({\n flexDirection: 'row',\n alignItems: 'center',\n gap: space.md,\n padding: space.md,\n borderRadius: radius.lg,\n backgroundColor: look?.background ?? colors.surface,\n opacity: pressed ? 0.85 : 1,\n })}\n testID={props.testID ?? 'vinaverse-ask-about'}\n >\n <View\n style={{\n width: 36,\n height: 36,\n borderRadius: 18,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: colors.primary,\n }}\n >\n {Mark ? (\n <Mark size={22} color={colors.onPrimary} />\n ) : (\n <Text style={{ color: colors.onPrimary, fontWeight: '600' }}>\n {(name.trim()[0] ?? '?').toUpperCase()}\n </Text>\n )}\n </View>\n <View style={{ flex: 1, gap: space.xxs }}>\n <Text\n style={{\n color: colors.text,\n fontSize: font.size.md,\n fontWeight: '600',\n }}\n >\n {props.title}\n </Text>\n {props.body ? (\n <Text style={{ color: colors.textMuted, fontSize: font.size.sm }}>\n {props.body}\n </Text>\n ) : null}\n </View>\n {look?.chevron === false ? null : (\n <Text style={{ color: colors.textMuted, fontSize: font.size.lg }}>\n ›\n </Text>\n )}\n </Pressable>\n );\n}\n\n/** `ask_about` with the app's word, cut as the contract takes it; without a label when nothing is left. */\nfunction entryOf(word: string): AgentEntry {\n const label = entryLabel(word);\n return label ? { point: 'ask_about', label } : { point: 'ask_about' };\n}\n"]}
@@ -1,4 +1,5 @@
1
- import { ThemeProvider, useTheme, useAgentSweep } from './chunk-EFEXTVIT.js';
1
+ import { ThemeProvider, useTheme, useAgentSweep } from './chunk-35A77CNF.js';
2
+ import { askAboutKey, anchorRef, entryLabel } from '@vinaverse/client/agent';
2
3
  import { CopyProvider, useCopy } from '@vinaverse/react';
3
4
  import { useAgentName, useAgentRuntime, useAgentStatus } from '@vinaverse/react/agent';
4
5
  import { useState } from 'react';
@@ -18,12 +19,31 @@ function Row(props) {
18
19
  const [shows] = useState(() => !!runtime.getStatus()?.available);
19
20
  if (!shows) return null;
20
21
  const { Mark, appearance: look } = props;
22
+ const press = () => {
23
+ const { preview: _, ...place } = props.place;
24
+ const agentKey = askAboutKey(props.agentKey, place);
25
+ const open = {
26
+ entryPoint: "ask",
27
+ agentKey,
28
+ place: props.place,
29
+ askAbout: props.question ?? null,
30
+ entry: entryOf(props.entryLabel ?? place.screen),
31
+ anchor: anchorRef(props.anchorType ?? place.entity.type, place.entity.id)
32
+ };
33
+ runtime.peek(agentKey).tell({
34
+ place,
35
+ entryPoint: "ask",
36
+ anchor: open.anchor,
37
+ entry: open.entry
38
+ });
39
+ props.onPress(open);
40
+ };
21
41
  return /* @__PURE__ */ jsxs(
22
42
  Pressable,
23
43
  {
24
44
  accessibilityRole: "button",
25
45
  accessibilityLabel: props.body ? `${props.title}. ${props.body}` : props.title,
26
- onPress: () => props.onPress({ entryPoint: "ask" }),
46
+ onPress: press,
27
47
  style: ({ pressed }) => ({
28
48
  flexDirection: "row",
29
49
  alignItems: "center",
@@ -68,7 +88,11 @@ function Row(props) {
68
88
  }
69
89
  );
70
90
  }
91
+ function entryOf(word) {
92
+ const label = entryLabel(word);
93
+ return label ? { point: "ask_about", label } : { point: "ask_about" };
94
+ }
71
95
 
72
96
  export { AskAboutRow };
73
- //# sourceMappingURL=chunk-7KPCO443.js.map
74
- //# sourceMappingURL=chunk-7KPCO443.js.map
97
+ //# sourceMappingURL=chunk-GFD4T3IA.js.map
98
+ //# sourceMappingURL=chunk-GFD4T3IA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/AskAboutRow.tsx"],"names":[],"mappings":"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","file":"chunk-GFD4T3IA.js","sourcesContent":["// \"Ask the agent about this\" on one of the app's own pages (a professional's, a space's, a booking's): a row that opens\n// a conversation of that object's own, the agent told the place before the chat opens. It shows only when the agent is\n// available, decided once as the page draws, from the status already read, so it never appears or disappears under\n// content the person is reading.\nimport {\n type AgentAnchorRef,\n type AgentAnchorType,\n type AgentEntry,\n type AgentKey,\n type AskAboutPlace,\n anchorRef,\n askAboutKey,\n entryLabel,\n} from '@vinaverse/client/agent';\nimport { type CopyOverrides, CopyProvider, useCopy } from '@vinaverse/react';\nimport {\n useAgentName,\n useAgentRuntime,\n useAgentStatus,\n} from '@vinaverse/react/agent';\nimport { type ComponentType, type ReactNode, useState } from 'react';\nimport { Pressable, Text, View } from 'react-native';\nimport { useAgentSweep } from '../platform.js';\nimport {\n type ColorSchemeSetting,\n type ThemeOverrides,\n ThemeProvider,\n useTheme,\n} from '../theme.js';\n\n/** The row's look beyond the theme. */\nexport interface AskAboutRowAppearance {\n /** A tint behind the row; default the theme's `surface`. */\n readonly background?: string;\n /** The chevron at the row's end. Default true. */\n readonly chevron?: boolean;\n}\n\n/** What the row hands back on a press: everything `<AgentChat {...open} />` needs to open the object's conversation. */\nexport interface AskAboutOpen {\n readonly entryPoint: 'ask';\n /** The app's key on the object's own thread (`askAboutKey`): each object its own conversation. */\n readonly agentKey: AgentKey;\n /** The place as given, its `preview` included (AgentChat draws it, and never sends it). */\n readonly place: AskAboutPlace;\n /** The question offered first, before the person says anything; null without one. */\n readonly askAbout: string | null;\n /** `ask_about`, with the app's label (at most 60 code points); sent only with the runtime's `sendAnchor`. */\n readonly entry: AgentEntry;\n /**\n * The object, for the contract's anchor (contracts#86); null when its type is not one of the contract's\n * (`AgentAnchorType`; pass `anchorType` for an app word such as \"space\"). Sent only with the runtime's `sendAnchor`.\n */\n readonly anchor: AgentAnchorRef | null;\n}\n\nexport interface AskAboutRowProps {\n /** \"Ask Example Agent about Riley Sample\". */\n readonly title: string;\n readonly body?: string;\n /** The app's key as it holds it (its mode as it is): the row puts the object's thread on it. Keep it stable. */\n readonly agentKey: AgentKey;\n /** The screen and the object on it; `preview` draws the object in the chat until the agent's verified card comes. */\n readonly place: AskAboutPlace;\n /** A question about the object, offered first in the chat as a chip the person taps; never sent in their name. */\n readonly question?: string;\n /**\n * The app's own word for this way in, for analytics: cut to 60 code points at a whole character (`entryLabel`).\n * Default: the place's screen.\n */\n readonly entryLabel?: string;\n /** The contract's type for the object, when the app's `place.entity.type` is a word of its own (\"space\"). */\n readonly anchorType?: AgentAnchorType;\n /** The person asks: the runtime was told the place for the object's key; open `<AgentChat {...open} />`. */\n readonly onPress: (open: AskAboutOpen) => void;\n /** The app's brand mark at the row's start; default the agent name's first letter. */\n readonly Mark?: ComponentType<{\n readonly size: number;\n readonly color: string;\n }>;\n readonly appearance?: AskAboutRowAppearance;\n readonly locale?: string;\n readonly copy?: CopyOverrides;\n readonly theme?: ThemeOverrides;\n readonly colorScheme?: ColorSchemeSetting;\n /** The row's test id. Default `vinaverse-ask-about`. */\n readonly testID?: string;\n}\n\nexport function AskAboutRow(props: AskAboutRowProps): ReactNode {\n return (\n <CopyProvider locale={props.locale} copy={props.copy}>\n <ThemeProvider theme={props.theme} colorScheme={props.colorScheme}>\n <Row {...props} />\n </ThemeProvider>\n </CopyProvider>\n );\n}\n\nfunction Row(props: AskAboutRowProps): ReactNode {\n const { t } = useCopy();\n const { colors, radius, space, font } = useTheme();\n const name = useAgentName(t('agentFallbackName'));\n const runtime = useAgentRuntime();\n useAgentStatus(); // reads the status when none is held, for the pages after this one\n useAgentSweep(runtime);\n // Decided once, as the page draws, from the status already read: an agent unknown or unavailable then stays away for\n // the visit, and the row is never added under content the person is reading.\n const [shows] = useState(() => !!runtime.getStatus()?.available);\n if (!shows) return null;\n const { Mark, appearance: look } = props;\n const press = () => {\n const { preview: _, ...place } = props.place;\n const agentKey = askAboutKey(props.agentKey, place);\n const open: AskAboutOpen = {\n entryPoint: 'ask',\n agentKey,\n place: props.place,\n askAbout: props.question ?? null,\n entry: entryOf(props.entryLabel ?? place.screen),\n anchor: anchorRef(props.anchorType ?? place.entity.type, place.entity.id),\n };\n // Told before the chat opens, so its first session already knows where the person asks from.\n runtime.peek(agentKey).tell({\n place,\n entryPoint: 'ask',\n anchor: open.anchor,\n entry: open.entry,\n });\n props.onPress(open);\n };\n return (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel={\n props.body ? `${props.title}. ${props.body}` : props.title\n }\n onPress={press}\n style={({ pressed }) => ({\n flexDirection: 'row',\n alignItems: 'center',\n gap: space.md,\n padding: space.md,\n borderRadius: radius.lg,\n backgroundColor: look?.background ?? colors.surface,\n opacity: pressed ? 0.85 : 1,\n })}\n testID={props.testID ?? 'vinaverse-ask-about'}\n >\n <View\n style={{\n width: 36,\n height: 36,\n borderRadius: 18,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: colors.primary,\n }}\n >\n {Mark ? (\n <Mark size={22} color={colors.onPrimary} />\n ) : (\n <Text style={{ color: colors.onPrimary, fontWeight: '600' }}>\n {(name.trim()[0] ?? '?').toUpperCase()}\n </Text>\n )}\n </View>\n <View style={{ flex: 1, gap: space.xxs }}>\n <Text\n style={{\n color: colors.text,\n fontSize: font.size.md,\n fontWeight: '600',\n }}\n >\n {props.title}\n </Text>\n {props.body ? (\n <Text style={{ color: colors.textMuted, fontSize: font.size.sm }}>\n {props.body}\n </Text>\n ) : null}\n </View>\n {look?.chevron === false ? null : (\n <Text style={{ color: colors.textMuted, fontSize: font.size.lg }}>\n ›\n </Text>\n )}\n </Pressable>\n );\n}\n\n/** `ask_about` with the app's word, cut as the contract takes it; without a label when nothing is left. */\nfunction entryOf(word: string): AgentEntry {\n const label = entryLabel(word);\n return label ? { point: 'ask_about', label } : { point: 'ask_about' };\n}\n"]}
@@ -1,10 +1,10 @@
1
- import { Button, useChat, FailureSlot, FailureActionButton, ChatContextProvider, ChatHeader, DisclosureBar, MessageList } from './chunk-KSHDF3MG.js';
2
- import { useTheme, useNativeLifecycle, themeProblems, ThemeProvider, useAgentSweep } from './chunk-EFEXTVIT.js';
1
+ import { Button, useChat, FailureSlot, FailureActionButton, ChatContextProvider, ChatHeader, DisclosureBar, MessageList, allowedImage, CardFrame, Body, Title } from './chunk-QSMMC4RZ.js';
2
+ import { useTheme, useNativeLifecycle, themeProblems, ThemeProvider, useAgentSweep } from './chunk-35A77CNF.js';
3
3
  import { useAgentRuntime, useAgentConversation, useAgentName } from '@vinaverse/react/agent';
4
4
  export { AgentRuntimeProvider, forgetGreeting, greetedKey, useAgentConversation, useAgentFeatures, useAgentLauncher, useAgentName, useAgentProfile, useAgentRuntime, useAgentStatus, useAgentStatusState } from '@vinaverse/react/agent';
5
5
  import { useCopy, useConversationSelector, bannedWordsIn, CopyProvider } from '@vinaverse/react';
6
- import { useState, memo, useCallback, useMemo, useEffect, useRef } from 'react';
7
- import { View, TextInput, Text, Platform, KeyboardAvoidingView } from 'react-native';
6
+ import { useState, memo, useCallback, useMemo, useEffect, useRef, createContext, useContext } from 'react';
7
+ import { View, TextInput, Text, Platform, KeyboardAvoidingView, Image } from 'react-native';
8
8
  import { codePoints, MAX_TEXT } from '@vinaverse/client/conversation';
9
9
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
10
10
  import { motion } from '@vinaverse/tokens';
@@ -214,8 +214,13 @@ function VinaverseChatProvider(props) {
214
214
  agentAvatar,
215
215
  timeZone,
216
216
  starters,
217
- imagePolicy
217
+ imagePolicy,
218
+ welcomeChips,
219
+ listHeader,
220
+ disclosure
218
221
  } = props;
222
+ const times = props.messageTimes ?? true;
223
+ const messageTimes = times === false ? null : times === true ? 10 : times.gapMinutes ?? 10;
219
224
  const handlers = useRef(props);
220
225
  handlers.current = props;
221
226
  const slots = useStableSlots(components);
@@ -234,7 +239,11 @@ function VinaverseChatProvider(props) {
234
239
  timeZone,
235
240
  failureAction,
236
241
  starters,
237
- imagePolicy
242
+ imagePolicy,
243
+ messageTimes,
244
+ welcomeChips: welcomeChips !== false,
245
+ listHeader,
246
+ disclosure
238
247
  }),
239
248
  [
240
249
  conversation,
@@ -243,7 +252,11 @@ function VinaverseChatProvider(props) {
243
252
  timeZone,
244
253
  failureAction,
245
254
  starters,
246
- imagePolicy
255
+ imagePolicy,
256
+ messageTimes,
257
+ welcomeChips,
258
+ listHeader,
259
+ disclosure
247
260
  ]
248
261
  );
249
262
  useNativeLifecycle(conversation);
@@ -264,7 +277,10 @@ function VinaverseChatProvider(props) {
264
277
  return /* @__PURE__ */ jsx(CopyProvider, { locale: props.locale, copy: props.copy, children: /* @__PURE__ */ jsx(ThemeProvider, { theme: props.theme, colorScheme: props.colorScheme, children: /* @__PURE__ */ jsx(ChatContextProvider, { value, children: props.children }) }) });
265
278
  }
266
279
  function VinaverseChat(props) {
267
- return /* @__PURE__ */ jsx(VinaverseChatProvider, { ...props, children: /* @__PURE__ */ jsx(
280
+ return /* @__PURE__ */ jsx(VinaverseChatProvider, { ...props, children: /* @__PURE__ */ jsx(ChatBody, { ...props }) });
281
+ }
282
+ function ChatBody(props) {
283
+ return /* @__PURE__ */ jsx(
268
284
  Layout,
269
285
  {
270
286
  hideHeader: props.hideHeader === true,
@@ -276,7 +292,7 @@ function VinaverseChat(props) {
276
292
  suggestionTestID: props.suggestionTestID ?? "vinaverse-suggestion",
277
293
  footer: props.footer
278
294
  }
279
- ) });
295
+ );
280
296
  }
281
297
  function Layout(props) {
282
298
  const { colors } = useTheme();
@@ -345,6 +361,8 @@ function AgentChat(props) {
345
361
  agentKey,
346
362
  place,
347
363
  entryPoint,
364
+ entry,
365
+ anchor,
348
366
  askAbout,
349
367
  onContact,
350
368
  onOpenPrivacy,
@@ -356,15 +374,25 @@ function AgentChat(props) {
356
374
  } = props;
357
375
  const runtime = useAgentRuntime();
358
376
  useAgentSweep(runtime);
377
+ const { preview, ...told } = place ?? {};
359
378
  const { conversation, state, startNew } = useAgentConversation(agentKey, {
360
- place: place ?? null,
361
- entryPoint: entryPoint ?? null
379
+ place: place ? told : null,
380
+ entryPoint: entryPoint ?? null,
381
+ anchor: anchor ?? null,
382
+ entry: entry ?? null
362
383
  });
363
384
  const store = conversation.store;
364
385
  const spoke = useConversationSelector(
365
386
  store,
366
387
  (v) => v.items.some((i) => i.type === "message" && i.role === "person")
367
388
  );
389
+ const aboutType = anchor?.type ?? place?.entity?.type;
390
+ const verified = useConversationSelector(
391
+ store,
392
+ (v) => v.items.some(
393
+ (i) => i.type === "card" && i.card.kind === "anchor" && i.card.card.anchor?.anchor_type === aboutType
394
+ )
395
+ );
368
396
  const { Ended, Unreachable, UnavailableScreen, Footer, ...slots } = components ?? {};
369
397
  const copy = useMemo(
370
398
  () => agentName ? { ...props.copy, agentFallbackName: agentName } : props.copy,
@@ -404,6 +432,7 @@ function AgentChat(props) {
404
432
  conversation: store,
405
433
  components: slots
406
434
  };
435
+ let screen = null;
407
436
  if (state.failure === "ended") {
408
437
  const own = {
409
438
  onStartNew: startNew,
@@ -411,41 +440,62 @@ function AgentChat(props) {
411
440
  code: state.code,
412
441
  onContact
413
442
  };
414
- return /* @__PURE__ */ jsx(VinaverseChatProvider, { ...shared, children: /* @__PURE__ */ jsx(Centered, { children: Ended ? /* @__PURE__ */ jsx(Ended, { ...own, Default: DefaultEnded }) : /* @__PURE__ */ jsx(DefaultEnded, { ...own }) }) });
415
- }
416
- if (state.failure === "unreachable") {
443
+ screen = Ended ? /* @__PURE__ */ jsx(Ended, { ...own, Default: DefaultEnded }) : /* @__PURE__ */ jsx(DefaultEnded, { ...own });
444
+ } else if (state.failure === "unreachable") {
417
445
  const own = {
418
446
  onRetry: conversation.retry,
419
447
  reason: state.reason,
420
448
  onContact
421
449
  };
422
- return /* @__PURE__ */ jsx(VinaverseChatProvider, { ...shared, children: /* @__PURE__ */ jsx(Centered, { children: Unreachable ? /* @__PURE__ */ jsx(Unreachable, { ...own, Default: DefaultUnreachable }) : /* @__PURE__ */ jsx(DefaultUnreachable, { ...own }) }) });
423
- }
424
- if (state.failure === "unavailable") {
450
+ screen = Unreachable ? /* @__PURE__ */ jsx(Unreachable, { ...own, Default: DefaultUnreachable }) : /* @__PURE__ */ jsx(DefaultUnreachable, { ...own });
451
+ } else if (state.failure === "unavailable") {
425
452
  const own = {
426
453
  reason: state.reason,
427
454
  code: state.code,
428
455
  onContact,
429
456
  onRetry: conversation.retry
430
457
  };
431
- return /* @__PURE__ */ jsx(VinaverseChatProvider, { ...shared, children: /* @__PURE__ */ jsx(Centered, { children: UnavailableScreen ? /* @__PURE__ */ jsx(UnavailableScreen, { ...own, Default: DefaultUnavailableScreen }) : /* @__PURE__ */ jsx(DefaultUnavailableScreen, { ...own }) }) });
458
+ screen = UnavailableScreen ? /* @__PURE__ */ jsx(UnavailableScreen, { ...own, Default: DefaultUnavailableScreen }) : /* @__PURE__ */ jsx(DefaultUnavailableScreen, { ...own });
432
459
  }
433
460
  const offered = opener && !spoke ? opener : null;
461
+ const shownTitle = preview && !verified ? preview.title : null;
462
+ const shownPhoto = preview?.image_url;
463
+ const header = useMemo(
464
+ () => shownTitle === null ? null : /* @__PURE__ */ jsx(
465
+ Provisional,
466
+ {
467
+ preview: {
468
+ title: shownTitle,
469
+ ...shownPhoto ? { image_url: shownPhoto } : {}
470
+ }
471
+ }
472
+ ),
473
+ [shownTitle, shownPhoto]
474
+ );
475
+ const leads = !offered && !spoke && !!askAbout && !!place?.entity;
434
476
  return /* @__PURE__ */ jsx(
435
- VinaverseChat,
477
+ VinaverseChatProvider,
436
478
  {
437
479
  ...shared,
438
- suggestion: offered ?? (state.moved && askAbout ? { label: askAbout, message: askAbout } : null),
439
- ...offered ? { suggestionTestID: openerTestID ?? "vinaverse-opener" } : {},
440
- footer: Footer === null ? null : /* @__PURE__ */ jsx(
441
- FooterFor,
480
+ welcomeChips: !leads,
481
+ listHeader: header,
482
+ children: screen ? /* @__PURE__ */ jsx(Centered, { children: /* @__PURE__ */ jsx(ScreenMode.Provider, { value: agentKey.mode, children: screen }) }) : /* @__PURE__ */ jsx(
483
+ ChatBody,
442
484
  {
443
- store,
444
- state,
445
- rate: conversation.rate,
446
- canRate: conversation.canRate,
447
- Footer,
448
- onOpenPrivacy
485
+ ...shared,
486
+ suggestion: offered ?? ((leads || state.moved) && askAbout ? { label: askAbout, message: askAbout } : null),
487
+ ...offered ? { suggestionTestID: openerTestID ?? "vinaverse-opener" } : {},
488
+ footer: Footer === null ? null : /* @__PURE__ */ jsx(
489
+ FooterFor,
490
+ {
491
+ store,
492
+ state,
493
+ rate: conversation.rate,
494
+ canRate: conversation.canRate,
495
+ Footer,
496
+ onOpenPrivacy
497
+ }
498
+ )
449
499
  }
450
500
  )
451
501
  }
@@ -474,6 +524,36 @@ function newestWholeReply(view) {
474
524
  }
475
525
  return null;
476
526
  }
527
+ var ScreenMode = /* @__PURE__ */ createContext(void 0);
528
+ function Provisional(props) {
529
+ const { title, image_url } = props.preview;
530
+ const { slots, imagePolicy } = useChat();
531
+ const { t } = useCopy();
532
+ const { radius, space } = useTheme();
533
+ const url = allowedImage(image_url, imagePolicy?.hosts);
534
+ const Img = slots.Image ?? Image;
535
+ return /* @__PURE__ */ jsx(
536
+ CardFrame,
537
+ {
538
+ label: `${t("askingAbout")} ${title}`,
539
+ testID: "vinaverse-ask-preview",
540
+ children: /* @__PURE__ */ jsxs(View, { style: { flexDirection: "row", gap: space.sm }, children: [
541
+ url ? /* @__PURE__ */ jsx(
542
+ Img,
543
+ {
544
+ source: { uri: url },
545
+ style: { width: 40, height: 40, borderRadius: radius.md },
546
+ testID: "vinaverse-ask-preview-photo"
547
+ }
548
+ ) : null,
549
+ /* @__PURE__ */ jsxs(View, { style: { flex: 1 }, children: [
550
+ /* @__PURE__ */ jsx(Body, { muted: true, children: t("askingAbout") }),
551
+ /* @__PURE__ */ jsx(Title, { numberOfLines: 1, children: title })
552
+ ] })
553
+ ] })
554
+ }
555
+ );
556
+ }
477
557
  function Centered(props) {
478
558
  const { colors, space } = useTheme();
479
559
  return /* @__PURE__ */ jsx(
@@ -547,7 +627,7 @@ function DefaultEnded(props) {
547
627
  }
548
628
  function DefaultUnavailableScreen(props) {
549
629
  const { t } = useCopy();
550
- const name = useAgentName(t("agentFallbackName"));
630
+ const name = useAgentName(t("agentFallbackName"), useContext(ScreenMode));
551
631
  const title = t("agentOff", { agent: name });
552
632
  return /* @__PURE__ */ jsx(
553
633
  Notice,
@@ -560,7 +640,7 @@ function DefaultUnavailableScreen(props) {
560
640
  }
561
641
  function DefaultUnreachable(props) {
562
642
  const { t } = useCopy();
563
- const name = useAgentName(t("agentFallbackName"));
643
+ const name = useAgentName(t("agentFallbackName"), useContext(ScreenMode));
564
644
  return /* @__PURE__ */ jsx(
565
645
  Notice,
566
646
  {
@@ -620,5 +700,5 @@ function AgentFooter(props) {
620
700
  }
621
701
 
622
702
  export { AgentChat, AgentFooter, Composer, DefaultComposer, DefaultEnded, DefaultUnavailable, DefaultUnavailableScreen, DefaultUnreachable, StatusBanner, VinaverseChat, VinaverseChatProvider, newestWholeReply };
623
- //# sourceMappingURL=chunk-2J2LIJLW.js.map
624
- //# sourceMappingURL=chunk-2J2LIJLW.js.map
703
+ //# sourceMappingURL=chunk-MCVW6TZD.js.map
704
+ //# sourceMappingURL=chunk-MCVW6TZD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Composer.tsx","../src/components/StatusBanner.tsx","../src/components/VinaverseChat.tsx","../src/components/AgentChat.tsx"],"names":["Composer","memo","StatusBanner","useCopy","useConversationSelector","useState","jsx","jsxs","View","useMemo","useEffect","Text"],"mappings":"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","file":"chunk-MCVW6TZD.js","sourcesContent":["// Where the person types. Its text is its own state, so typing renders nothing else. Enabled from the first frame:\n// a message typed before the session is ready is held and sent once it is. Stop replaces Send while the agent\n// replies and nothing is typed.\nimport { codePoints, MAX_TEXT } from '@vinaverse/client/conversation';\nimport { useConversationSelector, useCopy } from '@vinaverse/react';\nimport { memo, useCallback, useState } from 'react';\nimport { TextInput, View } from 'react-native';\nimport { useChat } from '../context.js';\nimport { useTheme } from '../theme.js';\nimport { Button } from './Button.js';\nimport type { ComposerProps } from './types.js';\n\nexport function DefaultComposer(props: Omit<ComposerProps, 'Default'>) {\n const { t, direction } = useCopy();\n const { colors, radius, space, font, size } = useTheme();\n const [text, setText] = useState('');\n const length = codePoints(text);\n const canSend = text.trim().length > 0 && length <= MAX_TEXT;\n const send = () => {\n if (!canSend) return;\n props.onSend(text);\n setText('');\n };\n return (\n <View\n style={{\n flexDirection: 'row',\n alignItems: 'flex-end',\n gap: space.sm,\n paddingHorizontal: space.lg,\n paddingVertical: space.sm,\n borderTopWidth: 1,\n borderTopColor: colors.divider,\n backgroundColor: colors.background,\n }}\n >\n <TextInput\n value={text}\n onChangeText={setText}\n placeholder={props.placeholder}\n placeholderTextColor={colors.textMuted}\n accessibilityLabel={props.placeholder}\n multiline\n maxLength={MAX_TEXT * 2}\n testID=\"vinaverse-composer-input\"\n style={{\n flex: 1,\n minHeight: size.touchTarget,\n maxHeight: 140,\n paddingHorizontal: space.md,\n paddingVertical: space.sm,\n borderRadius: radius.lg,\n borderWidth: 1,\n borderColor: colors.border,\n color: colors.text,\n backgroundColor: colors.surface,\n fontSize: font.size.md,\n textAlign: direction === 'rtl' ? 'right' : 'left',\n writingDirection: direction,\n ...(font.family ? { fontFamily: font.family } : {}),\n }}\n />\n {props.responding && !text ? (\n <Button\n label={t('stop')}\n onPress={props.onStop}\n testID=\"vinaverse-stop\"\n />\n ) : (\n <Button\n label={t('send')}\n variant=\"primary\"\n disabled={!canSend}\n onPress={send}\n testID=\"vinaverse-send\"\n />\n )}\n </View>\n );\n}\n\nexport const Composer = /* @__PURE__ */ memo(function Composer(props: {\n readonly onError?: (error: unknown) => void;\n}) {\n const { store, slots } = useChat();\n const { t } = useCopy();\n const takeover = useConversationSelector(store, (v) => v.takeover);\n const name = useConversationSelector(store, (v) => v.agent.name);\n const responding = useConversationSelector(store, (v) => v.responding);\n const { onError } = props;\n const onSend = useCallback(\n (text: string) => {\n try {\n store.send(text);\n } catch (error) {\n onError?.(error);\n }\n },\n [store, onError],\n );\n const onStop = useCallback(() => store.cancel(), [store]);\n const placeholder = takeover\n ? t('composerPlaceholderTakeover', {\n by: takeover.by || t('staffFallbackRole'),\n })\n : t('composerPlaceholder', { agent: name ?? t('agentFallbackName') });\n const Slot = slots.Composer;\n const own = { placeholder, responding, onSend, onStop };\n return Slot ? (\n <Slot {...own} Default={DefaultComposer} />\n ) : (\n <DefaultComposer {...own} />\n );\n});\n","// What the connection means for the person, in words, with the one action that helps: continue here, or try again;\n// on \"couldn't connect\", also the tenant's way out (`Failure.tsx`), or the tenant's own part in its place.\n// \"Connecting…\" waits 600 ms, so a quick connection never flashes a banner.\nimport { useConversationSelector, useCopy } from '@vinaverse/react';\nimport { motion } from '@vinaverse/tokens';\nimport { memo, type ReactNode, useEffect, useMemo, useState } from 'react';\nimport { Text, View } from 'react-native';\nimport { useChat } from '../context.js';\nimport { useTheme } from '../theme.js';\nimport { Button } from './Button.js';\nimport { FailureActionButton, FailureSlot } from './Failure.js';\nimport type { FailureState } from './types.js';\n\n/** How long \"Connecting…\" waits, shared with the Angular kit (`motion.bannerDelay`). */\nexport const CONNECTING_DELAY = motion.bannerDelay;\n\nexport const StatusBanner = /* @__PURE__ */ memo(function StatusBanner() {\n const { store, slots } = useChat();\n const { t } = useCopy();\n const banner = useConversationSelector(store, (v) => v.banner);\n const status = useConversationSelector(store, (v) => v.status);\n const conversationId = useConversationSelector(\n store,\n (v) => v.conversationId,\n );\n const unavailable = useMemo<FailureState>(\n () => ({\n kind: 'unavailable',\n reason: status,\n retry: () => store.start(),\n conversationId,\n }),\n [store, status, conversationId],\n );\n const [late, setLate] = useState(false);\n useEffect(() => {\n setLate(false);\n if (banner !== 'connecting') return;\n const timer = setTimeout(() => setLate(true), CONNECTING_DELAY);\n return () => clearTimeout(timer);\n }, [banner]);\n if (banner === null || (banner === 'connecting' && !late)) return null;\n if (banner === 'unavailable')\n return (\n <FailureSlot\n slot={slots.Unavailable}\n state={unavailable}\n Default={DefaultUnavailable}\n />\n );\n const text = {\n connecting: t('bannerConnecting'),\n reconnecting: t('bannerReconnecting'),\n offline: t('bannerOffline'),\n continued_elsewhere: t('bannerContinuedElsewhere'),\n }[banner];\n const action =\n banner === 'continued_elsewhere' ? (\n <Button\n label={t('continueHere')}\n variant=\"text\"\n onPress={() => void store.continueHere()}\n />\n ) : banner === 'offline' ? (\n <Button\n label={t('tryAgain')}\n variant=\"text\"\n onPress={() => store.start()}\n />\n ) : null;\n return <Banner text={text}>{action}</Banner>;\n});\n\n/** The kit's own \"Couldn't connect.\" banner: try again, and the tenant's failure action when there is one. */\nexport function DefaultUnavailable(props: {\n readonly state: FailureState;\n}): ReactNode {\n const { t } = useCopy();\n const { retry } = props.state;\n return (\n <Banner text={t('bannerUnavailable')}>\n {retry ? (\n <Button label={t('tryAgain')} variant=\"text\" onPress={retry} />\n ) : null}\n <FailureActionButton state={props.state} />\n </Banner>\n );\n}\n\nfunction Banner(props: {\n readonly text: string;\n readonly children?: ReactNode;\n}): ReactNode {\n const { colors, space, font } = useTheme();\n return (\n <View\n accessibilityLiveRegion=\"polite\"\n accessibilityRole=\"alert\"\n style={{\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: space.sm,\n paddingHorizontal: space.lg,\n paddingVertical: space.xs,\n backgroundColor: colors.surface,\n borderBottomWidth: 1,\n borderBottomColor: colors.divider,\n }}\n >\n <Text\n style={{ color: colors.text, fontSize: font.size.sm, flexShrink: 1 }}\n >\n {props.text}\n </Text>\n {props.children}\n </View>\n );\n}\n","// The whole conversation, ready to drop into a screen: header, the AI disclosure, the connection's banner, the\n// messages and cards, the composer. Everything visual is replaceable through `theme`, `copy` and `components`; the\n// disclosure, who-wrote-what and the proposal wiring are the kit's and stay.\nimport type { ConversationStore } from '@vinaverse/client/conversation';\nimport {\n bannedWordsIn,\n type CopyOverrides,\n CopyProvider,\n useCopy,\n} from '@vinaverse/react';\nimport {\n type ReactElement,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\nimport {\n KeyboardAvoidingView,\n Platform,\n type StyleProp,\n View,\n type ViewStyle,\n} from 'react-native';\nimport {\n ChatContextProvider,\n type ChatHandlers,\n type ChatSlots,\n type ChatWarning,\n type Chip,\n type ImagePolicy,\n useChat,\n} from '../context.js';\nimport { useNativeLifecycle } from '../platform.js';\nimport {\n type ColorSchemeSetting,\n type ThemeOverrides,\n ThemeProvider,\n themeProblems,\n useTheme,\n} from '../theme.js';\nimport { Button } from './Button.js';\nimport { ChatHeader } from './ChatHeader.js';\nimport { Composer } from './Composer.js';\nimport { DisclosureBar } from './DisclosureBar.js';\nimport { MessageList } from './MessageList.js';\nimport { StatusBanner } from './StatusBanner.js';\n\nexport interface VinaverseChatProps extends ChatHandlers {\n /** The conversation (`createConversation`), created where it can outlive the screen. */\n readonly conversation: ConversationStore;\n /** The person's locale: the copy, dates, money and text direction (pass the same one to `getSession`). */\n readonly locale?: string;\n /** For dates and times on cards; default: the device's. */\n readonly timeZone?: string;\n readonly copy?: CopyOverrides;\n readonly theme?: ThemeOverrides;\n readonly colorScheme?: ColorSchemeSetting;\n /** Parts to replace. Keep the object stable (module level, or memoized). */\n readonly components?: ChatSlots;\n /** The agent's picture, until the session carries one. */\n readonly agentAvatar?: string;\n /** Hide the header (a screen that draws its own); the disclosure stays. */\n readonly hideHeader?: boolean;\n /** iOS: the height above the keyboard that is not this view's (a navigation header). */\n readonly keyboardVerticalOffset?: number;\n /**\n * How the composer stays above the keyboard. Default: `padding` on iOS, none on Android (the window resizes). An\n * edge-to-edge Android app whose window does not resize passes `padding`; one that manages the keyboard itself\n * (react-native-keyboard-controller) passes `none`.\n */\n readonly keyboardBehavior?: 'padding' | 'height' | 'position' | 'none';\n readonly style?: StyleProp<ViewStyle>;\n /**\n * The AI disclosure the app already holds for this conversation (its cache, or the open's answer): drawn from the\n * first frame until the session's own arrives, in the same bar. Default: the kit's line.\n */\n readonly disclosure?: string;\n /** Chips for an empty conversation when the session brings no welcome (`Session.welcome` comes first). Keep stable. */\n readonly starters?: readonly Chip[];\n /** False: the welcome's chips and the starters give way, its text stays (`AgentChat`: a question about an object leads). */\n readonly welcomeChips?: boolean;\n /** Which card photos are drawn, their frame, and what stands in for one that is not. Keep stable. */\n readonly imagePolicy?: ImagePolicy;\n /** One chip above the composer: a question about where the person now is (`AgentChat` offers it when they moved). */\n readonly suggestion?: Chip | null;\n /** The suggestion chip's test id. Default `vinaverse-suggestion`. */\n readonly suggestionTestID?: string;\n /** Drawn under the composer, inside the kit's providers (`AgentChat`'s thumbs and footer). */\n readonly footer?: ReactNode;\n /**\n * When each message was sent: its time over the first message and over one after `gapMinutes` (default 10) of quiet,\n * and the exact date and time in every message's screen-reader label, in `locale` and `timeZone`. `false` draws none.\n * The line is the `MessageTime` slot. Default on.\n */\n readonly messageTimes?: boolean | { readonly gapMinutes?: number };\n /**\n * Drawn as the conversation's first row, scrolling with it (`AgentChat`: the object asked about, until its verified\n * card takes the same place). Keep it stable.\n */\n readonly listHeader?: ReactElement | null;\n}\n\n/** The providers alone, for a tenant composing its own layout from the exported parts. */\nexport function VinaverseChatProvider(\n props: Omit<\n VinaverseChatProps,\n | 'hideHeader'\n | 'keyboardVerticalOffset'\n | 'keyboardBehavior'\n | 'style'\n | 'suggestion'\n | 'suggestionTestID'\n | 'footer'\n > & {\n readonly children?: ReactNode;\n },\n): ReactNode {\n const {\n conversation,\n components,\n agentAvatar,\n timeZone,\n starters,\n imagePolicy,\n welcomeChips,\n listHeader,\n disclosure,\n } = props;\n const times = props.messageTimes ?? true;\n const messageTimes =\n times === false ? null : times === true ? 10 : (times.gapMinutes ?? 10);\n const handlers = useRef<ChatHandlers>(props);\n handlers.current = props;\n const slots = useStableSlots(components);\n const hasAction = props.failureAction !== undefined;\n const actionLabel = props.failureAction?.label;\n const failureAction = useMemo(\n () => (hasAction ? { label: actionLabel } : null),\n [hasAction, actionLabel],\n );\n const value = useMemo(\n () => ({\n store: conversation,\n handlers,\n slots,\n agentAvatar,\n timeZone,\n failureAction,\n starters,\n imagePolicy,\n messageTimes,\n welcomeChips: welcomeChips !== false,\n listHeader,\n disclosure,\n }),\n [\n conversation,\n slots,\n agentAvatar,\n timeZone,\n failureAction,\n starters,\n imagePolicy,\n messageTimes,\n welcomeChips,\n listHeader,\n disclosure,\n ],\n );\n useNativeLifecycle(conversation);\n useEffect(() => {\n conversation.start(); // early: a client secret opens its first connection within two minutes\n }, [conversation]);\n const { onWarning, theme, copy } = props;\n useEffect(() => {\n if (!onWarning) return;\n for (const problem of themeProblems(theme))\n onWarning(`Vinaverse theme: ${problem}`, { code: 'theme' });\n for (const key of bannedWordsIn(copy ?? {}))\n onWarning(\n `Vinaverse copy: \"${key}\" says assistant, bot or crew; the copy says agent.`,\n { code: 'copy' },\n );\n }, [onWarning, theme, copy]);\n return (\n <CopyProvider locale={props.locale} copy={props.copy}>\n <ThemeProvider theme={props.theme} colorScheme={props.colorScheme}>\n <ChatContextProvider value={value}>\n {props.children}\n </ChatContextProvider>\n </ThemeProvider>\n </CopyProvider>\n );\n}\n\nexport function VinaverseChat(props: VinaverseChatProps): ReactNode {\n return (\n <VinaverseChatProvider {...props}>\n <ChatBody {...props} />\n </VinaverseChatProvider>\n );\n}\n\n/** The chat's layout, inside providers given above it (`AgentChat` keeps one root across its states). */\nexport function ChatBody(props: VinaverseChatProps): ReactNode {\n return (\n <Layout\n hideHeader={props.hideHeader === true}\n keyboardVerticalOffset={props.keyboardVerticalOffset ?? 0}\n keyboardBehavior={\n props.keyboardBehavior ?? (Platform.OS === 'ios' ? 'padding' : 'none')\n }\n style={props.style}\n onError={props.onWarning}\n suggestion={props.suggestion ?? null}\n suggestionTestID={props.suggestionTestID ?? 'vinaverse-suggestion'}\n footer={props.footer}\n />\n );\n}\n\nfunction Layout(props: {\n readonly hideHeader: boolean;\n readonly keyboardVerticalOffset: number;\n readonly keyboardBehavior: 'padding' | 'height' | 'position' | 'none';\n readonly style: StyleProp<ViewStyle> | undefined;\n readonly onError:\n | ((message: string, warning: ChatWarning) => void)\n | undefined;\n readonly suggestion: Chip | null;\n readonly suggestionTestID: string;\n readonly footer: ReactNode;\n}) {\n const { colors } = useTheme();\n const { direction } = useCopy();\n const { onError } = props;\n const reportError = useMemo(\n () =>\n onError\n ? (e: unknown) => onError(String(e), { code: 'send_failed' })\n : undefined,\n [onError],\n );\n return (\n <KeyboardAvoidingView\n {...(props.keyboardBehavior === 'none'\n ? { enabled: false }\n : { behavior: props.keyboardBehavior })}\n keyboardVerticalOffset={props.keyboardVerticalOffset}\n style={[\n { flex: 1, backgroundColor: colors.background, direction },\n props.style,\n ]}\n >\n {props.hideHeader ? null : <ChatHeader />}\n <DisclosureBar />\n <StatusBanner />\n <View style={{ flex: 1 }}>\n <MessageList />\n </View>\n {props.suggestion ? (\n <Suggestion chip={props.suggestion} testID={props.suggestionTestID} />\n ) : null}\n <Composer {...(reportError ? { onError: reportError } : {})} />\n {props.footer}\n </KeyboardAvoidingView>\n );\n}\n\n/** One chip above the composer; a tap sends its message as the person's own text. */\nfunction Suggestion(props: { readonly chip: Chip; readonly testID: string }) {\n const { store, handlers } = useChat();\n const { space } = useTheme();\n return (\n <View style={{ paddingHorizontal: space.lg, alignItems: 'flex-start' }}>\n <Button\n label={props.chip.label}\n testID={props.testID}\n onPress={() => {\n store.send(props.chip.message);\n handlers.current?.onChip?.(props.chip);\n }}\n />\n </View>\n );\n}\n\n/** The slots object, kept the same while its parts are the same, so an inline `components={{…}}` re-renders nothing. */\nfunction useStableSlots(slots: ChatSlots | undefined): ChatSlots {\n const held = useRef<ChatSlots>({});\n const next = slots ?? {};\n if (!sameSlots(held.current, next)) held.current = next;\n return held.current;\n}\n\nfunction sameSlots(a: ChatSlots, b: ChatSlots): boolean {\n const keys = new Set([...Object.keys(a), ...Object.keys(b)]) as Set<\n keyof ChatSlots\n >;\n for (const key of keys) {\n if (key === 'cards') {\n const ca = a.cards ?? {};\n const cb = b.cards ?? {};\n const kinds = new Set([...Object.keys(ca), ...Object.keys(cb)]);\n for (const kind of kinds) if (ca[kind] !== cb[kind]) return false;\n } else if (a[key] !== b[key]) return false;\n }\n return true;\n}\n","// The agent's conversation for a key, on the runtime: the chat itself (`VinaverseChat`), and around it what an app used\n// to build by hand: a conversation that ended (start a new one), the backend out of reach (try again), a person when\n// there is no agent, the session's welcome or the app's starters, a question about where the person now is, thumbs on\n// the newest whole reply, and a footer. Built only on the public hooks; every part is a slot.\nimport type {\n AgentAnchorRef,\n AgentEntry,\n AgentEntryPoint,\n AgentFailureReason,\n AgentKey,\n AgentPlace,\n AgentPlacePreview,\n AgentRating,\n} from '@vinaverse/client/agent';\nimport { useConversationSelector, useCopy } from '@vinaverse/react';\nimport {\n useAgentConversation,\n useAgentName,\n useAgentRuntime,\n} from '@vinaverse/react/agent';\nimport {\n type ComponentType,\n createContext,\n type ReactNode,\n useContext,\n useMemo,\n} from 'react';\nimport { Image, Text, View } from 'react-native';\nimport { allowedImage, Body, CardFrame, Title } from '../cards/CardFrame.js';\nimport { type ChatSlots, type Chip, useChat } from '../context.js';\nimport { useAgentSweep } from '../platform.js';\nimport { useTheme } from '../theme.js';\nimport { Button } from './Button.js';\nimport {\n ChatBody,\n type VinaverseChatProps,\n VinaverseChatProvider,\n} from './VinaverseChat.js';\n\n/**\n * The full-screen states (`Ended`, `Unreachable`, `UnavailableScreen`) are slots: each gets everything its screen\n * needs (why, the actions, a person to contact) and the kit's own part as `Default`, so an app replaces the layout and\n * the words entirely, or only the words through `copy`.\n */\nexport interface AgentEndedProps {\n readonly onStartNew: () => void;\n /** Why: `ended`, `not_found`, `expired`, `mismatch`, `completed`. */\n readonly reason: AgentFailureReason | null;\n /** The API's code (`conversation_not_found`, `conversation_expired`), when it gave one. */\n readonly code: string | null;\n /** A person instead (the chat's `onContact`); absent when the app gave none. */\n readonly onContact: (() => void) | undefined;\n}\n/** No agent here: switched off for this tenant, mode or person, or the backend refused the session. */\nexport interface AgentUnavailableScreenProps {\n /** Why: `off`, `auth`, `invalid_session`, … */\n readonly reason: AgentFailureReason | null;\n readonly code: string | null;\n /** A person instead (the chat's `onContact`); absent when the app gave none. */\n readonly onContact: (() => void) | undefined;\n /** Ask again (after a sign-in, or the agent switched back on). */\n readonly onRetry: () => void;\n}\nexport interface AgentUnreachableProps {\n readonly onRetry: () => void;\n /** Why: `network`, `server`, `rate_limited`, … */\n readonly reason: AgentFailureReason | null;\n /** A person instead (the chat's `onContact`); absent when the app gave none. */\n readonly onContact: (() => void) | undefined;\n}\n\n/** A slot gets the kit's own part as `Default`, to wrap rather than rewrite. */\ntype Slot<P> = ComponentType<P & { readonly Default: ComponentType<P> }>;\nexport interface AgentFooterProps {\n /** The newest whole reply's turn, to rate; null when there is none or it was restored from before. */\n readonly turnId: string | null;\n readonly rating: AgentRating | undefined;\n readonly onRate: (rating: AgentRating) => void;\n readonly onOpenPrivacy: (() => void) | undefined;\n}\n\nexport interface AgentChatSlots extends ChatSlots {\n readonly Ended?: Slot<AgentEndedProps>;\n readonly Unreachable?: Slot<AgentUnreachableProps>;\n /**\n * The whole screen when there is no agent (off, or the session refused). Not `Unavailable`: that is the chat's own\n * \"couldn't connect\" banner, still drawn for a session that drops.\n */\n readonly UnavailableScreen?: Slot<AgentUnavailableScreenProps>;\n /** Under the composer; null hides it. Default: thumbs on the newest whole reply, and the privacy link. */\n readonly Footer?: Slot<AgentFooterProps> | null;\n}\n\nexport interface AgentChatProps\n extends Omit<\n VinaverseChatProps,\n | 'conversation'\n | 'components'\n | 'suggestion'\n | 'suggestionTestID'\n | 'footer'\n | 'listHeader'\n | 'welcomeChips'\n > {\n /** Whose conversation: one per person, mode, business and thread. */\n readonly agentKey: AgentKey;\n /**\n * Where the person asks from, told to the agent as a session opens. Its `preview` (from `AskAboutRow`) is drawn as the\n * conversation's first row, in a card's frame, until the agent's verified card of that object (an `anchor` card)\n * arrives and takes its place; never sent.\n */\n readonly place?:\n | (AgentPlace & { readonly preview?: AgentPlacePreview })\n | null;\n /** How the person came in: `launcher` and `ask` from the kit's parts, `deep_link`, or the app's own words. */\n readonly entryPoint?: AgentEntryPoint | null;\n /** How the person came in, in the contract's words (`ask_about`); sent only with the runtime's `sendAnchor`. */\n readonly entry?: AgentEntry | null;\n /** The object the conversation is about (contracts#86); sent only with the runtime's `sendAnchor`. */\n readonly anchor?: AgentAnchorRef | null;\n /**\n * The question about this place. At an object (`place.entity`), before the person says anything, it leads: a chip\n * above the composer, the welcome's own chips giving way. Elsewhere it is offered when the session was told another\n * place (`moved`).\n */\n readonly askAbout?: string | null;\n /** A person: offered on a failed turn, \"couldn't connect\" and no agent. */\n readonly onContact?: () => void;\n readonly onOpenPrivacy?: () => void;\n /** The agent's name until the session or the status gives one. */\n readonly agentName?: string;\n /**\n * A first question for a flow that asks for itself (setting a business up): a chip the person taps, offered until they\n * say anything. Never sent in their name: what the transcript shows as theirs, they typed or tapped.\n */\n readonly opener?: Chip | null;\n /** The opener chip's test id. Default `vinaverse-opener`. */\n readonly openerTestID?: string;\n readonly components?: AgentChatSlots;\n}\n\nexport function AgentChat(props: AgentChatProps): ReactNode {\n const {\n agentKey,\n place,\n entryPoint,\n entry,\n anchor,\n askAbout,\n onContact,\n onOpenPrivacy,\n components,\n agentName,\n opener,\n openerTestID,\n ...chat\n } = props;\n const runtime = useAgentRuntime();\n useAgentSweep(runtime);\n const { preview, ...told } = place ?? {};\n const { conversation, state, startNew } = useAgentConversation(agentKey, {\n place: place ? (told as AgentPlace) : null,\n entryPoint: entryPoint ?? null,\n anchor: anchor ?? null,\n entry: entry ?? null,\n });\n const store = conversation.store;\n const spoke = useConversationSelector(store, (v) =>\n v.items.some((i) => i.type === 'message' && i.role === 'person'),\n );\n // The agent's verified card of this object gives the preview way: an `anchor` card of its type. A conversation is\n // about one object (the gateway refuses a resume about another), and the gateway's card carries no `ref`.\n const aboutType = anchor?.type ?? place?.entity?.type;\n const verified = useConversationSelector(store, (v) =>\n v.items.some(\n (i) =>\n i.type === 'card' &&\n i.card.kind === 'anchor' &&\n (i.card.card as { anchor?: { anchor_type?: string } }).anchor\n ?.anchor_type === aboutType,\n ),\n );\n const { Ended, Unreachable, UnavailableScreen, Footer, ...slots } =\n components ?? {};\n const copy = useMemo(\n () =>\n agentName ? { ...props.copy, agentFallbackName: agentName } : props.copy,\n [agentName, props.copy],\n );\n const events = {\n onOpenTarget: chat.onOpenTarget\n ? (\n target: Parameters<NonNullable<typeof chat.onOpenTarget>>[0],\n card: Parameters<NonNullable<typeof chat.onOpenTarget>>[1],\n ) => {\n runtime.emit({\n type: 'target_opened',\n key: conversation.key,\n cardId: card.id,\n kind: target.type,\n });\n chat.onOpenTarget?.(target, card);\n }\n : undefined,\n onOpenLink: chat.onOpenLink\n ? (\n link: string,\n card: Parameters<NonNullable<typeof chat.onOpenLink>>[1],\n ) => {\n runtime.emit({\n type: 'link_opened',\n key: conversation.key,\n cardId: card.id,\n kind: card.kind,\n });\n chat.onOpenLink?.(link, card);\n }\n : undefined,\n onChip: (chip: Parameters<NonNullable<typeof chat.onChip>>[0]) => {\n runtime.emit({ type: 'chip_tapped', key: conversation.key });\n chat.onChip?.(chip);\n },\n };\n const shared = {\n ...chat,\n ...(events.onOpenTarget ? { onOpenTarget: events.onOpenTarget } : {}),\n ...(events.onOpenLink ? { onOpenLink: events.onOpenLink } : {}),\n onChip: events.onChip,\n ...(copy ? { copy } : {}),\n ...(onContact && !chat.failureAction\n ? { failureAction: { onPress: () => onContact() } }\n : {}),\n conversation: store,\n components: slots,\n };\n // One root whatever the state: the providers stay mounted, and only what is inside them changes.\n let screen: ReactNode = null;\n if (state.failure === 'ended') {\n const own: AgentEndedProps = {\n onStartNew: startNew,\n reason: state.reason,\n code: state.code,\n onContact,\n };\n screen = Ended ? (\n <Ended {...own} Default={DefaultEnded} />\n ) : (\n <DefaultEnded {...own} />\n );\n } else if (state.failure === 'unreachable') {\n const own: AgentUnreachableProps = {\n onRetry: conversation.retry,\n reason: state.reason,\n onContact,\n };\n screen = Unreachable ? (\n <Unreachable {...own} Default={DefaultUnreachable} />\n ) : (\n <DefaultUnreachable {...own} />\n );\n } else if (state.failure === 'unavailable') {\n const own: AgentUnavailableScreenProps = {\n reason: state.reason,\n code: state.code,\n onContact,\n onRetry: conversation.retry,\n };\n screen = UnavailableScreen ? (\n <UnavailableScreen {...own} Default={DefaultUnavailableScreen} />\n ) : (\n <DefaultUnavailableScreen {...own} />\n );\n }\n const offered = opener && !spoke ? opener : null;\n // One element while the preview and its verified card are the same, so the chat's context keeps its identity.\n const shownTitle = preview && !verified ? preview.title : null;\n const shownPhoto = preview?.image_url;\n const header = useMemo(\n () =>\n shownTitle === null ? null : (\n <Provisional\n preview={{\n title: shownTitle,\n ...(shownPhoto ? { image_url: shownPhoto } : {}),\n }}\n />\n ),\n [shownTitle, shownPhoto],\n );\n // At an object, the question about it leads until the person says anything; the welcome's chips give way.\n const leads = !offered && !spoke && !!askAbout && !!place?.entity;\n return (\n <VinaverseChatProvider\n {...shared}\n welcomeChips={!leads}\n listHeader={header}\n >\n {screen ? (\n <Centered>\n <ScreenMode.Provider value={agentKey.mode}>\n {screen}\n </ScreenMode.Provider>\n </Centered>\n ) : (\n <ChatBody\n {...shared}\n suggestion={\n offered ??\n ((leads || state.moved) && askAbout\n ? { label: askAbout, message: askAbout }\n : null)\n }\n {...(offered\n ? { suggestionTestID: openerTestID ?? 'vinaverse-opener' }\n : {})}\n footer={\n Footer === null ? null : (\n <FooterFor\n store={store}\n state={state}\n rate={conversation.rate}\n canRate={conversation.canRate}\n Footer={Footer}\n onOpenPrivacy={onOpenPrivacy}\n />\n )\n }\n />\n )}\n </VinaverseChatProvider>\n );\n}\n\nfunction FooterFor(props: {\n readonly store: Parameters<typeof useConversationSelector>[0];\n readonly state: { readonly ratings: ReadonlyMap<string, AgentRating> };\n readonly rate: (turnId: string, rating: AgentRating) => void;\n readonly canRate: (turnId: string) => boolean;\n readonly Footer: Slot<AgentFooterProps> | undefined;\n readonly onOpenPrivacy: (() => void) | undefined;\n}) {\n const newest = useConversationSelector(props.store, newestWholeReply);\n // A reply restored from before has no thumbs: it cannot be rated against the session it was given in.\n const turnId = newest && props.canRate(newest) ? newest : null;\n const own: AgentFooterProps = {\n turnId,\n rating: turnId ? props.state.ratings.get(turnId) : undefined,\n onRate: (rating) => {\n if (turnId) props.rate(turnId, rating);\n },\n onOpenPrivacy: props.onOpenPrivacy,\n };\n const { Footer } = props;\n return Footer ? (\n <Footer {...own} Default={AgentFooter} />\n ) : (\n <AgentFooter {...own} />\n );\n}\n\n/** The newest reply when it came whole (not cut off, not a refusal): the one to rate. */\nexport function newestWholeReply(view: {\n readonly items: readonly import('@vinaverse/client/conversation').TimelineItem[];\n}): string | null {\n for (let i = view.items.length - 1; i >= 0; i--) {\n const item = view.items[i];\n if (item?.type !== 'message' || item.role !== 'agent') continue;\n const whole =\n item.state === 'sent' &&\n !item.partial &&\n !item.refusal &&\n item.key.startsWith('a:');\n return whole ? item.key.slice(2) : null;\n }\n return null;\n}\n\n/** The conversation's mode, for the full screens' names: one side's agent is never named after the other's. */\nconst ScreenMode = /* @__PURE__ */ createContext<string | undefined>(undefined);\n\n/** The object as the page showed it, until the agent's verified card comes: its photo (by the image policy) and title. */\nfunction Provisional(props: { readonly preview: AgentPlacePreview }) {\n const { title, image_url } = props.preview;\n const { slots, imagePolicy } = useChat();\n const { t } = useCopy();\n const { radius, space } = useTheme();\n const url = allowedImage(image_url, imagePolicy?.hosts);\n const Img = slots.Image ?? Image;\n // In a card's frame where the verified card will be: when it comes, it takes this row's place.\n return (\n <CardFrame\n label={`${t('askingAbout')} ${title}`}\n testID=\"vinaverse-ask-preview\"\n >\n <View style={{ flexDirection: 'row', gap: space.sm }}>\n {url ? (\n <Img\n source={{ uri: url }}\n style={{ width: 40, height: 40, borderRadius: radius.md }}\n testID=\"vinaverse-ask-preview-photo\"\n />\n ) : null}\n <View style={{ flex: 1 }}>\n <Body muted>{t('askingAbout')}</Body>\n <Title numberOfLines={1}>{title}</Title>\n </View>\n </View>\n </CardFrame>\n );\n}\n\nfunction Centered(props: { readonly children: ReactNode }) {\n const { colors, space } = useTheme();\n return (\n <View\n style={{\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n padding: space.xl,\n backgroundColor: colors.background,\n }}\n >\n {props.children}\n </View>\n );\n}\n\nfunction Notice(props: {\n readonly title: string;\n readonly body: string;\n readonly action?: string;\n readonly onPress?: () => void;\n}) {\n const { colors, space, font } = useTheme();\n return (\n <View\n accessibilityRole=\"alert\"\n style={{ alignItems: 'center', gap: space.md }}\n >\n <Text\n style={{\n color: colors.text,\n fontSize: font.size.lg,\n fontWeight: '600',\n textAlign: 'center',\n }}\n >\n {props.title}\n </Text>\n <Text\n style={{\n color: colors.textMuted,\n fontSize: font.size.md,\n textAlign: 'center',\n }}\n >\n {props.body}\n </Text>\n {props.action && props.onPress ? (\n <Button\n label={props.action}\n variant=\"primary\"\n onPress={props.onPress}\n />\n ) : null}\n </View>\n );\n}\n\n/** The conversation is over: a new one starts only when the person asks. */\nexport function DefaultEnded(props: AgentEndedProps): ReactNode {\n const { t } = useCopy();\n return (\n <Notice\n title={t('agentEnded')}\n body={t('agentEndedBody')}\n action={t('agentStartOver')}\n onPress={props.onStartNew}\n />\n );\n}\n\n/** No agent here: says so, and offers a person when the app has one. */\nexport function DefaultUnavailableScreen(\n props: AgentUnavailableScreenProps,\n): ReactNode {\n const { t } = useCopy();\n const name = useAgentName(t('agentFallbackName'), useContext(ScreenMode));\n const title = t('agentOff', { agent: name });\n return (\n <Notice\n title={title.charAt(0).toUpperCase() + title.slice(1)}\n body={t('agentOffBody')}\n {...(props.onContact\n ? { action: t('talkToPerson'), onPress: props.onContact }\n : {})}\n />\n );\n}\n\n/** The app's backend could not be reached, after its tries: try again. */\nexport function DefaultUnreachable(props: AgentUnreachableProps): ReactNode {\n const { t } = useCopy();\n const name = useAgentName(t('agentFallbackName'), useContext(ScreenMode));\n return (\n <Notice\n title={t('agentUnreachable', { agent: name })}\n body={t('agentUnreachableBody')}\n action={t('tryAgain')}\n onPress={props.onRetry}\n />\n );\n}\n\n/** Thumbs on the newest whole reply (thanks once given), and the privacy link. */\nexport function AgentFooter(props: AgentFooterProps): ReactNode {\n const { t } = useCopy();\n const { colors, space, font } = useTheme();\n const muted = { color: colors.textMuted, fontSize: font.size.sm };\n return (\n <View\n style={{\n flexDirection: 'row',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: space.xs,\n paddingHorizontal: space.lg,\n }}\n >\n {props.turnId === null ? null : props.rating ? (\n <Text style={muted}>{t('helpfulThanks')}</Text>\n ) : (\n <>\n <Text style={muted}>{t('helpful')}</Text>\n <Button\n label={t('helpfulYes')}\n variant=\"text\"\n onPress={() => props.onRate('up')}\n />\n <Button\n label={t('helpfulNo')}\n variant=\"text\"\n onPress={() => props.onRate('down')}\n />\n </>\n )}\n {props.onOpenPrivacy ? (\n <Button\n label={t('privacy')}\n variant=\"text\"\n role=\"link\"\n onPress={props.onOpenPrivacy}\n />\n ) : null}\n </View>\n );\n}\n"]}