@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/README.md +66 -0
- package/dist/index.cjs +854 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +337 -90
- package/dist/index.d.ts +337 -90
- package/dist/index.js +808 -132
- package/dist/index.js.map +1 -1
- package/package.json +68 -8
package/README.md
CHANGED
|
@@ -33,6 +33,72 @@ export function AgentScreen() {
|
|
|
33
33
|
}
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
## Hosting the agent (the runtime)
|
|
37
|
+
|
|
38
|
+
An app that hosts the agent writes its backend once (`createAgentRuntime`, `@vinaverse/client/agent`) and draws the
|
|
39
|
+
parts; which conversation, keeping it across screens, waiting the backend out, a conversation that ended, the backend
|
|
40
|
+
out of reach, status, name, ratings and sign-out are the runtime's.
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { createAgentRuntime } from '@vinaverse/client/agent';
|
|
44
|
+
import { AgentChat, AgentLauncher, AgentRuntimeProvider, AskAboutRow, CardCarousel } from '@vinaverse/react-native';
|
|
45
|
+
|
|
46
|
+
const agent = createAgentRuntime({ backend: { openSession, refreshSecret, status }, conversation: { locale } });
|
|
47
|
+
const components = { CardGroup: CardCarousel, Image: ExpoImage }; // module level: stable
|
|
48
|
+
const imagePolicy = { hosts: ['images.example.com'], aspectRatio: 1.6, Placeholder: BrandTile }; // stable too
|
|
49
|
+
|
|
50
|
+
<AgentRuntimeProvider runtime={agent}>
|
|
51
|
+
<Tabs />
|
|
52
|
+
<AgentLauncher subject={user?.id ?? null} mode={side} Mark={YourMark}
|
|
53
|
+
route={currentTab} routes={['home', 'explore']} hidden={sheetOpen} // never with the keyboard up
|
|
54
|
+
storage={preferences} onOpen={({ route, mode }) => openChat(route, mode)}
|
|
55
|
+
style={{ position: 'absolute', right: 16, bottom: tabBarHeight + 16 }} />
|
|
56
|
+
</AgentRuntimeProvider>
|
|
57
|
+
|
|
58
|
+
// The chat screen
|
|
59
|
+
<AgentChat
|
|
60
|
+
agentKey={{ subject: user?.id ?? null, mode: side, scope: businessId }}
|
|
61
|
+
place={{ screen: 'professional', entity: { type: 'professional', id } }}
|
|
62
|
+
askAbout={`Tell me about ${name}`} // offered when the session was told another place
|
|
63
|
+
starters={startersFor(screen)} // when the session brings no welcome
|
|
64
|
+
components={components}
|
|
65
|
+
onOpenTarget={(t) => router.push(routeFor(t))} // a card about a professional, a space, a booking
|
|
66
|
+
onOpenLink={openLink}
|
|
67
|
+
onContact={() => router.push('/contact')} // a person, when the agent fails or is unavailable
|
|
68
|
+
onOpenPrivacy={() => router.push('/privacy')}
|
|
69
|
+
prefetchImage={(url) => Image.prefetch(url)}
|
|
70
|
+
imagePolicy={imagePolicy}
|
|
71
|
+
/>
|
|
72
|
+
|
|
73
|
+
// On the app's own page about a professional
|
|
74
|
+
<AskAboutRow title={`Ask ${agentName} about ${name}`} onPress={() => openChat('professional', side)} />
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- **Parts:** `AgentChat` draws the conversation, a conversation that ended (`components.Ended`, start over), the backend
|
|
78
|
+
out of reach (`components.Unreachable`, try again), no agent at all (`components.UnavailableScreen`, the whole
|
|
79
|
+
screen: off, or the session refused, with a person through `onContact`), and under the composer thumbs on the newest
|
|
80
|
+
whole reply and the privacy link (`components.Footer`, `null` to hide); each slot gets the kit's part as `Default`,
|
|
81
|
+
to wrap it. `opener` is a first question as a chip the person taps (a flow that asks for itself), until they say
|
|
82
|
+
anything; nothing is ever sent in their name. `AgentLauncher` is a round button with
|
|
83
|
+
a greeting bubble once per person and mode (`storage`: your preferences store; `greeting`: words or words by mode,
|
|
84
|
+
read through `announce`; `storageKey` maps the record to one your app already keeps, so nobody is greeted twice),
|
|
85
|
+
your `Mark` inside, floating where `placement` says (`edge`, `bottom` above your tab bar, `inset`; `style` after it),
|
|
86
|
+
with `appearance` (a `ring`, the `shadow`, the bubble's `tail`), shown on your `routes` only, never with the keyboard
|
|
87
|
+
up (`hideWithKeyboard`), stepping aside when you say (`hidden`), and only when the status offers it; its button,
|
|
88
|
+
bubble and entrance are slots (`LauncherButton`, `LauncherGreeting`, `LauncherEntrance`: a short fade and scale,
|
|
89
|
+
none with reduced motion). `AskAboutRow` is "ask the agent about this" on
|
|
90
|
+
your own pages, shown when the agent is available, decided once per visit.
|
|
91
|
+
- **Policies and adapters:** `imagePolicy` (photo hosts, frame, the stand-in for a missing photo) applies to every card
|
|
92
|
+
and every fetch ahead; `announce` reads finished replies and the greeting your way; `onChip` hears a tapped chip.
|
|
93
|
+
Card renderers get the card read once (`read`).
|
|
94
|
+
- **Hooks** for your own parts: `useAgentConversation`, `useAgentStatus`, `useAgentFeatures`, `useAgentProfile`,
|
|
95
|
+
`useAgentName`, `useAgentLauncher`, `useAgentRuntime`.
|
|
96
|
+
- **Events** for analytics through `onEvent`: sessions, ratings, chips, targets and links opened, the launcher shown,
|
|
97
|
+
opened, greeted and its greeting closed.
|
|
98
|
+
- **StrictMode, in development only:** React mounts, unmounts and mounts again, so a conversation still opening is let
|
|
99
|
+
go with the first unmount and the second mount asks your backend for another session: two `openSession` calls per
|
|
100
|
+
opening in development, one in a release build. The first request's answer is dropped, never shown.
|
|
101
|
+
|
|
36
102
|
## Install
|
|
37
103
|
|
|
38
104
|
```sh
|