@adminide-stack/yantra-mobile 12.0.28-alpha.67 → 12.0.28-alpha.68

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 (35) hide show
  1. package/lib/api/stt.js +54 -0
  2. package/lib/api/stt.js.map +1 -0
  3. package/lib/components/GatewayConnector/GatewayConnector.js +18 -0
  4. package/lib/components/GatewayConnector/GatewayConnector.js.map +1 -0
  5. package/lib/components/NavigationHeader/NavigationHeader.js +214 -0
  6. package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -0
  7. package/lib/components/ThinkingIndicator.js +55 -0
  8. package/lib/components/ThinkingIndicator.js.map +1 -0
  9. package/lib/compute.js +108 -31
  10. package/lib/compute.js.map +1 -1
  11. package/lib/contexts/CdecliConnectionContext.js +47 -0
  12. package/lib/contexts/CdecliConnectionContext.js.map +1 -0
  13. package/lib/contexts/GatewayContext.js +1 -1
  14. package/lib/features/audio-input/AudioRecorderPanel.js +228 -0
  15. package/lib/features/audio-input/AudioRecorderPanel.js.map +1 -0
  16. package/lib/hooks/useCdecliAutoConnect.js +41 -18
  17. package/lib/hooks/useCdecliAutoConnect.js.map +1 -1
  18. package/lib/hooks/useChatApi.js +158 -41
  19. package/lib/hooks/useChatApi.js.map +1 -1
  20. package/lib/hooks/useChatStream.js +59 -16
  21. package/lib/hooks/useChatStream.js.map +1 -1
  22. package/lib/hooks/usePrerequisiteIds.js +8 -12
  23. package/lib/hooks/usePrerequisiteIds.js.map +1 -1
  24. package/lib/index.js +1 -1
  25. package/lib/index.js.map +1 -1
  26. package/lib/routes.json +112 -0
  27. package/lib/screens/Chat/index.js +392 -0
  28. package/lib/screens/Chat/index.js.map +1 -0
  29. package/lib/screens/ChatHistory/index.js +56 -0
  30. package/lib/screens/ChatHistory/index.js.map +1 -0
  31. package/lib/screens/Home/HomeScreen.js +105 -427
  32. package/lib/screens/Home/HomeScreen.js.map +1 -1
  33. package/lib/screens/Home/components/ChatHistoryLanding.js +436 -214
  34. package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
  35. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import {jsx,jsxs}from'react/jsx-runtime';import React,{useState,useMemo,useEffect,useCallback}from'react';import {useWindowDimensions,useColorScheme,Platform,Keyboard,TouchableWithoutFeedback,View,StyleSheet,Pressable}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {getDefaultLeftItems,getDefaultRightItems,Box,Text,InputToolBar}from'@admin-layout/gluestack-ui-mobile';import {useSafeAreaInsets,SafeAreaView}from'react-native-safe-area-context';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {MessagesContainerUI}from'@messenger-box/platform-mobile';import {v4}from'uuid';import {ContributionSchemaId}from'common';import {useGetContextDataQuery,useGetPageSettingsQuery}from'common/graphql';import {useGatewayContext}from'../../contexts/GatewayContext.js';import {GatewayToolbarButtonMobile}from'../../components/GatewayToolbarButtonMobile.js';import {useCdecliAutoConnect}from'../../hooks/useCdecliAutoConnect.js';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {useChatMutations,useChatSessions}from'../../hooks/useChatApi.js';import {useChatStream}from'../../hooks/useChatStream.js';import DeepSearchModal from'./components/DeepSearchModal.js';import ChatHistoryLanding from'./components/ChatHistoryLanding.js';import {normalizeSummaryText,extractDeepSearchSources}from'./deepSearchUtils.js';import {YantraBrandLoader,YANTRA_LOADER_SIZE_COMPACT}from'../../components/YantraBrandLoader.js';import {mobileTokens}from'../../theme/mobileTokens.js';var __defProp = Object.defineProperty;
1
+ import {jsx,jsxs}from'react/jsx-runtime';import React,{useRef,useState,useMemo,useEffect,useCallback}from'react';import {useWindowDimensions,useColorScheme,Platform,Keyboard,TouchableWithoutFeedback,View,StyleSheet,Pressable}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {getDefaultLeftItems,getDefaultRightItems,Box,Text,InputToolBar}from'@admin-layout/gluestack-ui-mobile';import {useSafeAreaInsets,SafeAreaView}from'react-native-safe-area-context';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {v4}from'uuid';import {ContributionSchemaId}from'common';import {useGetContextDataQuery,useGetPageSettingsQuery}from'common/graphql';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {useChatMutations}from'../../hooks/useChatApi.js';import {AudioRecorderPanel}from'../../features/audio-input/AudioRecorderPanel.js';import {mobileTokens}from'../../theme/mobileTokens.js';var __defProp = Object.defineProperty;
2
2
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
3
  var __hasOwnProp = Object.prototype.hasOwnProperty;
4
4
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
@@ -14,8 +14,9 @@ var __spreadValues = (a, b) => {
14
14
  }
15
15
  return a;
16
16
  };
