@adminide-stack/yantra-mobile 12.0.28-alpha.54 → 12.0.28-alpha.59

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 (55) hide show
  1. package/lib/assets/icon.png +0 -0
  2. package/lib/components/CustomDrawer.js +358 -0
  3. package/lib/components/CustomDrawer.js.map +1 -0
  4. package/lib/components/GatewayToolbarButtonMobile.js +84 -0
  5. package/lib/components/GatewayToolbarButtonMobile.js.map +1 -0
  6. package/lib/components/YantraBrandLoader.js +94 -0
  7. package/lib/components/YantraBrandLoader.js.map +1 -0
  8. package/lib/compute.js +37 -5
  9. package/lib/compute.js.map +1 -1
  10. package/lib/config/constants.js +16 -0
  11. package/lib/config/constants.js.map +1 -0
  12. package/lib/config/env-config.js +74 -19
  13. package/lib/config/env-config.js.map +1 -1
  14. package/lib/contexts/GatewayContext.js +77 -0
  15. package/lib/contexts/GatewayContext.js.map +1 -0
  16. package/lib/graphql/agentGatewayDocuments.js +53 -0
  17. package/lib/graphql/agentGatewayDocuments.js.map +1 -0
  18. package/lib/hooks/useCdecliAutoConnect.js +219 -0
  19. package/lib/hooks/useCdecliAutoConnect.js.map +1 -0
  20. package/lib/hooks/useCdecliChannel.js +226 -0
  21. package/lib/hooks/useCdecliChannel.js.map +1 -0
  22. package/lib/hooks/useChatApi.js +220 -170
  23. package/lib/hooks/useChatApi.js.map +1 -1
  24. package/lib/hooks/useChatStream.js +232 -58
  25. package/lib/hooks/useChatStream.js.map +1 -1
  26. package/lib/hooks/useGatewayConnection.js +123 -0
  27. package/lib/hooks/useGatewayConnection.js.map +1 -0
  28. package/lib/hooks/useGatewayRegistry.js +28 -0
  29. package/lib/hooks/useGatewayRegistry.js.map +1 -0
  30. package/lib/hooks/usePrerequisiteIds.js +122 -0
  31. package/lib/hooks/usePrerequisiteIds.js.map +1 -0
  32. package/lib/hooks/useWorkspaceProvisioner.js +236 -0
  33. package/lib/hooks/useWorkspaceProvisioner.js.map +1 -0
  34. package/lib/index.js +1 -1
  35. package/lib/index.js.map +1 -1
  36. package/lib/routes.json +8 -5
  37. package/lib/screens/Home/HomeScreen.js +420 -97
  38. package/lib/screens/Home/HomeScreen.js.map +1 -1
  39. package/lib/screens/Home/components/ChatHistoryLanding.js +229 -0
  40. package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -0
  41. package/lib/screens/Home/components/DeepSearchModal.js +334 -0
  42. package/lib/screens/Home/components/DeepSearchModal.js.map +1 -0
  43. package/lib/screens/Home/deepSearchUtils.js +41 -0
  44. package/lib/screens/Home/deepSearchUtils.js.map +1 -0
  45. package/lib/screens/NewChat/index.js +75 -0
  46. package/lib/screens/NewChat/index.js.map +1 -0
  47. package/lib/services/agentSessionManager.js +451 -0
  48. package/lib/services/agentSessionManager.js.map +1 -0
  49. package/lib/services/gatewayApiKeyBridge.js +4 -0
  50. package/lib/services/gatewayApiKeyBridge.js.map +1 -0
  51. package/lib/services/gatewayClient.js +470 -0
  52. package/lib/services/gatewayClient.js.map +1 -0
  53. package/lib/utils/gatewaySelectionStorage.js +21 -0
  54. package/lib/utils/gatewaySelectionStorage.js.map +1 -0
  55. package/package.json +7 -3
@@ -1,4 +1,4 @@
1
- import {jsx,jsxs}from'react/jsx-runtime';import {useState,useCallback,useEffect}from'react';import {Pressable,StyleSheet}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {getDefaultLeftItems,getDefaultRightItems,Box,Text,InputToolBar}from'@admin-layout/gluestack-ui-mobile';import {SafeAreaView}from'react-native-safe-area-context';import {useGetAccountChatSessionsQuery}from'common/graphql';import {v4}from'uuid';import {useNavigation}from'@react-navigation/native';import {MessagesContainerUI}from'@messenger-box/platform-mobile';import {useChatMutations}from'../../hooks/useChatApi.js';import {useChatStream}from'../../hooks/useChatStream.js';var __defProp = Object.defineProperty;
1
+ import {jsx,jsxs}from'react/jsx-runtime';import React,{useState,useMemo,useCallback,useEffect}from'react';import {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 {navigationRef}from'@common-stack/client-react';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,6 +14,41 @@ var __spreadValues = (a, b) => {
14
14
  }
15
15
  return a;
16
16
  };
