@vinaverse/react-native 0.1.0-alpha.10 → 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.
@@ -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