@vinaverse/react-native 0.0.0-stage → 0.1.0-alpha.11

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 (57) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +326 -2
  3. package/dist/ask.cjs +62 -0
  4. package/dist/ask.cjs.map +1 -0
  5. package/dist/ask.d.cts +38 -0
  6. package/dist/ask.d.ts +38 -0
  7. package/dist/ask.js +5 -0
  8. package/dist/ask.js.map +1 -0
  9. package/dist/chat.cjs +274 -0
  10. package/dist/chat.cjs.map +1 -0
  11. package/dist/chat.d.cts +292 -0
  12. package/dist/chat.d.ts +292 -0
  13. package/dist/chat.js +5 -0
  14. package/dist/chat.js.map +1 -0
  15. package/dist/chunk-2J2LIJLW.js +624 -0
  16. package/dist/chunk-2J2LIJLW.js.map +1 -0
  17. package/dist/chunk-4PXQ7DEY.cjs +680 -0
  18. package/dist/chunk-4PXQ7DEY.cjs.map +1 -0
  19. package/dist/chunk-6QYDPGRS.cjs +97 -0
  20. package/dist/chunk-6QYDPGRS.cjs.map +1 -0
  21. package/dist/chunk-7KPCO443.js +74 -0
  22. package/dist/chunk-7KPCO443.js.map +1 -0
  23. package/dist/chunk-EFEXTVIT.js +88 -0
  24. package/dist/chunk-EFEXTVIT.js.map +1 -0
  25. package/dist/chunk-KSHDF3MG.js +1996 -0
  26. package/dist/chunk-KSHDF3MG.js.map +1 -0
  27. package/dist/chunk-MG32E4JI.cjs +268 -0
  28. package/dist/chunk-MG32E4JI.cjs.map +1 -0
  29. package/dist/chunk-NMKJ7LIJ.cjs +76 -0
  30. package/dist/chunk-NMKJ7LIJ.cjs.map +1 -0
  31. package/dist/chunk-POJP52GE.js +261 -0
  32. package/dist/chunk-POJP52GE.js.map +1 -0
  33. package/dist/chunk-XAG2P447.cjs +2035 -0
  34. package/dist/chunk-XAG2P447.cjs.map +1 -0
  35. package/dist/context-gHCLFsJh.d.cts +212 -0
  36. package/dist/context-gHCLFsJh.d.ts +212 -0
  37. package/dist/history.cjs +673 -0
  38. package/dist/history.cjs.map +1 -0
  39. package/dist/history.d.cts +177 -0
  40. package/dist/history.d.ts +177 -0
  41. package/dist/history.js +618 -0
  42. package/dist/history.js.map +1 -0
  43. package/dist/index.cjs +304 -0
  44. package/dist/index.cjs.map +1 -0
  45. package/dist/index.d.cts +12 -0
  46. package/dist/index.d.ts +12 -0
  47. package/dist/index.js +7 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/launcher.cjs +86 -0
  50. package/dist/launcher.cjs.map +1 -0
  51. package/dist/launcher.d.cts +122 -0
  52. package/dist/launcher.d.ts +122 -0
  53. package/dist/launcher.js +5 -0
  54. package/dist/launcher.js.map +1 -0
  55. package/dist/theme-BhiEGv64.d.cts +35 -0
  56. package/dist/theme-BhiEGv64.d.ts +35 -0
  57. package/package.json +311 -3