17
+ const SENDING_LOADER_COMPOSER_RESERVE_PX = 156;
18
+ function organizationFromSettingsValue(settings) {
19
+ if (settings == null) return null;
20
+ if (typeof settings === "string") {
21
+ try {
22
+ const parsed = JSON.parse(settings);
23
+ const o = parsed == null ? void 0 : parsed.organization;
24
+ return typeof o === "string" && o.trim() ? o.trim() : null;
25
+ } catch (e) {
26
+ return null;
27
+ }
28
+ }
29
+ if (typeof settings === "object" && settings !== null && "organization" in settings) {
30
+ const o = settings.organization;
31
+ return typeof o === "string" && o.trim() ? o.trim() : null;
32
+ }
33
+ return null;
34
+ }
35
+ function projectFromSettingsValue(settings) {
36
+ if (settings == null) return null;
37
+ if (typeof settings === "string") {
38
+ try {
39
+ const parsed = JSON.parse(settings);
40
+ const p = parsed == null ? void 0 : parsed.project;
41
+ return typeof p === "string" && p.trim() ? p.trim() : null;
42
+ } catch (e) {
43
+ return null;
44
+ }
45
+ }
46
+ if (typeof settings === "object" && settings !== null && "project" in settings) {
47
+ const p = settings.project;
48
+ return typeof p === "string" && p.trim() ? p.trim() : null;
49
+ }
50
+ return null;
51
+ }
17
52
  function HomeScreenContent({
18
53
  initialMode = "chat",
19
54
  onSubmit: onSubmitProp,
@@ -21,21 +56,74 @@ function HomeScreenContent({
21
56
  isLoading: isLoadingProp = false,
22
57
  disabled = false
23
58
  }) {
59
+ var _a, _b, _c, _d, _e, _f, _g;
24
60
  const navigation = useNavigation();
61
+ const route = useRoute();
62
+ const hasRehydratedOrgRef = React.useRef(false);
25
63
  const [value, setValue] = useState("");
26
64
  const [activeMode, setActiveMode] = useState(initialMode);
27
65
  const [activeSessionId, setActiveSessionId] = useState(null);
66
+ const [isDeepSearchModalOpen, setIsDeepSearchModalOpen] = useState(false);
67
+ const [deepSearchQuery, setDeepSearchQuery] = useState(null);
68
+ const [deepSearchSummary, setDeepSearchSummary] = useState("");
69
+ const [deepSearchSources, setDeepSearchSources] = useState([]);
70
+ const [researchProcessOpen, setResearchProcessOpen] = useState(true);
71
+ const [sourcesAccordionOpen, setSourcesAccordionOpen] = useState(true);
72
+ const [showChatHistory, setShowChatHistory] = useState(false);
73
+ const [channelBootstrap, setChannelBootstrap] = useState(false);
28
74
  const {
29
- createSession
75
+ createChannel
30
76
  } = useChatMutations();
31
- const chat = useChatStream(activeSessionId);
32
- useGetAccountChatSessionsQuery({
77
+ useChatSessions();
78
+ const {
79
+ orgName: resolvedOrgName,
80
+ projectId
81
+ } = usePrerequisiteIds();
82
+ const {
83
+ data: contextData
84
+ } = useGetContextDataQuery();
85
+ const cdecodeUri = (_a = contextData == null ? void 0 : contextData.getContextData) == null ? void 0 : _a.cdecodeUri;
86
+ const {
87
+ data: pageSettingsData
88
+ } = useGetPageSettingsQuery({
33
89
  variables: {
34
- first: 25,
35
- includeArchived: false
90
+ resourceUri: cdecodeUri,
91
+ options: {
92
+ schemaId: ContributionSchemaId.Configuration,
93
+ configKey: "account.default",
94
+ includeMarketplace: true
95
+ }
36
96
  },
97
+ skip: !cdecodeUri,
37
98
  fetchPolicy: "cache-first"
38
99
  });
100
+ const fallbackOrgNameFromSettings = useMemo(() => {
101
+ var _a2;
102
+ return organizationFromSettingsValue((_a2 = pageSettingsData == null ? void 0 : pageSettingsData.pageSettings) == null ? void 0 : _a2.settings);
103
+ }, [pageSettingsData]);
104
+ const fallbackProjectIdFromSettings = useMemo(() => {
105
+ var _a2;
106
+ return projectFromSettingsValue((_a2 = pageSettingsData == null ? void 0 : pageSettingsData.pageSettings) == null ? void 0 : _a2.settings);
107
+ }, [pageSettingsData]);
108
+ const routeOrgName = ((_c = (_b = route == null ? void 0 : route.params) == null ? void 0 : _b.orgName) != null ? _c : "").trim() || null;
109
+ const effectiveOrgName = resolvedOrgName || fallbackOrgNameFromSettings || routeOrgName || null;
110
+ const effectiveProjectId = projectId || fallbackProjectIdFromSettings || null;
111
+ const {
112
+ selectedGateway
113
+ } = useGatewayContext();
114
+ const cdecliSelected = (selectedGateway == null ? void 0 : selectedGateway.channelType) === "cdecli-serve";
115
+ const cdecli = useCdecliAutoConnect(cdecliSelected, activeSessionId != null ? activeSessionId : void 0);
116
+ const cdecliConnected = cdecliSelected && cdecli.channelConnected;
117
+ const effectivePersistenceMode = (_e = (_d = cdecli.persistenceMode) != null ? _d : selectedGateway == null ? void 0 : selectedGateway.persistenceMode) != null ? _e : "frontend";
118
+ const chatRouting = useMemo(() => cdecliConnected ? {
119
+ kind: "cdecli",
120
+ channelConnected: cdecli.channelConnected,
121
+ accountId: cdecli.accountId,
122
+ persistenceMode: effectivePersistenceMode
123
+ } : {
124
+ kind: "groq"
125
+ }, [cdecliConnected, cdecli.channelConnected, cdecli.accountId, effectivePersistenceMode]);
126
+ const chat = useChatStream(activeSessionId, chatRouting);
39
127
  const {
40
128
  messages,
41
129
  response,
@@ -44,17 +132,48 @@ function HomeScreenContent({
44
132
  isStreaming,
45
133
  hasMessages,
46
134
  sendMessage,
47
- cancel
135
+ cancel,
136
+ clearMessages
48
137
  } = chat;
49
138
  const trimmedQuery = value.trim();
50
139
  const hasQuery = trimmedQuery.length > 0;
51
- const canSubmit = hasQuery;
140
+ const canSubmit = hasQuery && Boolean(routeOrgName || effectiveOrgName);
52
141
  const isLoading = isLoadingProp || chatLoading;
53
142
  const isResearchMode = activeMode === "deep-search";
54
- const inputPlaceholder = isResearchMode ? "Research anything..." : "Ask anything...";
143
+ const inputPlaceholder = !effectiveOrgName ? "Initializing workspace..." : isResearchMode ? "Research anything..." : "Ask anything...";
144
+ const waitingForAssistant = useMemo(() => {
145
+ var _a2;
146
+ if (!chatLoading && !isStreaming || messages.length === 0) return false;
147
+ return ((_a2 = messages[messages.length - 1]) == null ? void 0 : _a2.role) === "user";
148
+ }, [chatLoading, isStreaming, messages]);
149
+ const pinSendingLoaderNearComposer = useMemo(() => messages.length > 0 || Boolean((response != null ? response : "").trim()), [messages.length, response]);
150
+ const showSendingLoader = !showChatHistory && (channelBootstrap || waitingForAssistant);
151
+ const insets = useSafeAreaInsets();
55
152
  const handleModeSwitch = useCallback((mode) => {
56
153
  setActiveMode(mode);
57
154
  }, []);
155
+ const ensureSessionId = useCallback(async (mode) => {
156
+ if (activeSessionId) return activeSessionId;
157
+ if (!effectiveOrgName || !effectiveProjectId) {
158
+ throw new Error("Workspace is still initializing. Please retry in a moment.");
159
+ }
160
+ const requestedChannelId = v4();
161
+ const title = mode === "deep-search" ? `deep-search-${requestedChannelId}` : `chat-channel-${requestedChannelId}`;
162
+ const session = await createChannel({
163
+ id: requestedChannelId,
164
+ title,
165
+ isShared: false,
166
+ sharedSlug: null,
167
+ isArchived: false,
168
+ isPinned: false,
169
+ model: null,
170
+ systemPrompt: null,
171
+ orgName: effectiveOrgName,
172
+ projectId: effectiveProjectId
173
+ });
174
+ setActiveSessionId(session.id);
175
+ return session.id;
176
+ }, [activeSessionId, createChannel, effectiveOrgName, effectiveProjectId]);
58
177
  const handleSubmit = useCallback(async (attachments) => {
59
178
  if (!canSubmit || isLoading || disabled) return;
60
179
  const submission = {
@@ -62,9 +181,24 @@ function HomeScreenContent({
62
181
  query: trimmedQuery,
63
182
  attachments
64
183
  };
65
- if (activeMode === "deep-search" && onSubmitProp) {
66
- onSubmitProp(submission);
184
+ if (activeMode === "deep-search") {
185
+ if (onSubmitProp) {
186
+ onSubmitProp(submission);
187
+ }
67
188
  setValue("");
189
+ setDeepSearchQuery(trimmedQuery);
190
+ setDeepSearchSummary("");
191
+ setDeepSearchSources([]);
192
+ setIsDeepSearchModalOpen(true);
193
+ try {
194
+ setChannelBootstrap(true);
195
+ const sessionId = await ensureSessionId("deep-search");
196
+ await sendMessage(trimmedQuery, void 0, sessionId);
197
+ } catch (err) {
198
+ console.error("[HomeScreen] Failed to create deep-search session:", err);
199
+ } finally {
200
+ setChannelBootstrap(false);
201
+ }
68
202
  return;
69
203
  }
70
204
  if (onSubmitProp && activeMode === "chat") {
@@ -72,63 +206,111 @@ function HomeScreenContent({
72
206
  setValue("");
73
207
  return;
74
208
  }
75
- if (!activeSessionId) {
76
- const newSessionId = v4();
77
- const title = activeMode === "deep-search" ? "Deep Search" : "New Chat";
78
- try {
79
- await createSession({
80
- id: newSessionId,
81
- title
82
- });
83
- setActiveSessionId(newSessionId);
84
- setValue("");
85
- sendMessage(trimmedQuery, void 0, newSessionId);
86
- } catch (err) {
87
- console.error("[HomeScreen] Failed to create session:", err);
88
- }
89
- } else {
209
+ try {
210
+ setChannelBootstrap(true);
211
+ const sessionId = await ensureSessionId("chat");
90
212
  setValue("");
91
- sendMessage(trimmedQuery);
213
+ await sendMessage(trimmedQuery, void 0, sessionId);
214
+ } catch (err) {
215
+ console.error("[HomeScreen] Failed to create session:", err);
216
+ } finally {
217
+ setChannelBootstrap(false);
92
218
  }
93
- }, [canSubmit, isLoading, disabled, activeMode, trimmedQuery, activeSessionId, onSubmitProp, createSession, sendMessage]);
219
+ }, [canSubmit, isLoading, disabled, activeMode, trimmedQuery, activeSessionId, onSubmitProp, ensureSessionId, sendMessage]);
94
220
  const handleNewChat = useCallback(() => {
221
+ setShowChatHistory(false);
95
222
  setActiveSessionId(null);
96
223
  setValue("");
224
+ clearMessages();
225
+ }, [clearMessages]);
226
+ const handleOpenChatHistory = useCallback(() => {
227
+ setShowChatHistory(true);
228
+ }, []);
229
+ const handleCloseChatHistory = useCallback(() => {
230
+ setShowChatHistory(false);
97
231
  }, []);
232
+ const handleToggleGateway = useCallback(() => {
233
+ }, []);
234
+ const gatewayToolbarStatus = cdecli.status === "connecting" ? "connecting" : cdecli.status === "connected" ? "connected" : cdecli.status === "error" ? "error" : "disconnected";
235
+ const gatewayToolbarTone = "default";
236
+ const gatewayToolbarLabel = cdecli.status === "connecting" ? "Checking..." : void 0;
237
+ const gatewayToolbarError = cdecli.error;
238
+ useEffect(() => {
239
+ var _a2, _b2, _c2;
240
+ const currentOrgName = ((_b2 = (_a2 = route == null ? void 0 : route.params) == null ? void 0 : _a2.orgName) == null ? void 0 : _b2.trim()) || "";
241
+ if (!effectiveOrgName || currentOrgName === effectiveOrgName) return;
242
+ (_c2 = navigation.setParams) == null ? void 0 : _c2.call(navigation, {
243
+ orgName: effectiveOrgName
244
+ });
245
+ }, [navigation, (_f = route == null ? void 0 : route.params) == null ? void 0 : _f.orgName, effectiveOrgName]);
246
+ useEffect(() => {
247
+ var _a2, _b2, _c2;
248
+ const currentOrgName = ((_b2 = (_a2 = route == null ? void 0 : route.params) == null ? void 0 : _a2.orgName) == null ? void 0 : _b2.trim()) || "";
249
+ if (hasRehydratedOrgRef.current || currentOrgName || !effectiveOrgName) return;
250
+ hasRehydratedOrgRef.current = true;
251
+ console.log("effectiveOrgName..", effectiveOrgName);
252
+ (_c2 = navigation.getParent()) == null ? void 0 : _c2.dispatch(CommonActions.navigate("MainStack", {
253
+ screen: "MainStack.Layout.Home",
254
+ params: {
255
+ orgName: effectiveOrgName
256
+ },
257
+ merge: true,
258
+ key: Date.now().toString()
259
+ }));
260
+ }, [navigation, (_g = route == null ? void 0 : route.params) == null ? void 0 : _g.orgName, effectiveOrgName, navigationRef]);
98
261
  useEffect(() => {
99
262
  navigation.setOptions({
100
- headerRight: () => /* @__PURE__ */ jsx(Pressable, { onPress: handleNewChat, style: ({
263
+ drawerLabel: "Chat",
264
+ headerTitle: showChatHistory ? "Chats" : "Yantra",
265
+ headerLeft: showChatHistory ? () => /* @__PURE__ */ jsx(Pressable, { onPress: handleCloseChatHistory, style: ({
101
266
  pressed
102
- }) => [styles.newChatButton, pressed && styles.newChatButtonPressed], accessibilityLabel: "New chat", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chat-plus-outline", size: 26, color: "#000" }) })
267
+ }) => [styles.backButton, pressed && styles.newChatButtonPressed], accessibilityLabel: "Back to chat", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chevron-left", size: 24, color: "#111827" }) }) : void 0,
268
+ headerRight: () => /* @__PURE__ */ jsxs(View, { style: styles.headerRight, children: [
269
+ /* @__PURE__ */ jsx(GatewayToolbarButtonMobile, { gatewayStatus: gatewayToolbarStatus, gatewayError: gatewayToolbarError, onToggleGateway: handleToggleGateway, disabled: false, statusLabel: gatewayToolbarLabel, tone: gatewayToolbarTone }),
270
+ !showChatHistory ? /* @__PURE__ */ jsx(Pressable, { onPress: handleOpenChatHistory, style: ({
271
+ pressed
272
+ }) => [styles.historyHeaderButton, pressed && styles.historyHeaderButtonPressed], accessibilityLabel: "Chat history", accessibilityRole: "button", children: /* @__PURE__ */ jsx(View, { style: styles.historyHeaderButtonInner, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "history", size: 19, color: "#4338ca" }) }) }) : null,
273
+ /* @__PURE__ */ jsx(Pressable, { onPress: handleNewChat, style: ({
274
+ pressed
275
+ }) => [styles.newChatButton, pressed && styles.newChatButtonPressed], accessibilityLabel: "New chat", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chat-plus-outline", size: 26, color: "#000" }) })
276
+ ] })
103
277
  });
104
- }, [navigation, handleNewChat]);
278
+ }, [navigation, showChatHistory, handleCloseChatHistory, handleOpenChatHistory, handleNewChat, handleToggleGateway, gatewayToolbarStatus, gatewayToolbarError, gatewayToolbarLabel, gatewayToolbarTone]);
105
279
  const handleSendMessage = useCallback(async (text) => {
106
280
  if (!text.trim() || isLoading || disabled) return;
107
281
  const submission = {
108
282
  mode: activeMode,
109
283
  query: text.trim()
110
284
  };
111
- if (activeMode === "deep-search" && onSubmitProp) {
112
- onSubmitProp(submission);
113
- return;
114
- }
115
- if (!activeSessionId) {
116
- const newSessionId = v4();
117
- const title = activeMode === "deep-search" ? "Deep Search" : "New Chat";
285
+ if (activeMode === "deep-search") {
286
+ if (onSubmitProp) {
287
+ onSubmitProp(submission);
288
+ }
289
+ setDeepSearchQuery(text.trim());
290
+ setDeepSearchSummary("");
291
+ setDeepSearchSources([]);
292
+ setIsDeepSearchModalOpen(true);
118
293
  try {
119
- await createSession({
120
- id: newSessionId,
121
- title
122
- });
123
- setActiveSessionId(newSessionId);
124
- sendMessage(text.trim(), void 0, newSessionId);
294
+ setChannelBootstrap(true);
295
+ const sessionId = await ensureSessionId("deep-search");
296
+ await sendMessage(text.trim(), void 0, sessionId);
125
297
  } catch (err) {
126
- console.error("[HomeScreen] Failed to create session:", err);
298
+ console.error("[HomeScreen] Failed to create deep-search session:", err);
299
+ } finally {
300
+ setChannelBootstrap(false);
127
301
  }
128
- } else {
129
- sendMessage(text.trim());
302
+ return;
130
303
  }
131
- }, [isLoading, disabled, activeSessionId, activeMode, onSubmitProp, createSession, sendMessage]);
304
+ try {
305
+ setChannelBootstrap(true);
306
+ const sessionId = await ensureSessionId("chat");
307
+ await sendMessage(text.trim(), void 0, sessionId);
308
+ } catch (err) {
309
+ console.error("[HomeScreen] Failed to create session:", err);
310
+ } finally {
311
+ setChannelBootstrap(false);
312
+ }
313
+ }, [isLoading, disabled, activeMode, onSubmitProp, ensureSessionId, sendMessage]);
132
314
  const leftItems = getDefaultLeftItems({
133
315
  search: {
134
316
  active: activeMode === "chat",
@@ -150,75 +332,216 @@ function HomeScreenContent({
150
332
  enabled: false
151
333
  },
152
334
  camera: {
335
+ enabled: false,
153
336
  onClick: () => console.log("camera")
154
337
  },
155
338
  image: {
339
+ enabled: false,
156
340
  onClick: () => console.log("image")
157
341
  },
158
342
  attach: {
343
+ enabled: false,
159
344
  onClick: () => console.log("attach")
160
345
  }
161
346
  });
162
- return /* @__PURE__ */ jsx(SafeAreaView, { style: {
347
+ const latestAssistantMessage = useMemo(() => {
348
+ var _a2, _b2, _c2;
349
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
350
+ if (((_a2 = messages[i]) == null ? void 0 : _a2.role) === "assistant") return (_c2 = (_b2 = messages[i]) == null ? void 0 : _b2.content) != null ? _c2 : "";
351
+ }
352
+ return "";
353
+ }, [messages]);
354
+ const deepSearchPreviewContent = response || deepSearchSummary;
355
+ const deepSearchPreviewNormalized = useMemo(() => normalizeSummaryText(deepSearchPreviewContent || deepSearchSummary || ""), [deepSearchPreviewContent, deepSearchSummary]);
356
+ const handleDeepSearchClose = useCallback(() => {
357
+ if (isStreaming) {
358
+ cancel();
359
+ }
360
+ setIsDeepSearchModalOpen(false);
361
+ setDeepSearchQuery(null);
362
+ setDeepSearchSummary("");
363
+ setDeepSearchSources([]);
364
+ setResearchProcessOpen(true);
365
+ setSourcesAccordionOpen(true);
366
+ }, [isStreaming, cancel]);
367
+ const handleRetryDeepSearch = useCallback(async () => {
368
+ if (!deepSearchQuery || isStreaming) return;
369
+ try {
370
+ setChannelBootstrap(true);
371
+ const sessionId = await ensureSessionId("deep-search");
372
+ await sendMessage(deepSearchQuery, void 0, sessionId);
373
+ } catch (error) {
374
+ console.error("[HomeScreen] Failed to retry deep-search:", error);
375
+ } finally {
376
+ setChannelBootstrap(false);
377
+ }
378
+ }, [deepSearchQuery, isStreaming, ensureSessionId, sendMessage]);
379
+ useEffect(() => {
380
+ if (!deepSearchQuery || isStreaming || !latestAssistantMessage) return;
381
+ setDeepSearchSummary(normalizeSummaryText(latestAssistantMessage));
382
+ setDeepSearchSources(extractDeepSearchSources(latestAssistantMessage));
383
+ }, [deepSearchQuery, isStreaming, latestAssistantMessage]);
384
+ return /* @__PURE__ */ jsxs(SafeAreaView, { edges: ["left", "right", "bottom"], style: {
163
385
  flex: 1,
164
386
  backgroundColor: "#fff"
165
- }, children: /* @__PURE__ */ jsxs(Box, { flex: 1, width: "100%", children: [
166
- chatError && /* @__PURE__ */ jsx(Box, { mb: "$2", mx: "$4", p: "$3", bg: "$gray200", borderRadius: "$md", children: /* @__PURE__ */ jsx(Text, { fontSize: "$sm", color: "$gray900", children: chatError }) }),
167
- hasMessages || response ? /* @__PURE__ */ jsx(Box, { flex: 1, width: "100%", alignSelf: "stretch", children: /* @__PURE__ */ jsx(MessagesContainerUI, { mode: "plan", showBackButton: false, onBackPress: handleNewChat, compactTop: true, messagesContainerStyle: {
168
- paddingHorizontal: 0,
169
- paddingTop: 0,
170
- margin: 0
171
- }, listContentStyle: {
172
- paddingTop: 0,
173
- margin: 0
174
- }, messages: messages.map((msg, index) => ({
175
- id: `msg-${index}-${msg.role}`,
176
- role: msg.role,
177
- content: msg.content,
178
- metadata: msg.metadata
179
- })), streamingContent: response, currentUser: {
180
- id: "user"
181
- }, onSend: handleSendMessage, disabled: isLoading || disabled, isLoading, onStop: isStreaming ? cancel : onStop, renderPlanInputToolbar: ({
182
- value: value2,
183
- onChange,
184
- onSend,
185
- disabled: inputDisabled
186
- }) => /* @__PURE__ */ jsx(InputToolBar, { inputConfig: {
187
- value: value2,
188
- onChange: (e) => onChange(e.nativeEvent.text),
189
- placeholder: inputPlaceholder,
190
- disabled: inputDisabled
191
- }, leftItems, rightItems, templateButton: null, templateModalConfig: null, micSendButton: {
192
- hasContent: value2.trim().length > 0,
193
- onSend: () => onSend(value2.trim()),
194
- onMic: () => console.log("mic"),
195
- disabled: inputDisabled,
196
- isLoading,
197
- onStop: isStreaming ? cancel : onStop
198
- } }), renderBuildInputToolbar: () => null }) }) : /* @__PURE__ */ jsx(Box, { flex: 1, justifyContent: "center", alignItems: "stretch", p: "$4", children: /* @__PURE__ */ jsx(InputToolBar, { inputConfig: {
199
- value,
200
- onChange: (e) => setValue(e.nativeEvent.text),
201
- placeholder: inputPlaceholder,
202
- disabled: isLoading || disabled
203
- }, leftItems, rightItems, templateButton: null, templateModalConfig: null, micSendButton: {
204
- hasContent: canSubmit,
205
- onSend: () => handleSubmit(),
206
- onMic: () => console.log("mic"),
207
- disabled: isLoading || disabled,
208
- isLoading,
209
- onStop
210
- } }) })
211
- ] }) });
387
+ }, children: [
388
+ /* @__PURE__ */ jsxs(Box, { flex: 1, width: "100%", position: "relative", children: [
389
+ (chatError || cdecli.error) && /* @__PURE__ */ jsx(Box, { mb: "$2", mx: "$4", p: "$3", bg: "$gray200", borderRadius: "$md", children: /* @__PURE__ */ jsx(Text, { fontSize: "$sm", color: "$gray900", children: chatError || cdecli.error }) }),
390
+ showChatHistory ? /* @__PURE__ */ jsx(ChatHistoryLanding, { onSelectSession: (channelId) => {
391
+ setShowChatHistory(false);
392
+ setActiveSessionId(channelId);
393
+ setActiveMode("chat");
394
+ }, onCompose: () => {
395
+ setShowChatHistory(false);
396
+ setActiveSessionId(null);
397
+ setValue("");
398
+ clearMessages();
399
+ } }) : hasMessages || response ? /* @__PURE__ */ jsx(Box, { flex: 1, width: "100%", alignSelf: "stretch", children: /* @__PURE__ */ jsx(MessagesContainerUI, { mode: "chat", showBackButton: false, onBackPress: handleNewChat, compactTop: false, messagesContainerStyle: {
400
+ paddingHorizontal: 0,
401
+ paddingTop: 6,
402
+ margin: 0
403
+ }, listContentStyle: {
404
+ paddingTop: 8,
405
+ margin: 0
406
+ }, messages: messages.map((msg, index) => ({
407
+ id: `msg-${index}-${msg.role}`,
408
+ role: msg.role,
409
+ content: msg.content,
410
+ metadata: msg.metadata
411
+ })), streamingContent: response, currentUser: {
412
+ id: "user"
413
+ }, onSend: handleSendMessage, disabled: isLoading || disabled, isLoading, onStop: isStreaming ? cancel : onStop, renderPlanInputToolbar: ({
414
+ value: value2,
415
+ onChange,
416
+ onSend,
417
+ disabled: inputDisabled
418
+ }) => /* @__PURE__ */ jsx(InputToolBar, { inputConfig: {
419
+ value: value2,
420
+ onChange: (e) => onChange(e.nativeEvent.text),
421
+ placeholder: inputPlaceholder,
422
+ disabled: inputDisabled
423
+ }, leftItems, rightItems, templateButton: null, templateModalConfig: null, micSendButton: {
424
+ hasContent: value2.trim().length > 0,
425
+ onSend: () => onSend(value2.trim()),
426
+ onMic: () => console.log("mic"),
427
+ disabled: inputDisabled,
428
+ isLoading,
429
+ onStop: isStreaming ? cancel : onStop
430
+ } }), renderBuildInputToolbar: () => null }) }) : /* @__PURE__ */ jsxs(Box, { flex: 1, width: "100%", children: [
431
+ /* @__PURE__ */ jsx(View, { style: styles.emptyCenterTitleWrap, children: /* @__PURE__ */ jsx(Text, { style: styles.emptyCenterTitle, children: "What can I do for you?" }) }),
432
+ /* @__PURE__ */ jsx(View, { style: [styles.bottomComposerWrap, {
433
+ paddingBottom: Math.max(insets.bottom - 6, 2),
434
+ marginBottom: -Math.max(insets.bottom - 2, 0)
435
+ }], children: /* @__PURE__ */ jsx(InputToolBar, { inputConfig: {
436
+ value,
437
+ onChange: (e) => setValue(e.nativeEvent.text),
438
+ placeholder: inputPlaceholder,
439
+ disabled: isLoading || disabled
440
+ }, leftItems, rightItems, templateButton: null, templateModalConfig: null, micSendButton: {
441
+ hasContent: canSubmit,
442
+ onSend: () => handleSubmit(),
443
+ onMic: () => console.log("mic"),
444
+ disabled: isLoading || disabled,
445
+ isLoading,
446
+ onStop
447
+ } }) })
448
+ ] }),
449
+ showSendingLoader ? /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: pinSendingLoaderNearComposer ? [styles.sendingLoaderAboveComposer, {
450
+ bottom: Math.max(insets.bottom, 12) + SENDING_LOADER_COMPOSER_RESERVE_PX
451
+ }] : styles.sendingLoaderEmptyState, children: /* @__PURE__ */ jsx(YantraBrandLoader, { size: YANTRA_LOADER_SIZE_COMPACT }) }) : null
452
+ ] }),
453
+ /* @__PURE__ */ jsx(DeepSearchModal, { visible: isDeepSearchModalOpen, query: deepSearchQuery, summaryText: deepSearchPreviewNormalized, sources: deepSearchSources, isStreaming, researchProcessOpen, sourcesAccordionOpen, onToggleResearchProcess: () => setResearchProcessOpen((prev) => !prev), onToggleSourcesAccordion: () => setSourcesAccordionOpen((prev) => !prev), onRetry: () => {
454
+ void handleRetryDeepSearch();
455
+ }, onStop: cancel, onClose: handleDeepSearchClose })
456
+ ] });
212
457
  }
213
458
  const styles = StyleSheet.create({
459
+ /** First message / empty screen: loader in the middle of the pane. */
460
+ sendingLoaderEmptyState: {
461
+ position: "absolute",
462
+ left: 0,
463
+ right: 0,
464
+ top: 0,
465
+ bottom: 0,
466
+ justifyContent: "center",
467
+ alignItems: "center",
468
+ zIndex: 40
469
+ },
470
+ /** Active thread: loader just above the input, not over message history. */
471
+ sendingLoaderAboveComposer: {
472
+ position: "absolute",
473
+ left: 0,
474
+ right: 0,
475
+ alignItems: "center",
476
+ justifyContent: "flex-end",
477
+ paddingBottom: 8,
478
+ zIndex: 40
479
+ },
480
+ headerRight: {
481
+ flexDirection: "row",
482
+ alignItems: "center",
483
+ marginRight: 4,
484
+ gap: 2
485
+ },
486
+ historyHeaderButton: {
487
+ marginHorizontal: 2,
488
+ padding: 4,
489
+ borderRadius: 22
490
+ },
491
+ historyHeaderButtonPressed: {
492
+ opacity: 0.72
493
+ },
494
+ historyHeaderButtonInner: {
495
+ width: 36,
496
+ height: 36,
497
+ borderRadius: 18,
498
+ alignItems: "center",
499
+ justifyContent: "center",
500
+ backgroundColor: "#eef2ff",
501
+ borderWidth: StyleSheet.hairlineWidth,
502
+ borderColor: "rgba(67, 56, 202, 0.22)",
503
+ shadowColor: "#4338ca",
504
+ shadowOpacity: 0.12,
505
+ shadowRadius: 6,
506
+ shadowOffset: {
507
+ width: 0,
508
+ height: 2
509
+ },
510
+ elevation: 2
511
+ },
214
512
  newChatButton: {
215
513
  padding: 6,
216
- marginRight: 4,
217
514
  alignItems: "center",
218
515
  justifyContent: "center"
219
516
  },
517
+ backButton: {
518
+ marginLeft: 6,
519
+ width: 36,
520
+ height: 36,
521
+ borderRadius: 18,
522
+ alignItems: "center",
523
+ justifyContent: "center",
524
+ backgroundColor: "#f3f4f6"
525
+ },
220
526
  newChatButtonPressed: {
221
527
  opacity: 0.6
528
+ },
529
+ emptyCenterTitleWrap: {
530
+ flex: 1,
531
+ alignItems: "center",
532
+ justifyContent: "center",
533
+ paddingHorizontal: 24,
534
+ paddingTop: 44
535
+ },
536
+ emptyCenterTitle: {
537
+ fontSize: 52 / 2,
538
+ fontWeight: "400",
539
+ color: "#111827",
540
+ textAlign: "center",
541
+ letterSpacing: 0.2
542
+ },
543
+ bottomComposerWrap: {
544
+ paddingHorizontal: 14
222
545
  }
223
546
  });
224
547
  const HomeScreen = (props) => /* @__PURE__ */ jsx(HomeScreenContent, __spreadValues({}, props));export{HomeScreen as default};//# sourceMappingURL=HomeScreen.js.map