17
- const SENDING_LOADER_COMPOSER_RESERVE_PX = 156;
18
- const COMPOSER_SCROLL_RESERVE_PX = 164;
17
+ function buildChannelTitle(mode, channelId) {
18
+ return mode === "deep-search" ? `deep-search-${channelId}` : `chat-channel-${channelId}`;
19
+ }
19
20
  function organizationFromSettingsValue(settings) {
20
21
  if (settings == null) return null;
21
22
  if (typeof settings === "string") {
@@ -50,44 +51,6 @@ function projectFromSettingsValue(settings) {
50
51
  }
51
52
  return null;
52
53
  }
53
- const ChatContentSection = React.memo(function ChatContentSection2({
54
- contentMaxWidth,
55
- composerScrollBottomPadding,
56
- messages,
57
- response,
58
- isLoading,
59
- disabled,
60
- isStreaming,
61
- onStop,
62
- cancel,
63
- onSend,
64
- onBackPress
65
- }) {
66
- return /* @__PURE__ */ jsx(Box, { flex: 1, width: "100%", alignSelf: "stretch", children: /* @__PURE__ */ jsx(MessagesContainerUI, { mode: "chat", showBackButton: false, onBackPress, compactTop: true, messagesContainerStyle: {
67
- paddingHorizontal: 0,
68
- paddingTop: 0,
69
- paddingBottom: composerScrollBottomPadding,
70
- margin: 0,
71
- marginTop: 0,
72
- alignSelf: "center",
73
- width: contentMaxWidth
74
- }, listContentStyle: {
75
- paddingTop: 0,
76
- paddingBottom: composerScrollBottomPadding,
77
- margin: 0,
78
- marginTop: 0,
79
- width: contentMaxWidth,
80
- alignSelf: "center",
81
- justifyContent: "flex-end"
82
- }, messages: messages.map((msg, index) => ({
83
- id: `msg-${index}-${msg.role}`,
84
- role: msg.role,
85
- content: msg.content,
86
- metadata: msg.metadata
87
- })), streamingContent: response, currentUser: {
88
- id: "user"
89
- }, onSend, disabled: isLoading || disabled, isLoading, onStop: isStreaming ? cancel : onStop, renderPlanInputToolbar: () => null, renderBuildInputToolbar: () => null }) });
90
- });
91
54
  const EmptyStateSection = React.memo(function EmptyStateSection2({
92
55
  isDark,
93
56
  secondaryTextColor,
@@ -118,6 +81,14 @@ const EmptyStateSection = React.memo(function EmptyStateSection2({
118
81
  /* @__PURE__ */ jsx(Text, { style: [styles.emptyModePillLabel, {
119
82
  color: activeMode === "deep-search" ? "#ffffff" : secondaryTextColor
120
83
  }], children: "Deep Search" })
84
+ ] }),
85
+ /* @__PURE__ */ jsxs(Pressable, { onPress: () => {
86
+ console.log("build mode");
87
+ }, style: styles.emptyModePill, accessibilityRole: "button", accessibilityLabel: "Build mode (preview)", children: [
88
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "lightbulb-outline", size: 14, color: secondaryTextColor }),
89
+ /* @__PURE__ */ jsx(Text, { style: [styles.emptyModePillLabel, {
90
+ color: secondaryTextColor
91
+ }], children: "Build" })
121
92
  ] })
122
93
  ] }),
123
94
  /* @__PURE__ */ jsx(Text, { style: [styles.emptyCenterTitle, {
@@ -125,48 +96,16 @@ const EmptyStateSection = React.memo(function EmptyStateSection2({
125
96
  }], children: "How do you want to start?" }),
126
97
  /* @__PURE__ */ jsx(Text, { style: [styles.emptySubtitle, {
127
98
  color: secondaryTextColor
128
- }], children: "Use Chat for quick help, or Deep Search for researched, source-backed answers." })
99
+ }], children: "Use Chat for quick help, Deep Search for source-backed answers, or Build to assemble workflows." })
129
100
  ] }) });
130
101
  });