@@ -0,0 +1,680 @@
1
+ 'use strict';
2
+
3
+ var chunkXAG2P447_cjs = require('./chunk-XAG2P447.cjs');
4
+ var chunk6QYDPGRS_cjs = require('./chunk-6QYDPGRS.cjs');
5
+ var agent = require('@vinaverse/react/agent');
6
+ var react = require('@vinaverse/react');
7
+ var react$1 = require('react');
8
+ var reactNative = require('react-native');
9
+ var conversation = require('@vinaverse/client/conversation');
10
+ var jsxRuntime = require('react/jsx-runtime');
11
+ var tokens = require('@vinaverse/tokens');
12
+
13
+ function DefaultComposer(props) {
14
+ const { t, direction } = react.useCopy();
15
+ const { colors, radius, space, font, size } = chunk6QYDPGRS_cjs.useTheme();
16
+ const [text, setText] = react$1.useState("");
17
+ const length = conversation.codePoints(text);
18
+ const canSend = text.trim().length > 0 && length <= conversation.MAX_TEXT;
19
+ const send = () => {
20
+ if (!canSend) return;
21
+ props.onSend(text);
22
+ setText("");
23
+ };
24
+ return /* @__PURE__ */ jsxRuntime.jsxs(
25
+ reactNative.View,
26
+ {
27
+ style: {
28
+ flexDirection: "row",
29
+ alignItems: "flex-end",
30
+ gap: space.sm,
31
+ paddingHorizontal: space.lg,
32
+ paddingVertical: space.sm,
33
+ borderTopWidth: 1,
34
+ borderTopColor: colors.divider,
35
+ backgroundColor: colors.background
36
+ },
37
+ children: [
38
+ /* @__PURE__ */ jsxRuntime.jsx(
39
+ reactNative.TextInput,
40
+ {
41
+ value: text,
42
+ onChangeText: setText,
43
+ placeholder: props.placeholder,
44
+ placeholderTextColor: colors.textMuted,
45
+ accessibilityLabel: props.placeholder,
46
+ multiline: true,
47
+ maxLength: conversation.MAX_TEXT * 2,
48
+ testID: "vinaverse-composer-input",
49
+ style: {
50
+ flex: 1,
51
+ minHeight: size.touchTarget,
52
+ maxHeight: 140,
53
+ paddingHorizontal: space.md,
54
+ paddingVertical: space.sm,
55
+ borderRadius: radius.lg,
56
+ borderWidth: 1,
57
+ borderColor: colors.border,
58
+ color: colors.text,
59
+ backgroundColor: colors.surface,
60
+ fontSize: font.size.md,
61
+ textAlign: direction === "rtl" ? "right" : "left",
62
+ writingDirection: direction,
63
+ ...font.family ? { fontFamily: font.family } : {}
64
+ }
65
+ }
66
+ ),
67
+ props.responding && !text ? /* @__PURE__ */ jsxRuntime.jsx(
68
+ chunkXAG2P447_cjs.Button,
69
+ {
70
+ label: t("stop"),
71
+ onPress: props.onStop,
72
+ testID: "vinaverse-stop"
73
+ }
74
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
75
+ chunkXAG2P447_cjs.Button,
76
+ {
77
+ label: t("send"),
78
+ variant: "primary",
79
+ disabled: !canSend,
80
+ onPress: send,
81
+ testID: "vinaverse-send"
82
+ }
83
+ )
84
+ ]
85
+ }
86
+ );
87
+ }
88
+ var Composer = /* @__PURE__ */ react$1.memo(function Composer2(props) {
89
+ const { store, slots } = chunkXAG2P447_cjs.useChat();
90
+ const { t } = react.useCopy();
91
+ const takeover = react.useConversationSelector(store, (v) => v.takeover);
92
+ const name = react.useConversationSelector(store, (v) => v.agent.name);
93
+ const responding = react.useConversationSelector(store, (v) => v.responding);
94
+ const { onError } = props;
95
+ const onSend = react$1.useCallback(
96
+ (text) => {
97
+ try {
98
+ store.send(text);
99
+ } catch (error) {
100
+ onError?.(error);
101
+ }
102
+ },
103
+ [store, onError]
104
+ );
105
+ const onStop = react$1.useCallback(() => store.cancel(), [store]);
106
+ const placeholder = takeover ? t("composerPlaceholderTakeover", {
107
+ by: takeover.by || t("staffFallbackRole")
108
+ }) : t("composerPlaceholder", { agent: name ?? t("agentFallbackName") });
109
+ const Slot = slots.Composer;
110
+ const own = { placeholder, responding, onSend, onStop };
111
+ return Slot ? /* @__PURE__ */ jsxRuntime.jsx(Slot, { ...own, Default: DefaultComposer }) : /* @__PURE__ */ jsxRuntime.jsx(DefaultComposer, { ...own });
112
+ });
113
+ var CONNECTING_DELAY = tokens.motion.bannerDelay;
114
+ var StatusBanner = /* @__PURE__ */ react$1.memo(function StatusBanner2() {
115
+ const { store, slots } = chunkXAG2P447_cjs.useChat();
116
+ const { t } = react.useCopy();
117
+ const banner = react.useConversationSelector(store, (v) => v.banner);
118
+ const status = react.useConversationSelector(store, (v) => v.status);
119
+ const conversationId = react.useConversationSelector(
120
+ store,
121
+ (v) => v.conversationId
122
+ );
123
+ const unavailable = react$1.useMemo(
124
+ () => ({
125
+ kind: "unavailable",
126
+ reason: status,
127
+ retry: () => store.start(),
128
+ conversationId
129
+ }),
130
+ [store, status, conversationId]
131
+ );
132
+ const [late, setLate] = react$1.useState(false);
133
+ react$1.useEffect(() => {
134
+ setLate(false);
135
+ if (banner !== "connecting") return;
136
+ const timer = setTimeout(() => setLate(true), CONNECTING_DELAY);
137
+ return () => clearTimeout(timer);
138
+ }, [banner]);
139
+ if (banner === null || banner === "connecting" && !late) return null;
140
+ if (banner === "unavailable")
141
+ return /* @__PURE__ */ jsxRuntime.jsx(
142
+ chunkXAG2P447_cjs.FailureSlot,
143
+ {
144
+ slot: slots.Unavailable,
145
+ state: unavailable,
146
+ Default: DefaultUnavailable
147
+ }
148
+ );
149
+ const text = {
150
+ connecting: t("bannerConnecting"),
151
+ reconnecting: t("bannerReconnecting"),
152
+ offline: t("bannerOffline"),
153
+ continued_elsewhere: t("bannerContinuedElsewhere")
154
+ }[banner];
155
+ const action = banner === "continued_elsewhere" ? /* @__PURE__ */ jsxRuntime.jsx(
156
+ chunkXAG2P447_cjs.Button,
157
+ {
158
+ label: t("continueHere"),
159
+ variant: "text",
160
+ onPress: () => void store.continueHere()
161
+ }
162
+ ) : banner === "offline" ? /* @__PURE__ */ jsxRuntime.jsx(
163
+ chunkXAG2P447_cjs.Button,
164
+ {
165
+ label: t("tryAgain"),
166
+ variant: "text",
167
+ onPress: () => store.start()
168
+ }
169
+ ) : null;
170
+ return /* @__PURE__ */ jsxRuntime.jsx(Banner, { text, children: action });
171
+ });
172
+ function DefaultUnavailable(props) {
173
+ const { t } = react.useCopy();
174
+ const { retry } = props.state;
175
+ return /* @__PURE__ */ jsxRuntime.jsxs(Banner, { text: t("bannerUnavailable"), children: [
176
+ retry ? /* @__PURE__ */ jsxRuntime.jsx(chunkXAG2P447_cjs.Button, { label: t("tryAgain"), variant: "text", onPress: retry }) : null,
177
+ /* @__PURE__ */ jsxRuntime.jsx(chunkXAG2P447_cjs.FailureActionButton, { state: props.state })
178
+ ] });
179
+ }
180
+ function Banner(props) {
181
+ const { colors, space, font } = chunk6QYDPGRS_cjs.useTheme();
182
+ return /* @__PURE__ */ jsxRuntime.jsxs(
183
+ reactNative.View,
184
+ {
185
+ accessibilityLiveRegion: "polite",
186
+ accessibilityRole: "alert",
187
+ style: {
188
+ flexDirection: "row",
189
+ alignItems: "center",
190
+ justifyContent: "space-between",
191
+ gap: space.sm,
192
+ paddingHorizontal: space.lg,
193
+ paddingVertical: space.xs,
194
+ backgroundColor: colors.surface,
195
+ borderBottomWidth: 1,
196
+ borderBottomColor: colors.divider
197
+ },
198
+ children: [
199
+ /* @__PURE__ */ jsxRuntime.jsx(
200
+ reactNative.Text,
201
+ {
202
+ style: { color: colors.text, fontSize: font.size.sm, flexShrink: 1 },
203
+ children: props.text
204
+ }
205
+ ),
206
+ props.children
207
+ ]
208
+ }
209
+ );
210
+ }
211
+ function VinaverseChatProvider(props) {
212
+ const {
213
+ conversation,
214
+ components,
215
+ agentAvatar,
216
+ timeZone,
217
+ starters,
218
+ imagePolicy
219
+ } = props;
220
+ const handlers = react$1.useRef(props);
221
+ handlers.current = props;
222
+ const slots = useStableSlots(components);
223
+ const hasAction = props.failureAction !== void 0;
224
+ const actionLabel = props.failureAction?.label;
225
+ const failureAction = react$1.useMemo(
226
+ () => hasAction ? { label: actionLabel } : null,
227
+ [hasAction, actionLabel]
228
+ );
229
+ const value = react$1.useMemo(
230
+ () => ({
231
+ store: conversation,
232
+ handlers,
233
+ slots,
234
+ agentAvatar,
235
+ timeZone,
236
+ failureAction,
237
+ starters,
238
+ imagePolicy
239
+ }),
240
+ [
241
+ conversation,
242
+ slots,
243
+ agentAvatar,
244
+ timeZone,
245
+ failureAction,
246
+ starters,
247
+ imagePolicy
248
+ ]
249
+ );
250
+ chunk6QYDPGRS_cjs.useNativeLifecycle(conversation);
251
+ react$1.useEffect(() => {
252
+ conversation.start();
253
+ }, [conversation]);
254
+ const { onWarning, theme, copy } = props;
255
+ react$1.useEffect(() => {
256
+ if (!onWarning) return;
257
+ for (const problem of chunk6QYDPGRS_cjs.themeProblems(theme))
258
+ onWarning(`Vinaverse theme: ${problem}`, { code: "theme" });
259
+ for (const key of react.bannedWordsIn(copy ?? {}))
260
+ onWarning(
261
+ `Vinaverse copy: "${key}" says assistant, bot or crew; the copy says agent.`,
262
+ { code: "copy" }
263
+ );
264
+ }, [onWarning, theme, copy]);
265
+ return /* @__PURE__ */ jsxRuntime.jsx(react.CopyProvider, { locale: props.locale, copy: props.copy, children: /* @__PURE__ */ jsxRuntime.jsx(chunk6QYDPGRS_cjs.ThemeProvider, { theme: props.theme, colorScheme: props.colorScheme, children: /* @__PURE__ */ jsxRuntime.jsx(chunkXAG2P447_cjs.ChatContextProvider, { value, children: props.children }) }) });
266
+ }
267
+ function VinaverseChat(props) {
268
+ return /* @__PURE__ */ jsxRuntime.jsx(VinaverseChatProvider, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx(
269
+ Layout,
270
+ {
271
+ hideHeader: props.hideHeader === true,
272
+ keyboardVerticalOffset: props.keyboardVerticalOffset ?? 0,
273
+ keyboardBehavior: props.keyboardBehavior ?? (reactNative.Platform.OS === "ios" ? "padding" : "none"),
274
+ style: props.style,
275
+ onError: props.onWarning,
276
+ suggestion: props.suggestion ?? null,
277
+ suggestionTestID: props.suggestionTestID ?? "vinaverse-suggestion",
278
+ footer: props.footer
279
+ }
280
+ ) });
281
+ }
282
+ function Layout(props) {
283
+ const { colors } = chunk6QYDPGRS_cjs.useTheme();
284
+ const { direction } = react.useCopy();
285
+ const { onError } = props;
286
+ const reportError = react$1.useMemo(
287
+ () => onError ? (e) => onError(String(e), { code: "send_failed" }) : void 0,
288
+ [onError]
289
+ );
290
+ return /* @__PURE__ */ jsxRuntime.jsxs(
291
+ reactNative.KeyboardAvoidingView,
292
+ {
293
+ ...props.keyboardBehavior === "none" ? { enabled: false } : { behavior: props.keyboardBehavior },
294
+ keyboardVerticalOffset: props.keyboardVerticalOffset,
295
+ style: [
296
+ { flex: 1, backgroundColor: colors.background, direction },
297
+ props.style
298
+ ],
299
+ children: [
300
+ props.hideHeader ? null : /* @__PURE__ */ jsxRuntime.jsx(chunkXAG2P447_cjs.ChatHeader, {}),
301
+ /* @__PURE__ */ jsxRuntime.jsx(chunkXAG2P447_cjs.DisclosureBar, {}),
302
+ /* @__PURE__ */ jsxRuntime.jsx(StatusBanner, {}),
303
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flex: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(chunkXAG2P447_cjs.MessageList, {}) }),
304
+ props.suggestion ? /* @__PURE__ */ jsxRuntime.jsx(Suggestion, { chip: props.suggestion, testID: props.suggestionTestID }) : null,
305
+ /* @__PURE__ */ jsxRuntime.jsx(Composer, { ...reportError ? { onError: reportError } : {} }),
306
+ props.footer
307
+ ]
308
+ }
309
+ );
310
+ }
311
+ function Suggestion(props) {
312
+ const { store, handlers } = chunkXAG2P447_cjs.useChat();
313
+ const { space } = chunk6QYDPGRS_cjs.useTheme();
314
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { paddingHorizontal: space.lg, alignItems: "flex-start" }, children: /* @__PURE__ */ jsxRuntime.jsx(
315
+ chunkXAG2P447_cjs.Button,
316
+ {
317
+ label: props.chip.label,
318
+ testID: props.testID,
319
+ onPress: () => {
320
+ store.send(props.chip.message);
321
+ handlers.current?.onChip?.(props.chip);
322
+ }
323
+ }
324
+ ) });
325
+ }
326
+ function useStableSlots(slots) {
327
+ const held = react$1.useRef({});
328
+ const next = slots ?? {};
329
+ if (!sameSlots(held.current, next)) held.current = next;
330
+ return held.current;
331
+ }
332
+ function sameSlots(a, b) {
333
+ const keys = /* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)]);
334
+ for (const key of keys) {
335
+ if (key === "cards") {
336
+ const ca = a.cards ?? {};
337
+ const cb = b.cards ?? {};
338
+ const kinds = /* @__PURE__ */ new Set([...Object.keys(ca), ...Object.keys(cb)]);
339
+ for (const kind of kinds) if (ca[kind] !== cb[kind]) return false;
340
+ } else if (a[key] !== b[key]) return false;
341
+ }
342
+ return true;
343
+ }
344
+ function AgentChat(props) {
345
+ const {
346
+ agentKey,
347
+ place,
348
+ entryPoint,
349
+ askAbout,
350
+ onContact,
351
+ onOpenPrivacy,
352
+ components,
353
+ agentName,
354
+ opener,
355
+ openerTestID,
356
+ ...chat
357
+ } = props;
358
+ const runtime = agent.useAgentRuntime();
359
+ chunk6QYDPGRS_cjs.useAgentSweep(runtime);
360
+ const { conversation, state, startNew } = agent.useAgentConversation(agentKey, {
361
+ place: place ?? null,
362
+ entryPoint: entryPoint ?? null
363
+ });
364
+ const store = conversation.store;
365
+ const spoke = react.useConversationSelector(
366
+ store,
367
+ (v) => v.items.some((i) => i.type === "message" && i.role === "person")
368
+ );
369
+ const { Ended, Unreachable, UnavailableScreen, Footer, ...slots } = components ?? {};
370
+ const copy = react$1.useMemo(
371
+ () => agentName ? { ...props.copy, agentFallbackName: agentName } : props.copy,
372
+ [agentName, props.copy]
373
+ );
374
+ const events = {
375
+ onOpenTarget: chat.onOpenTarget ? (target, card) => {
376
+ runtime.emit({
377
+ type: "target_opened",
378
+ key: conversation.key,
379
+ cardId: card.id,
380
+ kind: target.type
381
+ });
382
+ chat.onOpenTarget?.(target, card);
383
+ } : void 0,
384
+ onOpenLink: chat.onOpenLink ? (link, card) => {
385
+ runtime.emit({
386
+ type: "link_opened",
387
+ key: conversation.key,
388
+ cardId: card.id,
389
+ kind: card.kind
390
+ });
391
+ chat.onOpenLink?.(link, card);
392
+ } : void 0,
393
+ onChip: (chip) => {
394
+ runtime.emit({ type: "chip_tapped", key: conversation.key });
395
+ chat.onChip?.(chip);
396
+ }
397
+ };
398
+ const shared = {
399
+ ...chat,
400
+ ...events.onOpenTarget ? { onOpenTarget: events.onOpenTarget } : {},
401
+ ...events.onOpenLink ? { onOpenLink: events.onOpenLink } : {},
402
+ onChip: events.onChip,
403
+ ...copy ? { copy } : {},
404
+ ...onContact && !chat.failureAction ? { failureAction: { onPress: () => onContact() } } : {},
405
+ conversation: store,
406
+ components: slots
407
+ };
408
+ if (state.failure === "ended") {
409
+ const own = {
410
+ onStartNew: startNew,
411
+ reason: state.reason,
412
+ code: state.code,
413
+ onContact
414
+ };
415
+ return /* @__PURE__ */ jsxRuntime.jsx(VinaverseChatProvider, { ...shared, children: /* @__PURE__ */ jsxRuntime.jsx(Centered, { children: Ended ? /* @__PURE__ */ jsxRuntime.jsx(Ended, { ...own, Default: DefaultEnded }) : /* @__PURE__ */ jsxRuntime.jsx(DefaultEnded, { ...own }) }) });
416
+ }
417
+ if (state.failure === "unreachable") {
418
+ const own = {
419
+ onRetry: conversation.retry,
420
+ reason: state.reason,
421
+ onContact
422
+ };
423
+ return /* @__PURE__ */ jsxRuntime.jsx(VinaverseChatProvider, { ...shared, children: /* @__PURE__ */ jsxRuntime.jsx(Centered, { children: Unreachable ? /* @__PURE__ */ jsxRuntime.jsx(Unreachable, { ...own, Default: DefaultUnreachable }) : /* @__PURE__ */ jsxRuntime.jsx(DefaultUnreachable, { ...own }) }) });
424
+ }
425
+ if (state.failure === "unavailable") {
426
+ const own = {
427
+ reason: state.reason,
428
+ code: state.code,
429
+ onContact,
430
+ onRetry: conversation.retry
431
+ };
432
+ return /* @__PURE__ */ jsxRuntime.jsx(VinaverseChatProvider, { ...shared, children: /* @__PURE__ */ jsxRuntime.jsx(Centered, { children: UnavailableScreen ? /* @__PURE__ */ jsxRuntime.jsx(UnavailableScreen, { ...own, Default: DefaultUnavailableScreen }) : /* @__PURE__ */ jsxRuntime.jsx(DefaultUnavailableScreen, { ...own }) }) });
433
+ }
434
+ const offered = opener && !spoke ? opener : null;
435
+ return /* @__PURE__ */ jsxRuntime.jsx(
436
+ VinaverseChat,
437
+ {
438
+ ...shared,
439
+ suggestion: offered ?? (state.moved && askAbout ? { label: askAbout, message: askAbout } : null),
440
+ ...offered ? { suggestionTestID: openerTestID ?? "vinaverse-opener" } : {},
441
+ footer: Footer === null ? null : /* @__PURE__ */ jsxRuntime.jsx(
442
+ FooterFor,
443
+ {
444
+ store,
445
+ state,
446
+ rate: conversation.rate,
447
+ canRate: conversation.canRate,
448
+ Footer,
449
+ onOpenPrivacy
450
+ }
451
+ )
452
+ }
453
+ );
454
+ }
455
+ function FooterFor(props) {
456
+ const newest = react.useConversationSelector(props.store, newestWholeReply);
457
+ const turnId = newest && props.canRate(newest) ? newest : null;
458
+ const own = {
459
+ turnId,
460
+ rating: turnId ? props.state.ratings.get(turnId) : void 0,
461
+ onRate: (rating) => {
462
+ if (turnId) props.rate(turnId, rating);
463
+ },
464
+ onOpenPrivacy: props.onOpenPrivacy
465
+ };
466
+ const { Footer } = props;
467
+ return Footer ? /* @__PURE__ */ jsxRuntime.jsx(Footer, { ...own, Default: AgentFooter }) : /* @__PURE__ */ jsxRuntime.jsx(AgentFooter, { ...own });
468
+ }
469
+ function newestWholeReply(view) {
470
+ for (let i = view.items.length - 1; i >= 0; i--) {
471
+ const item = view.items[i];
472
+ if (item?.type !== "message" || item.role !== "agent") continue;
473
+ const whole = item.state === "sent" && !item.partial && !item.refusal && item.key.startsWith("a:");
474
+ return whole ? item.key.slice(2) : null;
475
+ }
476
+ return null;
477
+ }
478
+ function Centered(props) {
479
+ const { colors, space } = chunk6QYDPGRS_cjs.useTheme();
480
+ return /* @__PURE__ */ jsxRuntime.jsx(
481
+ reactNative.View,
482
+ {
483
+ style: {
484
+ flex: 1,
485
+ alignItems: "center",
486
+ justifyContent: "center",
487
+ padding: space.xl,
488
+ backgroundColor: colors.background
489
+ },
490
+ children: props.children
491
+ }
492
+ );
493
+ }
494
+ function Notice(props) {
495
+ const { colors, space, font } = chunk6QYDPGRS_cjs.useTheme();
496
+ return /* @__PURE__ */ jsxRuntime.jsxs(
497
+ reactNative.View,
498
+ {
499
+ accessibilityRole: "alert",
500
+ style: { alignItems: "center", gap: space.md },
501
+ children: [
502
+ /* @__PURE__ */ jsxRuntime.jsx(
503
+ reactNative.Text,
504
+ {
505
+ style: {
506
+ color: colors.text,
507
+ fontSize: font.size.lg,
508
+ fontWeight: "600",
509
+ textAlign: "center"
510
+ },
511
+ children: props.title
512
+ }
513
+ ),
514
+ /* @__PURE__ */ jsxRuntime.jsx(
515
+ reactNative.Text,
516
+ {
517
+ style: {
518
+ color: colors.textMuted,
519
+ fontSize: font.size.md,
520
+ textAlign: "center"
521
+ },
522
+ children: props.body
523
+ }
524
+ ),
525
+ props.action && props.onPress ? /* @__PURE__ */ jsxRuntime.jsx(
526
+ chunkXAG2P447_cjs.Button,
527
+ {
528
+ label: props.action,
529
+ variant: "primary",
530
+ onPress: props.onPress
531
+ }
532
+ ) : null
533
+ ]
534
+ }
535
+ );
536
+ }
537
+ function DefaultEnded(props) {
538
+ const { t } = react.useCopy();
539
+ return /* @__PURE__ */ jsxRuntime.jsx(
540
+ Notice,
541
+ {
542
+ title: t("agentEnded"),
543
+ body: t("agentEndedBody"),
544
+ action: t("agentStartOver"),
545
+ onPress: props.onStartNew
546
+ }
547
+ );
548
+ }
549
+ function DefaultUnavailableScreen(props) {
550
+ const { t } = react.useCopy();
551
+ const name = agent.useAgentName(t("agentFallbackName"));
552
+ const title = t("agentOff", { agent: name });
553
+ return /* @__PURE__ */ jsxRuntime.jsx(
554
+ Notice,
555
+ {
556
+ title: title.charAt(0).toUpperCase() + title.slice(1),
557
+ body: t("agentOffBody"),
558
+ ...props.onContact ? { action: t("talkToPerson"), onPress: props.onContact } : {}
559
+ }
560
+ );
561
+ }
562
+ function DefaultUnreachable(props) {
563
+ const { t } = react.useCopy();
564
+ const name = agent.useAgentName(t("agentFallbackName"));
565
+ return /* @__PURE__ */ jsxRuntime.jsx(
566
+ Notice,
567
+ {
568
+ title: t("agentUnreachable", { agent: name }),
569
+ body: t("agentUnreachableBody"),
570
+ action: t("tryAgain"),
571
+ onPress: props.onRetry
572
+ }
573
+ );
574
+ }
575
+ function AgentFooter(props) {
576
+ const { t } = react.useCopy();
577
+ const { colors, space, font } = chunk6QYDPGRS_cjs.useTheme();
578
+ const muted = { color: colors.textMuted, fontSize: font.size.sm };
579
+ return /* @__PURE__ */ jsxRuntime.jsxs(
580
+ reactNative.View,
581
+ {
582
+ style: {
583
+ flexDirection: "row",
584
+ flexWrap: "wrap",
585
+ alignItems: "center",
586
+ gap: space.xs,
587
+ paddingHorizontal: space.lg
588
+ },
589
+ children: [
590
+ props.turnId === null ? null : props.rating ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: muted, children: t("helpfulThanks") }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
591
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: muted, children: t("helpful") }),
592
+ /* @__PURE__ */ jsxRuntime.jsx(
593
+ chunkXAG2P447_cjs.Button,
594
+ {
595
+ label: t("helpfulYes"),
596
+ variant: "text",
597
+ onPress: () => props.onRate("up")
598
+ }
599
+ ),
600
+ /* @__PURE__ */ jsxRuntime.jsx(
601
+ chunkXAG2P447_cjs.Button,
602
+ {
603
+ label: t("helpfulNo"),
604
+ variant: "text",
605
+ onPress: () => props.onRate("down")
606
+ }
607
+ )
608
+ ] }),
609
+ props.onOpenPrivacy ? /* @__PURE__ */ jsxRuntime.jsx(
610
+ chunkXAG2P447_cjs.Button,
611
+ {
612
+ label: t("privacy"),
613
+ variant: "text",
614
+ role: "link",
615
+ onPress: props.onOpenPrivacy
616
+ }
617
+ ) : null
618
+ ]
619
+ }
620
+ );
621
+ }
622
+
623
+ Object.defineProperty(exports, "AgentRuntimeProvider", {
624
+ enumerable: true,
625
+ get: function () { return agent.AgentRuntimeProvider; }
626
+ });
627
+ Object.defineProperty(exports, "forgetGreeting", {
628
+ enumerable: true,
629
+ get: function () { return agent.forgetGreeting; }
630
+ });
631
+ Object.defineProperty(exports, "greetedKey", {
632
+ enumerable: true,
633
+ get: function () { return agent.greetedKey; }
634
+ });
635
+ Object.defineProperty(exports, "useAgentConversation", {
636
+ enumerable: true,
637
+ get: function () { return agent.useAgentConversation; }
638
+ });
639
+ Object.defineProperty(exports, "useAgentFeatures", {
640
+ enumerable: true,
641
+ get: function () { return agent.useAgentFeatures; }
642
+ });
643
+ Object.defineProperty(exports, "useAgentLauncher", {
644
+ enumerable: true,
645
+ get: function () { return agent.useAgentLauncher; }
646
+ });
647
+ Object.defineProperty(exports, "useAgentName", {
648
+ enumerable: true,
649
+ get: function () { return agent.useAgentName; }
650
+ });
651
+ Object.defineProperty(exports, "useAgentProfile", {
652
+ enumerable: true,
653
+ get: function () { return agent.useAgentProfile; }
654
+ });
655
+ Object.defineProperty(exports, "useAgentRuntime", {
656
+ enumerable: true,
657
+ get: function () { return agent.useAgentRuntime; }
658
+ });
659
+ Object.defineProperty(exports, "useAgentStatus", {
660
+ enumerable: true,
661
+ get: function () { return agent.useAgentStatus; }
662
+ });
663
+ Object.defineProperty(exports, "useAgentStatusState", {
664
+ enumerable: true,
665
+ get: function () { return agent.useAgentStatusState; }
666
+ });
667
+ exports.AgentChat = AgentChat;
668
+ exports.AgentFooter = AgentFooter;
669
+ exports.Composer = Composer;
670
+ exports.DefaultComposer = DefaultComposer;
671
+ exports.DefaultEnded = DefaultEnded;
672
+ exports.DefaultUnavailable = DefaultUnavailable;
673
+ exports.DefaultUnavailableScreen = DefaultUnavailableScreen;
674
+ exports.DefaultUnreachable = DefaultUnreachable;
675
+ exports.StatusBanner = StatusBanner;
676
+ exports.VinaverseChat = VinaverseChat;
677
+ exports.VinaverseChatProvider = VinaverseChatProvider;
678
+ exports.newestWholeReply = newestWholeReply;
679
+ //# sourceMappingURL=chunk-4PXQ7DEY.cjs.map
680
+ //# sourceMappingURL=chunk-4PXQ7DEY.cjs.map