131
- const HeaderBackButton = React.memo(function HeaderBackButton2({
132
- color,
133
- onPress
134
- }) {
135
- return /* @__PURE__ */ jsx(Pressable, { onPress, style: ({
136
- pressed
137
- }) => [styles.backButton, pressed && styles.newChatButtonPressed], accessibilityLabel: "Back to chat", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chevron-left", size: 24, color }) });
138
- });
139
- const HeaderRightActions = React.memo(function HeaderRightActions2({
140
- gatewayToolbarStatus,
141
- gatewayToolbarError,
142
- onToggleGateway,
143
- gatewayToolbarLabel,
144
- gatewayToolbarTone,
145
- showChatHistory,
146
- onOpenChatHistory,
147
- onNewChat,
148
- isDark,
149
- accentColor,
150
- newChatIconColor
151
- }) {
152
- return /* @__PURE__ */ jsxs(View, { style: styles.headerRight, children: [
153
- /* @__PURE__ */ jsx(GatewayToolbarButtonMobile, { gatewayStatus: gatewayToolbarStatus, gatewayError: gatewayToolbarError, onToggleGateway, disabled: false, statusLabel: gatewayToolbarLabel, tone: gatewayToolbarTone }),
154
- !showChatHistory ? /* @__PURE__ */ jsx(Pressable, { onPress: onOpenChatHistory, style: ({
155
- pressed
156
- }) => [styles.historyHeaderButton, pressed && styles.historyHeaderButtonPressed], accessibilityLabel: "Chat history", accessibilityRole: "button", children: /* @__PURE__ */ jsx(View, { style: [styles.historyHeaderButtonInner, isDark ? styles.historyHeaderButtonInnerDark : null], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "history", size: 19, color: accentColor }) }) }) : null,
157
- /* @__PURE__ */ jsx(Pressable, { onPress: onNewChat, style: ({
158
- pressed
159
- }) => [styles.newChatButton, pressed && styles.newChatButtonPressed], accessibilityLabel: "New chat", children: /* @__PURE__ */ jsx(View, { style: [styles.newChatButtonInner, isDark ? styles.newChatButtonInnerDark : null], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chat-plus-outline", size: 20, color: newChatIconColor }) }) })
160
- ] });
161
- });
162
102
  function HomeScreenContent({
163
103
  initialMode = "chat",
164
104
  onSubmit: onSubmitProp,
165
- onStop,
166
105
  isLoading: isLoadingProp = false,
167
106
  disabled = false
168
107
  }) {
169
- var _a, _b, _c, _d, _e, _f, _g;
108
+ var _a, _b, _c, _d, _e;
170
109
  const {
171
110
  width: screenWidth
172
111
  } = useWindowDimensions();
@@ -174,22 +113,14 @@ function HomeScreenContent({
174
113
  const isDark = colorScheme === "dark";
175
114
  const navigation = useNavigation();
176
115
  const route = useRoute();
177
- const hasRehydratedOrgRef = React.useRef(false);
116
+ const hasRehydratedOrgRef = useRef(false);
178
117
  const [value, setValue] = useState("");
179
118
  const [activeMode, setActiveMode] = useState(initialMode);
180
- const [activeSessionId, setActiveSessionId] = useState(null);
181
- const [isDeepSearchModalOpen, setIsDeepSearchModalOpen] = useState(false);
182
- const [deepSearchQuery, setDeepSearchQuery] = useState(null);
183
- const [deepSearchSummary, setDeepSearchSummary] = useState("");
184
- const [deepSearchSources, setDeepSearchSources] = useState([]);
185
- const [researchProcessOpen, setResearchProcessOpen] = useState(true);
186
- const [sourcesAccordionOpen, setSourcesAccordionOpen] = useState(true);
187
- const [showChatHistory, setShowChatHistory] = useState(false);
188
- const [channelBootstrap, setChannelBootstrap] = useState(false);
119
+ const [showAudioRecorder, setShowAudioRecorder] = useState(false);
120
+ const [voiceError, setVoiceError] = useState(null);
189
121
  const {
190
122
  createChannel
191
123
  } = useChatMutations();
192
- useChatSessions();
193
124
  const {
194
125
  orgName: resolvedOrgName,
195
126
  projectId
@@ -223,46 +154,12 @@ function HomeScreenContent({
223
154
  const routeOrgName = ((_c = (_b = route == null ? void 0 : route.params) == null ? void 0 : _b.orgName) != null ? _c : "").trim() || null;
224
155
  const effectiveOrgName = resolvedOrgName || fallbackOrgNameFromSettings || routeOrgName || null;
225
156
  const effectiveProjectId = projectId || fallbackProjectIdFromSettings || null;
226
- const {
227
- selectedGateway
228
- } = useGatewayContext();
229
- const cdecliSelected = (selectedGateway == null ? void 0 : selectedGateway.channelType) === "cdecli-serve";
230
- const cdecli = useCdecliAutoConnect(cdecliSelected, activeSessionId != null ? activeSessionId : void 0);
231
- const cdecliConnected = cdecliSelected && cdecli.channelConnected;
232
- const effectivePersistenceMode = (_e = (_d = cdecli.persistenceMode) != null ? _d : selectedGateway == null ? void 0 : selectedGateway.persistenceMode) != null ? _e : "frontend";
233
- const chatRouting = useMemo(() => cdecliConnected ? {
234
- kind: "cdecli",
235
- channelConnected: cdecli.channelConnected,
236
- accountId: cdecli.accountId,
237
- persistenceMode: effectivePersistenceMode
238
- } : {
239
- kind: "groq"
240
- }, [cdecliConnected, cdecli.channelConnected, cdecli.accountId, effectivePersistenceMode]);
241
- const chat = useChatStream(activeSessionId, chatRouting);
242
- const {
243
- messages,
244
- response,
245
- error: chatError,
246
- isLoading: chatLoading,
247
- isStreaming,
248
- sendMessage,
249
- cancel,
250
- clearMessages
251
- } = chat;
252
157
  const trimmedQuery = value.trim();
253
158
  const hasQuery = trimmedQuery.length > 0;
254
159
  const canSubmit = hasQuery && Boolean(routeOrgName || effectiveOrgName);
255
- const isLoading = isLoadingProp || chatLoading;
160
+ const isLoading = isLoadingProp;
256
161
  const isResearchMode = activeMode === "deep-search";
257
162
  const inputPlaceholder = !effectiveOrgName ? "Initializing workspace..." : isResearchMode ? "Research anything..." : "Ask anything...";
258
- const waitingForAssistant = useMemo(() => {
259
- var _a2;
260
- if (!chatLoading && !isStreaming || messages.length === 0) return false;
261
- return ((_a2 = messages[messages.length - 1]) == null ? void 0 : _a2.role) === "user";
262
- }, [chatLoading, isStreaming, messages]);
263
- const pinSendingLoaderNearComposer = useMemo(() => messages.length > 0 || Boolean((response != null ? response : "").trim()), [messages.length, response]);
264
- const showSendingLoader = !showChatHistory && (channelBootstrap || waitingForAssistant);
265
- const hasRenderableConversation = messages.length > 0 || isStreaming;
266
163
  const insets = useSafeAreaInsets();
267
164
  const [keyboardHeight, setKeyboardHeight] = useState(0);
268
165
  useEffect(() => {
@@ -295,14 +192,42 @@ function HomeScreenContent({
295
192
  const handleModeSwitch = useCallback((mode) => {
296
193
  setActiveMode(mode);
297
194
  }, []);
298
- const ensureSessionId = useCallback(async (mode) => {
299
- if (activeSessionId) return activeSessionId;
195
+ const navigateToChat = useCallback((channelId, query, mode, attachments) => {
196
+ var _a2;
197
+ const params = {
198
+ channelId,
199
+ orgName: (_a2 = effectiveOrgName != null ? effectiveOrgName : routeOrgName) != null ? _a2 : void 0,
200
+ initialQuery: query,
201
+ initialMode: mode
202
+ };
203
+ if (attachments && attachments.length > 0) {
204
+ params.initialAttachments = attachments;
205
+ }
206
+ navigation.dispatch(CommonActions.navigate({
207
+ name: "MainStack.Chat",
208
+ params
209
+ }));
210
+ }, [navigation, effectiveOrgName, routeOrgName]);
211
+ const handleSubmit = useCallback(async (attachments) => {
212
+ if (!canSubmit || isLoading || disabled) return;
213
+ const submission = {
214
+ mode: activeMode,
215
+ query: trimmedQuery,
216
+ attachments
217
+ };
218
+ if (onSubmitProp) {
219
+ onSubmitProp(submission);
220
+ }
300
221
  if (!effectiveOrgName || !effectiveProjectId) {
301
- throw new Error("Workspace is still initializing. Please retry in a moment.");
222
+ console.warn("[HomeScreen] orgName/projectId not ready \u2014 skipping submit.");
223
+ return;
302
224
  }
303
225
  const requestedChannelId = v4();
304
- const title = mode === "deep-search" ? `deep-search-${requestedChannelId}` : `chat-channel-${requestedChannelId}`;
305
- const session = await createChannel({
226
+ const title = buildChannelTitle(activeMode, requestedChannelId);
227
+ const queryToForward = trimmedQuery;
228
+ const attachmentsToForward = attachments;
229
+ setValue("");
230
+ void createChannel({
306
231
  id: requestedChannelId,
307
232
  title,
308
233
  isShared: false,
@@ -313,76 +238,14 @@ function HomeScreenContent({
313
238
  systemPrompt: null,
314
239
  orgName: effectiveOrgName,
315
240
  projectId: effectiveProjectId
241
+ }).catch((err) => {
242
+ console.error("[HomeScreen] createChannel failed:", err);
316
243
  });
317
- setActiveSessionId(session.id);
318
- return session.id;
319
- }, [activeSessionId, createChannel, effectiveOrgName, effectiveProjectId]);
320
- const handleSubmit = useCallback(async (attachments) => {
321
- if (!canSubmit || isLoading || disabled) return;
322
- const submission = {
323
- mode: activeMode,
324
- query: trimmedQuery,
325
- attachments
326
- };
327
- if (activeMode === "deep-search") {
328
- if (onSubmitProp) {
329
- onSubmitProp(submission);
330
- }
331
- setValue("");
332
- setDeepSearchQuery(trimmedQuery);
333
- setDeepSearchSummary("");
334
- setDeepSearchSources([]);
335
- setIsDeepSearchModalOpen(true);
336
- try {
337
- setChannelBootstrap(true);
338
- const sessionId = await ensureSessionId("deep-search");
339
- await sendMessage(trimmedQuery, void 0, sessionId);
340
- } catch (err) {
341
- console.error("[HomeScreen] Failed to create deep-search session:", err);
342
- } finally {
343
- setChannelBootstrap(false);
344
- }
345
- return;
346
- }
347
- if (onSubmitProp && activeMode === "chat") {
348
- onSubmitProp(submission);
349
- setValue("");
350
- return;
351
- }
352
- try {
353
- setChannelBootstrap(true);
354
- const sessionId = await ensureSessionId("chat");
355
- setValue("");
356
- await sendMessage(trimmedQuery, void 0, sessionId);
357
- } catch (err) {
358
- console.error("[HomeScreen] Failed to create session:", err);
359
- } finally {
360
- setChannelBootstrap(false);
361
- }
362
- }, [canSubmit, isLoading, disabled, activeMode, trimmedQuery, activeSessionId, onSubmitProp, ensureSessionId, sendMessage]);
363
- const handleNewChat = useCallback(() => {
364
- setShowChatHistory(false);
365
- setActiveSessionId(null);
366
- setValue("");
367
- clearMessages();
368
- }, [clearMessages]);
369
- const handleOpenChatHistory = useCallback(() => {
370
- setShowChatHistory(true);
371
- }, []);
372
- const handleCloseChatHistory = useCallback(() => {
373
- setShowChatHistory(false);
374
- }, []);
375
- const handleToggleGateway = useCallback(() => {
376
- }, []);
377
- const gatewayToolbarStatus = cdecli.status === "connecting" ? "connecting" : cdecli.status === "connected" ? "connected" : cdecli.status === "error" ? "error" : "disconnected";
378
- const gatewayToolbarTone = "default";
379
- const gatewayToolbarLabel = cdecli.status === "connecting" ? "Checking..." : void 0;
380
- const gatewayToolbarError = cdecli.error;
244
+ navigateToChat(requestedChannelId, queryToForward, activeMode, attachmentsToForward);
245
+ }, [canSubmit, isLoading, disabled, activeMode, trimmedQuery, onSubmitProp, effectiveOrgName, effectiveProjectId, createChannel, navigateToChat]);
381
246
  const surfaceColor = isDark ? "#0f172a" : mobileTokens.color.surface;
382
247
  const primaryTextColor = isDark ? "#e5e7eb" : mobileTokens.color.text;
383
248
  const secondaryTextColor = isDark ? "#94a3b8" : mobileTokens.color.textMuted;
384
- const accentColor = isDark ? "#a5b4fc" : "#4338ca";
385
- const newChatIconColor = isDark ? "#e5e7eb" : "#000000";
386
249
  const contentMaxWidth = Math.min(720, Math.max(360, screenWidth - 24));
387
250
  useEffect(() => {
388
251
  var _a2, _b2, _c2;
@@ -391,7 +254,7 @@ function HomeScreenContent({
391
254
  (_c2 = navigation.setParams) == null ? void 0 : _c2.call(navigation, {
392
255
  orgName: effectiveOrgName
393
256
  });
394
- }, [navigation, (_f = route == null ? void 0 : route.params) == null ? void 0 : _f.orgName, effectiveOrgName]);
257
+ }, [navigation, (_d = route == null ? void 0 : route.params) == null ? void 0 : _d.orgName, effectiveOrgName]);
395
258
  useEffect(() => {
396
259
  var _a2, _b2, _c2;
397
260
  const currentOrgName = ((_b2 = (_a2 = route == null ? void 0 : route.params) == null ? void 0 : _a2.orgName) == null ? void 0 : _b2.trim()) || "";
@@ -405,116 +268,28 @@ function HomeScreenContent({
405
268
  merge: true,
406
269
  key: Date.now().toString()
407
270
  }));
408
- }, [navigation, (_g = route == null ? void 0 : route.params) == null ? void 0 : _g.orgName, effectiveOrgName]);
409
- useEffect(() => {
410
- const headerLeft = showChatHistory ? () => /* @__PURE__ */ jsx(HeaderBackButton, { color: primaryTextColor, onPress: handleCloseChatHistory }) : void 0;
411
- const headerRight = () => /* @__PURE__ */ jsx(HeaderRightActions, { gatewayToolbarStatus, gatewayToolbarError, onToggleGateway: handleToggleGateway, gatewayToolbarLabel, gatewayToolbarTone, showChatHistory, onOpenChatHistory: handleOpenChatHistory, onNewChat: handleNewChat, isDark, accentColor, newChatIconColor });
412
- navigation.setOptions({
413
- drawerLabel: "Chat",
414
- headerTitle: showChatHistory ? "Chats" : "Yantra",
415
- headerLeft,
416
- headerRight
417
- });
418
- }, [navigation, showChatHistory, handleCloseChatHistory, handleOpenChatHistory, handleNewChat, handleToggleGateway, gatewayToolbarStatus, gatewayToolbarError, gatewayToolbarLabel, gatewayToolbarTone, primaryTextColor, accentColor, newChatIconColor, isDark]);
419
- const handleSendMessage = useCallback(async (text) => {
420
- if (!text.trim() || isLoading || disabled) return;
421
- const submission = {
422
- mode: activeMode,
423
- query: text.trim()
424
- };
425
- if (activeMode === "deep-search") {
426
- if (onSubmitProp) {
427
- onSubmitProp(submission);
428
- }
429
- setDeepSearchQuery(text.trim());
430
- setDeepSearchSummary("");
431
- setDeepSearchSources([]);
432
- setIsDeepSearchModalOpen(true);
433
- try {
434
- setChannelBootstrap(true);
435
- const sessionId = await ensureSessionId("deep-search");
436
- await sendMessage(text.trim(), void 0, sessionId);
437
- } catch (err) {
438
- console.error("[HomeScreen] Failed to create deep-search session:", err);
439
- } finally {
440
- setChannelBootstrap(false);
441
- }
442
- return;
443
- }
444
- try {
445
- setChannelBootstrap(true);
446
- const sessionId = await ensureSessionId("chat");
447
- await sendMessage(text.trim(), void 0, sessionId);
448
- } catch (err) {
449
- console.error("[HomeScreen] Failed to create session:", err);
450
- } finally {
451
- setChannelBootstrap(false);
452
- }
453
- }, [isLoading, disabled, activeMode, onSubmitProp, ensureSessionId, sendMessage]);
454
- const latestAssistantMessage = useMemo(() => {
455
- var _a2, _b2, _c2;
456
- for (let i = messages.length - 1; i >= 0; i -= 1) {
457
- if (((_a2 = messages[i]) == null ? void 0 : _a2.role) === "assistant") return (_c2 = (_b2 = messages[i]) == null ? void 0 : _b2.content) != null ? _c2 : "";
458
- }
459
- return "";
460
- }, [messages]);
461
- const deepSearchPreviewContent = response || deepSearchSummary;
462
- const deepSearchPreviewNormalized = useMemo(() => normalizeSummaryText(deepSearchPreviewContent || deepSearchSummary || ""), [deepSearchPreviewContent, deepSearchSummary]);
463
- const handleDeepSearchClose = useCallback(() => {
464
- if (isStreaming) {
465
- cancel();
466
- }
467
- setIsDeepSearchModalOpen(false);
468
- setDeepSearchQuery(null);
469
- setDeepSearchSummary("");
470
- setDeepSearchSources([]);
471
- setResearchProcessOpen(true);
472
- setSourcesAccordionOpen(true);
473
- }, [isStreaming, cancel]);
474
- const handleRetryDeepSearch = useCallback(async () => {
475
- if (!deepSearchQuery || isStreaming) return;
476
- try {
477
- setChannelBootstrap(true);
478
- const sessionId = await ensureSessionId("deep-search");
479
- await sendMessage(deepSearchQuery, void 0, sessionId);
480
- } catch (error) {
481
- console.error("[HomeScreen] Failed to retry deep-search:", error);
482
- } finally {
483
- setChannelBootstrap(false);
484
- }
485
- }, [deepSearchQuery, isStreaming, ensureSessionId, sendMessage]);
271
+ }, [navigation, (_e = route == null ? void 0 : route.params) == null ? void 0 : _e.orgName, effectiveOrgName]);
486
272
  const handleValueChange = useCallback((e) => {
487
273
  setValue(e.nativeEvent.text);
488
274
  }, []);
489
275
  const handleMicPress = useCallback(() => {
490
- console.log("mic");
491
- }, []);
492
- const handleSelectHistorySession = useCallback((channelId) => {
493
- setShowChatHistory(false);
494
- setActiveSessionId(channelId);
495
- setActiveMode("chat");
276
+ if (hasQuery) return;
277
+ setVoiceError(null);
278
+ Keyboard.dismiss();
279
+ setShowAudioRecorder(true);
280
+ }, [hasQuery]);
281
+ const handleTranscriptionComplete = useCallback((text) => {
282
+ const cleaned = (text != null ? text : "").trim();
283
+ setShowAudioRecorder(false);
284
+ if (!cleaned) return;
285
+ setValue((prev) => prev.trim().length > 0 ? `${prev.trim()} ${cleaned}` : cleaned);
496
286
  }, []);
497
- const handleComposeFromHistory = useCallback(() => {
498
- setShowChatHistory(false);
499
- setActiveSessionId(null);
500
- setValue("");
501
- clearMessages();
502
- }, [clearMessages]);
503
- const handleToggleResearchProcess = useCallback(() => {
504
- setResearchProcessOpen((prev) => !prev);
287
+ const handleRecorderCancel = useCallback(() => {
288
+ setShowAudioRecorder(false);
505
289
  }, []);
506
- const handleToggleSourcesAccordion = useCallback(() => {
507
- setSourcesAccordionOpen((prev) => !prev);
290
+ const handleRecorderError = useCallback((error) => {
291
+ setVoiceError(error);
508
292
  }, []);
509
- const handleRetryDeepSearchPress = useCallback(() => {
510
- void handleRetryDeepSearch();
511
- }, [handleRetryDeepSearch]);
512
- useEffect(() => {
513
- if (!deepSearchQuery || isStreaming || !latestAssistantMessage) return;
514
- setDeepSearchSummary(normalizeSummaryText(latestAssistantMessage));
515
- setDeepSearchSources(extractDeepSearchSources(latestAssistantMessage));
516
- }, [deepSearchQuery, isStreaming, latestAssistantMessage]);
517
- const composerScrollBottomPadding = COMPOSER_SCROLL_RESERVE_PX;
518
293
  const leftItems = useMemo(() => getDefaultLeftItems({
519
294
  search: {
520
295
  active: activeMode === "chat",
@@ -525,7 +300,9 @@ function HomeScreenContent({
525
300
  onClick: () => handleModeSwitch("deep-search")
526
301
  },
527
302
  lightbulb: {
528
- enabled: false
303
+ onClick: () => {
304
+ console.log("build mode");
305
+ }
529
306
  }
530
307
  }), [activeMode, handleModeSwitch]);
531
308
  const rightItems = useMemo(() => getDefaultRightItems({
@@ -536,16 +313,13 @@ function HomeScreenContent({
536
313
  enabled: false
537
314
  },
538
315
  camera: {
539
- enabled: false,
540
- onClick: () => console.log("camera")
316
+ enabled: false
541
317
  },
542
318
  image: {
543
- enabled: false,
544
- onClick: () => console.log("image")
319
+ enabled: false
545
320
  },
546
321
  attach: {
547
- enabled: false,
548
- onClick: () => console.log("attach")
322
+ enabled: false
549
323
  }
550
324
  }), []);
551
325
  const inputConfig = useMemo(() => ({
@@ -559,136 +333,30 @@ function HomeScreenContent({
559
333
  onSend: () => handleSubmit(),
560
334
  onMic: handleMicPress,
561
335
  disabled: isLoading || disabled,
562
- isLoading,
563
- onStop: isStreaming ? cancel : onStop
564
- }), [canSubmit, handleSubmit, handleMicPress, isLoading, disabled, isStreaming, cancel, onStop]);
565
- return /* @__PURE__ */ jsxs(SafeAreaView, { edges: ["left", "right", "bottom"], style: {
336
+ isLoading
337
+ }), [canSubmit, handleSubmit, handleMicPress, isLoading, disabled]);
338
+ return /* @__PURE__ */ jsx(SafeAreaView, { edges: ["left", "right", "bottom"], style: {
566
339
  flex: 1,
567
340
  backgroundColor: surfaceColor
568
- }, children: [
569
- /* @__PURE__ */ jsx(TouchableWithoutFeedback, { onPress: Keyboard.dismiss, accessible: false, children: /* @__PURE__ */ jsxs(Box, { flex: 1, width: "100%", position: "relative", children: [
570
- (chatError || cdecli.error) && /* @__PURE__ */ jsx(Box, { mb: "$2", mx: "$4", p: "$3", borderRadius: "$md", style: {
341
+ }, children: /* @__PURE__ */ jsx(TouchableWithoutFeedback, { onPress: Keyboard.dismiss, accessible: false, children: /* @__PURE__ */ jsxs(Box, { flex: 1, width: "100%", position: "relative", children: [
342
+ /* @__PURE__ */ jsx(EmptyStateSection, { isDark, secondaryTextColor, primaryTextColor, activeMode, onModeSwitch: handleModeSwitch }),
343
+ /* @__PURE__ */ jsx(View, { style: [styles.bottomComposerWrap, {
344
+ bottom: Math.max(0, keyboardHeight - insets.bottom),
345
+ paddingBottom: Math.max(insets.bottom - 6, 2)
346
+ }], children: /* @__PURE__ */ jsxs(View, { style: [styles.bottomComposerInner, {
347
+ width: contentMaxWidth
348
+ }], children: [
349
+ voiceError ? /* @__PURE__ */ jsx(View, { style: [styles.voiceErrorBanner, {
571
350
  backgroundColor: isDark ? "#2b1a1d" : "#fef2f2",
572
- borderWidth: 1,
573
351
  borderColor: isDark ? "#7f1d1d" : "#fecaca"
574
- }, children: /* @__PURE__ */ jsx(Text, { fontSize: "$sm", style: {
352
+ }], children: /* @__PURE__ */ jsx(Text, { style: [styles.voiceErrorText, {
575
353
  color: isDark ? "#fecaca" : "#991b1b"
576
- }, children: chatError || cdecli.error }) }),
577
- showChatHistory ? /* @__PURE__ */ jsx(ChatHistoryLanding, { onSelectSession: handleSelectHistorySession, onCompose: handleComposeFromHistory }) : hasRenderableConversation ? /* @__PURE__ */ jsx(ChatContentSection, { contentMaxWidth, composerScrollBottomPadding, messages, response, isLoading, disabled, isStreaming, onStop, cancel, onSend: handleSendMessage, onBackPress: handleNewChat }) : /* @__PURE__ */ jsx(EmptyStateSection, { isDark, secondaryTextColor, primaryTextColor, activeMode, onModeSwitch: handleModeSwitch }),
578
- !showChatHistory ? /* @__PURE__ */ jsx(View, { style: [styles.bottomComposerWrap, {
579
- bottom: Math.max(0, keyboardHeight - insets.bottom),
580
- paddingBottom: Math.max(insets.bottom - 6, 2)
581
- // backgroundColor: composerBarBackground,
582
- // borderTopColor: composerBarBorder,
583
- }], children: /* @__PURE__ */ jsx(View, { style: [styles.bottomComposerInner, {
584
- width: contentMaxWidth
585
- }], children: /* @__PURE__ */ jsx(InputToolBar, { inputConfig, leftItems, rightItems, templateButton: null, templateModalConfig: null, micSendButton }) }) }) : null,
586
- showSendingLoader ? /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: pinSendingLoaderNearComposer ? [styles.sendingLoaderAboveComposer, {
587
- bottom: Math.max(insets.bottom, 12) + SENDING_LOADER_COMPOSER_RESERVE_PX
588
- }] : styles.sendingLoaderEmptyState, children: /* @__PURE__ */ jsx(YantraBrandLoader, { size: YANTRA_LOADER_SIZE_COMPACT }) }) : null
589
- ] }) }),
590
- /* @__PURE__ */ jsx(DeepSearchModal, { visible: isDeepSearchModalOpen, query: deepSearchQuery, summaryText: deepSearchPreviewNormalized, sources: deepSearchSources, isStreaming, researchProcessOpen, sourcesAccordionOpen, onToggleResearchProcess: handleToggleResearchProcess, onToggleSourcesAccordion: handleToggleSourcesAccordion, onRetry: handleRetryDeepSearchPress, onStop: cancel, onClose: handleDeepSearchClose })
591
- ] });
354
+ }], children: voiceError }) }) : null,
355
+ showAudioRecorder ? /* @__PURE__ */ jsx(AudioRecorderPanel, { isDark, onTranscriptionComplete: handleTranscriptionComplete, onCancel: handleRecorderCancel, onError: handleRecorderError }) : /* @__PURE__ */ jsx(InputToolBar, { inputConfig, leftItems, rightItems, templateButton: null, templateModalConfig: null, micSendButton })
356
+ ] }) })
357
+ ] }) }) });
592
358
  }
593
359
  const styles = StyleSheet.create({
594
- /** First message / empty screen: loader in the middle of the pane. */
595
- sendingLoaderEmptyState: {
596
- position: "absolute",
597
- left: 0,
598
- right: 0,
599
- top: 0,
600
- bottom: 0,
601
- justifyContent: "center",
602
- alignItems: "center",
603
- zIndex: 40
604
- },
605
- /** Active thread: loader just above the input, not over message history. */
606
- sendingLoaderAboveComposer: {
607
- position: "absolute",
608
- left: 0,
609
- right: 0,
610
- alignItems: "center",
611
- justifyContent: "flex-end",
612
- paddingBottom: 8,
613
- zIndex: 40
614
- },
615
- headerRight: {
616
- flexDirection: "row",
617
- alignItems: "center",
618
- marginRight: 6,
619
- gap: 6
620
- },
621
- historyHeaderButton: {
622
- marginHorizontal: 0,
623
- padding: 0,
624
- borderRadius: 22
625
- },
626
- historyHeaderButtonPressed: {
627
- opacity: 0.72
628
- },
629
- historyHeaderButtonInner: {
630
- width: 32,
631
- height: 32,
632
- borderRadius: 16,
633
- alignItems: "center",
634
- justifyContent: "center",
635
- backgroundColor: mobileTokens.color.primarySoft,
636
- borderWidth: StyleSheet.hairlineWidth,
637
- borderColor: mobileTokens.color.primaryBorder,
638
- shadowColor: "#312e81",
639
- shadowOpacity: 0.1,
640
- shadowRadius: 5,
641
- shadowOffset: {
642
- width: 0,
643
- height: 2
644
- },
645
- elevation: 2
646
- },
647
- historyHeaderButtonInnerDark: {
648
- backgroundColor: "#1e293b",
649
- borderColor: "rgba(148, 163, 184, 0.35)",
650
- shadowColor: "#111827"
651
- },
652
- newChatButton: {
653
- padding: 0,
654
- alignItems: "center",
655
- justifyContent: "center",
656
- borderRadius: 22
657
- },
658
- newChatButtonInner: {
659
- width: 32,
660
- height: 32,
661
- borderRadius: 16,
662
- alignItems: "center",
663
- justifyContent: "center",
664
- backgroundColor: mobileTokens.color.surface,
665
- borderWidth: 1,
666
- borderColor: mobileTokens.color.border,
667
- shadowColor: "#0f172a",
668
- shadowOpacity: 0.08,
669
- shadowRadius: 5,
670
- shadowOffset: {
671
- width: 0,
672
- height: 2
673
- },
674
- elevation: 2
675
- },
676
- newChatButtonInnerDark: {
677
- backgroundColor: "#0f172a",
678
- borderColor: "#334155"
679
- },
680
- backButton: {
681
- marginLeft: 6,
682
- width: 36,
683
- height: 36,
684
- borderRadius: 18,
685
- alignItems: "center",
686
- justifyContent: "center",
687
- backgroundColor: "#f3f4f6"
688
- },
689
- newChatButtonPressed: {
690
- opacity: 0.6
691
- },
692
360
  emptyCenterTitleWrap: {
693
361
  flex: 1,
694
362
  alignItems: "center",
@@ -729,7 +397,6 @@ const styles = StyleSheet.create({
729
397
  bottom: 0,
730
398
  alignItems: "center",
731
399
  justifyContent: "flex-end",
732
- // borderTopWidth: 1,
733
400
  shadowColor: "#0f172a",
734
401
  shadowOpacity: 0.08,
735
402
  shadowRadius: 8,
@@ -745,6 +412,17 @@ const styles = StyleSheet.create({
745
412
  paddingTop: 10,
746
413
  paddingBottom: 4
747
414
  },
415
+ voiceErrorBanner: {
416
+ marginBottom: 8,
417
+ paddingHorizontal: 12,
418
+ paddingVertical: 8,
419
+ borderRadius: 10,
420
+ borderWidth: 1
421
+ },
422
+ voiceErrorText: {
423
+ fontSize: 12,
424
+ fontWeight: "500"
425
+ },
748
426
  emptyModePillRow: {
749
427
  flexDirection: "row",
750
428
  alignItems: "center",