@adminide-stack/yantra-mobile 12.0.69-alpha.9 → 12.0.70-alpha.0

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 (522) hide show
  1. package/lib/components/GatewayConnector/GatewayConnector.js +2 -2
  2. package/lib/components/GatewayConnector/GatewayConnector.js.map +1 -1
  3. package/lib/components/KeyboardComposerDock.js +8 -1
  4. package/lib/components/KeyboardComposerDock.js.map +1 -1
  5. package/lib/components/NavigationHeader/NavigationHeader.js +2 -2
  6. package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -1
  7. package/lib/config/env-config.js +4 -0
  8. package/lib/config/env-config.js.map +1 -1
  9. package/lib/contexts/ChatLiveStreamContext.js +4 -1
  10. package/lib/contexts/ChatLiveStreamContext.js.map +1 -1
  11. package/lib/features/agent-chat/NativeAgentChat.js +2 -0
  12. package/lib/features/agent-chat/NativeAgentChat.js.map +1 -1
  13. package/lib/features/apps/AppsCatalog.js +2 -2
  14. package/lib/features/apps/AppsCatalog.js.map +1 -1
  15. package/lib/features/audio-input/MicErrorBoundary.js +2 -2
  16. package/lib/features/audio-input/MicErrorBoundary.js.map +1 -1
  17. package/lib/features/canvas/AudioEditorExperience.js +308 -0
  18. package/lib/features/canvas/AudioEditorExperience.js.map +1 -0
  19. package/lib/features/canvas/CanvasAgentChatPane.js +310 -0
  20. package/lib/features/canvas/CanvasAgentChatPane.js.map +1 -0
  21. package/lib/features/canvas/CanvasBoardsGrid.js +414 -0
  22. package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -0
  23. package/lib/features/canvas/CanvasChatResultCard.js +113 -0
  24. package/lib/features/canvas/CanvasChatResultCard.js.map +1 -0
  25. package/lib/features/canvas/CanvasEditToolsPanel.js +179 -0
  26. package/lib/features/canvas/CanvasEditToolsPanel.js.map +1 -0
  27. package/lib/features/canvas/CanvasExperience.js +859 -0
  28. package/lib/features/canvas/CanvasExperience.js.map +1 -0
  29. package/lib/features/canvas/CanvasGeneratePanel.js +514 -0
  30. package/lib/features/canvas/CanvasGeneratePanel.js.map +1 -0
  31. package/lib/features/canvas/CanvasLibrarySheet.js +355 -0
  32. package/lib/features/canvas/CanvasLibrarySheet.js.map +1 -0
  33. package/lib/features/canvas/CanvasLooksPanel.js +184 -0
  34. package/lib/features/canvas/CanvasLooksPanel.js.map +1 -0
  35. package/lib/features/canvas/CanvasTasksPanel.js +138 -0
  36. package/lib/features/canvas/CanvasTasksPanel.js.map +1 -0
  37. package/lib/features/canvas/CanvasTemplatesPanel.js +226 -0
  38. package/lib/features/canvas/CanvasTemplatesPanel.js.map +1 -0
  39. package/lib/features/canvas/CanvasToolDock.js +423 -0
  40. package/lib/features/canvas/CanvasToolDock.js.map +1 -0
  41. package/lib/features/canvas/FrameExtractorExperience.js +242 -0
  42. package/lib/features/canvas/FrameExtractorExperience.js.map +1 -0
  43. package/lib/features/canvas/ImageEditorExperience.js +491 -0
  44. package/lib/features/canvas/ImageEditorExperience.js.map +1 -0
  45. package/lib/features/canvas/InfluencerStudioExperience.js +288 -0
  46. package/lib/features/canvas/InfluencerStudioExperience.js.map +1 -0
  47. package/lib/features/canvas/MoodboardExperience.js +205 -0
  48. package/lib/features/canvas/MoodboardExperience.js.map +1 -0
  49. package/lib/features/canvas/NativeCanvasViewer.js +929 -0
  50. package/lib/features/canvas/NativeCanvasViewer.js.map +1 -0
  51. package/lib/features/canvas/PromoContextFields.js +150 -0
  52. package/lib/features/canvas/PromoContextFields.js.map +1 -0
  53. package/lib/features/canvas/SetStudioExperience.js +323 -0
  54. package/lib/features/canvas/SetStudioExperience.js.map +1 -0
  55. package/lib/features/canvas/VideoClipsExperience.js +175 -0
  56. package/lib/features/canvas/VideoClipsExperience.js.map +1 -0
  57. package/lib/features/canvas/VideoEditExperience.js +824 -0
  58. package/lib/features/canvas/VideoEditExperience.js.map +1 -0
  59. package/lib/features/canvas/VideoEditorExperience.js +3050 -0
  60. package/lib/features/canvas/VideoEditorExperience.js.map +1 -0
  61. package/lib/features/canvas/VideoGeneratorExperience.js +415 -0
  62. package/lib/features/canvas/VideoGeneratorExperience.js.map +1 -0
  63. package/lib/features/canvas/aiEdit.js +53 -0
  64. package/lib/features/canvas/aiEdit.js.map +1 -0
  65. package/lib/features/canvas/canvasAgentChat.js +76 -0
  66. package/lib/features/canvas/canvasAgentChat.js.map +1 -0
  67. package/lib/features/canvas/canvasBoardsCatalog.js +59 -0
  68. package/lib/features/canvas/canvasBoardsCatalog.js.map +1 -0
  69. package/lib/features/canvas/canvasBoardsSnapshot.js +14 -1
  70. package/lib/features/canvas/canvasBoardsSnapshot.js.map +1 -1
  71. package/lib/features/canvas/canvasChatDisplay.js +38 -0
  72. package/lib/features/canvas/canvasChatDisplay.js.map +1 -0
  73. package/lib/features/canvas/canvasChatTemplates.js +219 -0
  74. package/lib/features/canvas/canvasChatTemplates.js.map +1 -0
  75. package/lib/features/canvas/canvasCore.js +138 -1
  76. package/lib/features/canvas/canvasCore.js.map +1 -1
  77. package/lib/features/canvas/canvasEditOps.js +224 -0
  78. package/lib/features/canvas/canvasEditOps.js.map +1 -0
  79. package/lib/features/canvas/canvasTasks.js +187 -0
  80. package/lib/features/canvas/canvasTasks.js.map +1 -0
  81. package/lib/features/canvas/designPromptTemplates.js +3084 -0
  82. package/lib/features/canvas/designPromptTemplates.js.map +1 -0
  83. package/lib/features/canvas/editTools.js +54 -0
  84. package/lib/features/canvas/editTools.js.map +1 -0
  85. package/lib/features/canvas/extendVideo.js +5 -0
  86. package/lib/features/canvas/extendVideo.js.map +1 -0
  87. package/lib/features/canvas/frameExtract.js +33 -0
  88. package/lib/features/canvas/frameExtract.js.map +1 -0
  89. package/lib/features/canvas/generationModels.js +201 -0
  90. package/lib/features/canvas/generationModels.js.map +1 -0
  91. package/lib/features/canvas/influencer/influencerPipeline.js +170 -0
  92. package/lib/features/canvas/influencer/influencerPipeline.js.map +1 -0
  93. package/lib/features/canvas/influencer/productReel.js +72 -0
  94. package/lib/features/canvas/influencer/productReel.js.map +1 -0
  95. package/lib/features/canvas/influencer/reelPlan.js +159 -0
  96. package/lib/features/canvas/influencer/reelPlan.js.map +1 -0
  97. package/lib/features/canvas/moodboardCore.js +13 -0
  98. package/lib/features/canvas/moodboardCore.js.map +1 -0
  99. package/lib/features/canvas/promoProjectImport.js +99 -0
  100. package/lib/features/canvas/promoProjectImport.js.map +1 -0
  101. package/lib/features/canvas/promoVideo.js +312 -0
  102. package/lib/features/canvas/promoVideo.js.map +1 -0
  103. package/lib/features/canvas/recorder/CameraRecorderExperience.js +109 -0
  104. package/lib/features/canvas/recorder/CameraRecorderExperience.js.map +1 -0
  105. package/lib/features/canvas/sessionIdentity.js +28 -1
  106. package/lib/features/canvas/sessionIdentity.js.map +1 -1
  107. package/lib/features/canvas/set/SetViewportWebView.js +133 -0
  108. package/lib/features/canvas/set/SetViewportWebView.js.map +1 -0
  109. package/lib/features/canvas/set/cameraPath.js +194 -0
  110. package/lib/features/canvas/set/cameraPath.js.map +1 -0
  111. package/lib/features/canvas/set/setProject.js +24 -0
  112. package/lib/features/canvas/set/setProject.js.map +1 -0
  113. package/lib/features/canvas/storageLibrary.js +184 -0
  114. package/lib/features/canvas/storageLibrary.js.map +1 -0
  115. package/lib/features/canvas/studioCatalog.js +129 -0
  116. package/lib/features/canvas/studioCatalog.js.map +1 -0
  117. package/lib/features/canvas/studioLooks.js +189 -0
  118. package/lib/features/canvas/studioLooks.js.map +1 -0
  119. package/lib/features/canvas/surfaceIndex.js +63 -1
  120. package/lib/features/canvas/surfaceIndex.js.map +1 -1
  121. package/lib/features/canvas/templateImport/invideoNative.js +221 -0
  122. package/lib/features/canvas/templateImport/invideoNative.js.map +1 -0
  123. package/lib/features/canvas/templateImport/loadTemplate.js +43 -0
  124. package/lib/features/canvas/templateImport/loadTemplate.js.map +1 -0
  125. package/lib/features/canvas/templateImport/renderConfig.js +93 -0
  126. package/lib/features/canvas/templateImport/renderConfig.js.map +1 -0
  127. package/lib/features/canvas/useStudioCatalogTemplates.js +134 -0
  128. package/lib/features/canvas/useStudioCatalogTemplates.js.map +1 -0
  129. package/lib/features/canvas/video3d.js +109 -0
  130. package/lib/features/canvas/video3d.js.map +1 -0
  131. package/lib/features/canvas/videoClips.js +42 -0
  132. package/lib/features/canvas/videoClips.js.map +1 -0
  133. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js +120 -0
  134. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js.map +1 -0
  135. package/lib/features/canvas/videoEditor/agent/agentLoop.js +69 -0
  136. package/lib/features/canvas/videoEditor/agent/agentLoop.js.map +1 -0
  137. package/lib/features/canvas/videoEditor/agent/brainClient.js +45 -0
  138. package/lib/features/canvas/videoEditor/agent/brainClient.js.map +1 -0
  139. package/lib/features/canvas/videoEditor/agent/cutTools.js +129 -0
  140. package/lib/features/canvas/videoEditor/agent/cutTools.js.map +1 -0
  141. package/lib/features/canvas/videoEditor/editorModel.js +346 -0
  142. package/lib/features/canvas/videoEditor/editorModel.js.map +1 -0
  143. package/lib/features/canvas/videoEditor/exportRenderer.js +214 -0
  144. package/lib/features/canvas/videoEditor/exportRenderer.js.map +1 -0
  145. package/lib/features/canvas/videoEditor/filters.js +41 -0
  146. package/lib/features/canvas/videoEditor/filters.js.map +1 -0
  147. package/lib/features/canvas/videoEditor/mediaActions.js +57 -0
  148. package/lib/features/canvas/videoEditor/mediaActions.js.map +1 -0
  149. package/lib/features/canvas/videoEditor/remoteMediaClient.js +129 -0
  150. package/lib/features/canvas/videoEditor/remoteMediaClient.js.map +1 -0
  151. package/lib/features/canvas/videoEditor/solidColorPng.js +115 -0
  152. package/lib/features/canvas/videoEditor/solidColorPng.js.map +1 -0
  153. package/lib/features/canvas/videoEditor/videoEditOps.js +191 -0
  154. package/lib/features/canvas/videoEditor/videoEditOps.js.map +1 -0
  155. package/lib/features/canvas/videoEditor/videoProjectsStore.js +82 -0
  156. package/lib/features/canvas/videoEditor/videoProjectsStore.js.map +1 -0
  157. package/lib/features/canvas/videoRenderer.js +8 -0
  158. package/lib/features/canvas/videoRenderer.js.map +1 -0
  159. package/lib/features/canvas/withRemoteSafeArea.js +2 -2
  160. package/lib/features/canvas/withRemoteSafeArea.js.map +1 -1
  161. package/lib/features/characters/characterStudioProps.js +14 -0
  162. package/lib/features/characters/characterStudioProps.js.map +1 -0
  163. package/lib/features/chat/ChatCodeBlock.js +7 -3
  164. package/lib/features/chat/ChatCodeBlock.js.map +1 -1
  165. package/lib/features/chat/ChatTranscript.js +7 -3
  166. package/lib/features/chat/ChatTranscript.js.map +1 -1
  167. package/lib/features/chat/ChatWidgetCard.js +13 -0
  168. package/lib/features/chat/ChatWidgetCard.js.map +1 -0
  169. package/lib/features/chat/ConnectorConnectCard.js +166 -0
  170. package/lib/features/chat/ConnectorConnectCard.js.map +1 -0
  171. package/lib/features/chat/ConnectorConnectPrompt.js +272 -0
  172. package/lib/features/chat/ConnectorConnectPrompt.js.map +1 -0
  173. package/lib/features/chat/MessageActionBar.js.map +1 -1
  174. package/lib/features/chat/QueuedFollowUps.js +71 -0
  175. package/lib/features/chat/QueuedFollowUps.js.map +1 -0
  176. package/lib/features/chat/chatWidgets.js +37 -0
  177. package/lib/features/chat/chatWidgets.js.map +1 -0
  178. package/lib/features/chat/connectorConnect.js +207 -0
  179. package/lib/features/chat/connectorConnect.js.map +1 -0
  180. package/lib/features/chat/connectorConnectHandbacks.js +55 -0
  181. package/lib/features/chat/connectorConnectHandbacks.js.map +1 -0
  182. package/lib/features/design/DesignEditorExperience.js +643 -0
  183. package/lib/features/design/DesignEditorExperience.js.map +1 -0
  184. package/lib/features/design/DesignExperience.js +444 -0
  185. package/lib/features/design/DesignExperience.js.map +1 -0
  186. package/lib/features/design/designCore.js +298 -0
  187. package/lib/features/design/designCore.js.map +1 -0
  188. package/lib/features/design/designIndex.js +150 -0
  189. package/lib/features/design/designIndex.js.map +1 -0
  190. package/lib/features/design/exportDesign.js +133 -0
  191. package/lib/features/design/exportDesign.js.map +1 -0
  192. package/lib/features/job-search/ApplicationsPanel.js +907 -0
  193. package/lib/features/job-search/ApplicationsPanel.js.map +1 -0
  194. package/lib/features/job-search/ContactsPanel.js +627 -0
  195. package/lib/features/job-search/ContactsPanel.js.map +1 -0
  196. package/lib/features/job-search/InsightsPanel.js +299 -0
  197. package/lib/features/job-search/InsightsPanel.js.map +1 -0
  198. package/lib/features/job-search/InterviewPanel.js +637 -0
  199. package/lib/features/job-search/InterviewPanel.js.map +1 -0
  200. package/lib/features/job-search/JdPastePrompt.js +130 -0
  201. package/lib/features/job-search/JdPastePrompt.js.map +1 -0
  202. package/lib/features/job-search/JobCard.js +199 -0
  203. package/lib/features/job-search/JobCard.js.map +1 -0
  204. package/lib/features/job-search/JobDetailSheet.js +255 -0
  205. package/lib/features/job-search/JobDetailSheet.js.map +1 -0
  206. package/lib/features/job-search/JobSearchAgentChatPane.js +377 -0
  207. package/lib/features/job-search/JobSearchAgentChatPane.js.map +1 -0
  208. package/lib/features/job-search/JobSearchExperience.js +1324 -0
  209. package/lib/features/job-search/JobSearchExperience.js.map +1 -0
  210. package/lib/features/job-search/JobSearchLocationField.js +231 -0
  211. package/lib/features/job-search/JobSearchLocationField.js.map +1 -0
  212. package/lib/features/job-search/ProfilePanel.js +679 -0
  213. package/lib/features/job-search/ProfilePanel.js.map +1 -0
  214. package/lib/features/job-search/RepliesPanel.js +344 -0
  215. package/lib/features/job-search/RepliesPanel.js.map +1 -0
  216. package/lib/features/job-search/SavedPanel.js +297 -0
  217. package/lib/features/job-search/SavedPanel.js.map +1 -0
  218. package/lib/features/job-search/chat/widgetContent.js +29 -0
  219. package/lib/features/job-search/chat/widgetContent.js.map +1 -0
  220. package/lib/features/job-search/cvText.js +91 -0
  221. package/lib/features/job-search/cvText.js.map +1 -0
  222. package/lib/features/job-search/jobAgentSwipe.js +7 -0
  223. package/lib/features/job-search/jobAgentSwipe.js.map +1 -0
  224. package/lib/features/job-search/jobSearchClient.js +184 -0
  225. package/lib/features/job-search/jobSearchClient.js.map +1 -0
  226. package/lib/features/job-search/jobSearchExec.js +14 -0
  227. package/lib/features/job-search/jobSearchExec.js.map +1 -0
  228. package/lib/features/job-search/jobSearchRuntime.js +50 -0
  229. package/lib/features/job-search/jobSearchRuntime.js.map +1 -0
  230. package/lib/features/job-search/jobSearchTheme.js +44 -0
  231. package/lib/features/job-search/jobSearchTheme.js.map +1 -0
  232. package/lib/features/job-search/savedJobs.js +85 -0
  233. package/lib/features/job-search/savedJobs.js.map +1 -0
  234. package/lib/features/job-search/searchHistory.js +117 -0
  235. package/lib/features/job-search/searchHistory.js.map +1 -0
  236. package/lib/features/job-search/types.js +36 -0
  237. package/lib/features/job-search/types.js.map +1 -0
  238. package/lib/features/job-search/useJobSearchSession.js +558 -0
  239. package/lib/features/job-search/useJobSearchSession.js.map +1 -0
  240. package/lib/features/messaging/ChatComponents.js +529 -0
  241. package/lib/features/messaging/ChatComponents.js.map +1 -0
  242. package/lib/features/messaging/ChatInviteDeepLink.js +116 -0
  243. package/lib/features/messaging/ChatInviteDeepLink.js.map +1 -0
  244. package/lib/features/messaging/ContactsScreen.js +288 -0
  245. package/lib/features/messaging/ContactsScreen.js.map +1 -0
  246. package/lib/features/messaging/ConversationListScreen.js +147 -0
  247. package/lib/features/messaging/ConversationListScreen.js.map +1 -0
  248. package/lib/features/messaging/MessageActions.js +290 -0
  249. package/lib/features/messaging/MessageActions.js.map +1 -0
  250. package/lib/features/messaging/NativeChatExperience.js +189 -0
  251. package/lib/features/messaging/NativeChatExperience.js.map +1 -0
  252. package/lib/features/messaging/RegistrationScreen.js +11 -14
  253. package/lib/features/messaging/RegistrationScreen.js.map +1 -1
  254. package/lib/features/messaging/ThreadScreen.js +215 -0
  255. package/lib/features/messaging/ThreadScreen.js.map +1 -0
  256. package/lib/features/messaging/chatInviteLink.js +52 -0
  257. package/lib/features/messaging/chatInviteLink.js.map +1 -0
  258. package/lib/features/messaging/chatModel.js +278 -0
  259. package/lib/features/messaging/chatModel.js.map +1 -0
  260. package/lib/features/messaging/chatOperations.js +106 -1
  261. package/lib/features/messaging/chatOperations.js.map +1 -1
  262. package/lib/features/messaging/emojiCatalog.js +60 -0
  263. package/lib/features/messaging/emojiCatalog.js.map +1 -0
  264. package/lib/features/messaging/emojiKeywords.js +1592 -0
  265. package/lib/features/messaging/emojiKeywords.js.map +1 -0
  266. package/lib/features/messaging/nativeChatChannelQuery.js +27 -0
  267. package/lib/features/messaging/nativeChatChannelQuery.js.map +1 -0
  268. package/lib/features/messaging/phoneNumbers.js +52 -1
  269. package/lib/features/messaging/phoneNumbers.js.map +1 -1
  270. package/lib/features/messaging/sha256.js +68 -0
  271. package/lib/features/messaging/sha256.js.map +1 -0
  272. package/lib/features/messaging/useChatData.js +421 -0
  273. package/lib/features/messaging/useChatData.js.map +1 -0
  274. package/lib/features/messaging/useContactMatches.js +191 -0
  275. package/lib/features/messaging/useContactMatches.js.map +1 -0
  276. package/lib/features/messaging/usePhoneVerification.js +12 -12
  277. package/lib/features/messaging/usePhoneVerification.js.map +1 -1
  278. package/lib/features/messaging/yantraChatOrg.js +8 -3
  279. package/lib/features/messaging/yantraChatOrg.js.map +1 -1
  280. package/lib/features/resume/AnnotateModal.js +100 -0
  281. package/lib/features/resume/AnnotateModal.js.map +1 -0
  282. package/lib/features/resume/AnnotationBar.js +69 -0
  283. package/lib/features/resume/AnnotationBar.js.map +1 -0
  284. package/lib/features/resume/ExportSheet.js +105 -0
  285. package/lib/features/resume/ExportSheet.js.map +1 -0
  286. package/lib/features/resume/ResumeAgentChatPane.js +95 -0
  287. package/lib/features/resume/ResumeAgentChatPane.js.map +1 -0
  288. package/lib/features/resume/ResumeEditor.js +676 -0
  289. package/lib/features/resume/ResumeEditor.js.map +1 -0
  290. package/lib/features/resume/ResumeExperience.js +235 -0
  291. package/lib/features/resume/ResumeExperience.js.map +1 -0
  292. package/lib/features/resume/ResumeListPanel.js +262 -0
  293. package/lib/features/resume/ResumeListPanel.js.map +1 -0
  294. package/lib/features/resume/ResumeToolbar.js +236 -0
  295. package/lib/features/resume/ResumeToolbar.js.map +1 -0
  296. package/lib/features/resume/annotations.js +17 -0
  297. package/lib/features/resume/annotations.js.map +1 -0
  298. package/lib/features/resume/documentCss.js +52 -0
  299. package/lib/features/resume/documentCss.js.map +1 -0
  300. package/lib/features/resume/draft.js +89 -0
  301. package/lib/features/resume/draft.js.map +1 -0
  302. package/lib/features/resume/exportResume.js +43 -0
  303. package/lib/features/resume/exportResume.js.map +1 -0
  304. package/lib/features/resume/pickResumePhoto.js +22 -0
  305. package/lib/features/resume/pickResumePhoto.js.map +1 -0
  306. package/lib/features/resume/renderResume.js +121 -0
  307. package/lib/features/resume/renderResume.js.map +1 -0
  308. package/lib/features/resume/resumeClient.js +69 -0
  309. package/lib/features/resume/resumeClient.js.map +1 -0
  310. package/lib/features/resume/resumeExec.js +14 -0
  311. package/lib/features/resume/resumeExec.js.map +1 -0
  312. package/lib/features/resume/resumeIndex.js +244 -0
  313. package/lib/features/resume/resumeIndex.js.map +1 -0
  314. package/lib/features/resume/resumeRuntime.js +50 -0
  315. package/lib/features/resume/resumeRuntime.js.map +1 -0
  316. package/lib/features/resume/resumeTheme.js +34 -0
  317. package/lib/features/resume/resumeTheme.js.map +1 -0
  318. package/lib/features/resume/resumeToolbox.js +49 -0
  319. package/lib/features/resume/resumeToolbox.js.map +1 -0
  320. package/lib/features/resume/templates.js +90 -0
  321. package/lib/features/resume/templates.js.map +1 -0
  322. package/lib/features/resume/types.js +10 -0
  323. package/lib/features/resume/types.js.map +1 -0
  324. package/lib/features/resume/useResumeSession.js +183 -0
  325. package/lib/features/resume/useResumeSession.js.map +1 -0
  326. package/lib/features/shopping/DealsPanel.js +254 -0
  327. package/lib/features/shopping/DealsPanel.js.map +1 -0
  328. package/lib/features/shopping/HistoryPanel.js +147 -0
  329. package/lib/features/shopping/HistoryPanel.js.map +1 -0
  330. package/lib/features/shopping/OrdersPanel.js +157 -0
  331. package/lib/features/shopping/OrdersPanel.js.map +1 -0
  332. package/lib/features/shopping/ProductCard.js +326 -0
  333. package/lib/features/shopping/ProductCard.js.map +1 -0
  334. package/lib/features/shopping/ProductDetailSheet.js +313 -0
  335. package/lib/features/shopping/ProductDetailSheet.js.map +1 -0
  336. package/lib/features/shopping/ProductFilterBar.js +153 -0
  337. package/lib/features/shopping/ProductFilterBar.js.map +1 -0
  338. package/lib/features/shopping/ProductPhoto.js +27 -0
  339. package/lib/features/shopping/ProductPhoto.js.map +1 -0
  340. package/lib/features/shopping/SavedPanel.js +139 -0
  341. package/lib/features/shopping/SavedPanel.js.map +1 -0
  342. package/lib/features/shopping/ShoppingAgentChatPane.js +436 -0
  343. package/lib/features/shopping/ShoppingAgentChatPane.js.map +1 -0
  344. package/lib/features/shopping/ShoppingExperience.js +888 -0
  345. package/lib/features/shopping/ShoppingExperience.js.map +1 -0
  346. package/lib/features/shopping/TrendingSections.js +199 -0
  347. package/lib/features/shopping/TrendingSections.js.map +1 -0
  348. package/lib/features/shopping/WatchlistPanel.js +148 -0
  349. package/lib/features/shopping/WatchlistPanel.js.map +1 -0
  350. package/lib/features/shopping/catalog.js +238 -0
  351. package/lib/features/shopping/catalog.js.map +1 -0
  352. package/lib/features/shopping/chat/ShoppingChatResultCard.js +175 -0
  353. package/lib/features/shopping/chat/ShoppingChatResultCard.js.map +1 -0
  354. package/lib/features/shopping/chat/streamAssistantReply.js +34 -0
  355. package/lib/features/shopping/chat/streamAssistantReply.js.map +1 -0
  356. package/lib/features/shopping/chat/widgetContent.js +233 -0
  357. package/lib/features/shopping/chat/widgetContent.js.map +1 -0
  358. package/lib/features/shopping/hooks/useTrendingProducts.js +162 -0
  359. package/lib/features/shopping/hooks/useTrendingProducts.js.map +1 -0
  360. package/lib/features/shopping/productImage.js +42 -0
  361. package/lib/features/shopping/productImage.js.map +1 -0
  362. package/lib/features/shopping/savedProducts.js +84 -0
  363. package/lib/features/shopping/savedProducts.js.map +1 -0
  364. package/lib/features/shopping/services/catalogActions.js +166 -0
  365. package/lib/features/shopping/services/catalogActions.js.map +1 -0
  366. package/lib/features/shopping/services/parsePriceCheckIntent.js +58 -0
  367. package/lib/features/shopping/services/parsePriceCheckIntent.js.map +1 -0
  368. package/lib/features/shopping/services/parseShoppingIntent.js +67 -0
  369. package/lib/features/shopping/services/parseShoppingIntent.js.map +1 -0
  370. package/lib/features/shopping/services/productAvailability.js +25 -0
  371. package/lib/features/shopping/services/productAvailability.js.map +1 -0
  372. package/lib/features/shopping/services/productFilters.js +72 -0
  373. package/lib/features/shopping/services/productFilters.js.map +1 -0
  374. package/lib/features/shopping/services/retailerUrl.js +75 -0
  375. package/lib/features/shopping/services/retailerUrl.js.map +1 -0
  376. package/lib/features/shopping/services/shoppingChatReply.js +46 -0
  377. package/lib/features/shopping/services/shoppingChatReply.js.map +1 -0
  378. package/lib/features/shopping/services/shoppingProductSearch.js +336 -0
  379. package/lib/features/shopping/services/shoppingProductSearch.js.map +1 -0
  380. package/lib/features/shopping/services/shoppingSearchConnectorClient.js +41 -0
  381. package/lib/features/shopping/services/shoppingSearchConnectorClient.js.map +1 -0
  382. package/lib/features/shopping/shopAgentSwipe.js +7 -0
  383. package/lib/features/shopping/shopAgentSwipe.js.map +1 -0
  384. package/lib/features/shopping/shoppingCart.js +116 -0
  385. package/lib/features/shopping/shoppingCart.js.map +1 -0
  386. package/lib/features/shopping/shoppingExec.js +14 -0
  387. package/lib/features/shopping/shoppingExec.js.map +1 -0
  388. package/lib/features/shopping/shoppingHistoryStore.js +176 -0
  389. package/lib/features/shopping/shoppingHistoryStore.js.map +1 -0
  390. package/lib/features/shopping/shoppingRuntime.js +63 -0
  391. package/lib/features/shopping/shoppingRuntime.js.map +1 -0
  392. package/lib/features/shopping/timeAgo.js +14 -0
  393. package/lib/features/shopping/timeAgo.js.map +1 -0
  394. package/lib/features/shopping/useShoppingSearch.js +262 -0
  395. package/lib/features/shopping/useShoppingSearch.js.map +1 -0
  396. package/lib/features/travel/BookHeaderGlow.js +48 -0
  397. package/lib/features/travel/BookHeaderGlow.js.map +1 -0
  398. package/lib/features/travel/BookingsPanel.js +29 -0
  399. package/lib/features/travel/BookingsPanel.js.map +1 -0
  400. package/lib/features/travel/DiscoverPanel.js +155 -0
  401. package/lib/features/travel/DiscoverPanel.js.map +1 -0
  402. package/lib/features/travel/FlightCompareBar.js +86 -0
  403. package/lib/features/travel/FlightCompareBar.js.map +1 -0
  404. package/lib/features/travel/FlightDealsBoard.js +100 -0
  405. package/lib/features/travel/FlightDealsBoard.js.map +1 -0
  406. package/lib/features/travel/HistoryPanel.js +82 -0
  407. package/lib/features/travel/HistoryPanel.js.map +1 -0
  408. package/lib/features/travel/PopularDestinations.js +144 -0
  409. package/lib/features/travel/PopularDestinations.js.map +1 -0
  410. package/lib/features/travel/SavedPanel.js +27 -0
  411. package/lib/features/travel/SavedPanel.js.map +1 -0
  412. package/lib/features/travel/TravelAgentChatPane.js +303 -0
  413. package/lib/features/travel/TravelAgentChatPane.js.map +1 -0
  414. package/lib/features/travel/TravelBookHero.js +425 -0
  415. package/lib/features/travel/TravelBookHero.js.map +1 -0
  416. package/lib/features/travel/TravelDatesField.js +234 -0
  417. package/lib/features/travel/TravelDatesField.js.map +1 -0
  418. package/lib/features/travel/TravelDetailSheet.js +106 -0
  419. package/lib/features/travel/TravelDetailSheet.js.map +1 -0
  420. package/lib/features/travel/TravelExperience.js +624 -0
  421. package/lib/features/travel/TravelExperience.js.map +1 -0
  422. package/lib/features/travel/TravelGuestsField.js +85 -0
  423. package/lib/features/travel/TravelGuestsField.js.map +1 -0
  424. package/lib/features/travel/TravelLanding.js +318 -0
  425. package/lib/features/travel/TravelLanding.js.map +1 -0
  426. package/lib/features/travel/TravelLocationField.js +179 -0
  427. package/lib/features/travel/TravelLocationField.js.map +1 -0
  428. package/lib/features/travel/TravelPropertyCard.js +266 -0
  429. package/lib/features/travel/TravelPropertyCard.js.map +1 -0
  430. package/lib/features/travel/TravelPropertyPhoto.js +22 -0
  431. package/lib/features/travel/TravelPropertyPhoto.js.map +1 -0
  432. package/lib/features/travel/TravelRailFlyout.js +79 -0
  433. package/lib/features/travel/TravelRailFlyout.js.map +1 -0
  434. package/lib/features/travel/TravelResultsMap.js +126 -0
  435. package/lib/features/travel/TravelResultsMap.js.map +1 -0
  436. package/lib/features/travel/WorkspacePanel.js +148 -0
  437. package/lib/features/travel/WorkspacePanel.js.map +1 -0
  438. package/lib/features/travel/appNav.js +244 -0
  439. package/lib/features/travel/appNav.js.map +1 -0
  440. package/lib/features/travel/calendarDays.js +50 -0
  441. package/lib/features/travel/calendarDays.js.map +1 -0
  442. package/lib/features/travel/catalog.js +72 -0
  443. package/lib/features/travel/catalog.js.map +1 -0
  444. package/lib/features/travel/chat/TravelChatResultCard.js +107 -0
  445. package/lib/features/travel/chat/TravelChatResultCard.js.map +1 -0
  446. package/lib/features/travel/chat/widgetContent.js +107 -0
  447. package/lib/features/travel/chat/widgetContent.js.map +1 -0
  448. package/lib/features/travel/flightDeals.js +65 -0
  449. package/lib/features/travel/flightDeals.js.map +1 -0
  450. package/lib/features/travel/mapCoordinates.js +36 -0
  451. package/lib/features/travel/mapCoordinates.js.map +1 -0
  452. package/lib/features/travel/parseTravelIntent.js +303 -0
  453. package/lib/features/travel/parseTravelIntent.js.map +1 -0
  454. package/lib/features/travel/savedStays.js +66 -0
  455. package/lib/features/travel/savedStays.js.map +1 -0
  456. package/lib/features/travel/services/flightDealsBoard.js +111 -0
  457. package/lib/features/travel/services/flightDealsBoard.js.map +1 -0
  458. package/lib/features/travel/services/flightSearchConnectorClient.js +42 -0
  459. package/lib/features/travel/services/flightSearchConnectorClient.js.map +1 -0
  460. package/lib/features/travel/services/geocodeLocation.js +79 -0
  461. package/lib/features/travel/services/geocodeLocation.js.map +1 -0
  462. package/lib/features/travel/services/placePredictions.js +113 -0
  463. package/lib/features/travel/services/placePredictions.js.map +1 -0
  464. package/lib/features/travel/services/resolveOriginCity.js +27 -0
  465. package/lib/features/travel/services/resolveOriginCity.js.map +1 -0
  466. package/lib/features/travel/services/resortifiConnectorClient.js +76 -0
  467. package/lib/features/travel/services/resortifiConnectorClient.js.map +1 -0
  468. package/lib/features/travel/services/travelFlightSearch.js +289 -0
  469. package/lib/features/travel/services/travelFlightSearch.js.map +1 -0
  470. package/lib/features/travel/services/travelPropertySearch.js +377 -0
  471. package/lib/features/travel/services/travelPropertySearch.js.map +1 -0
  472. package/lib/features/travel/travelAgentSwipe.js +7 -0
  473. package/lib/features/travel/travelAgentSwipe.js.map +1 -0
  474. package/lib/features/travel/travelExec.js +14 -0
  475. package/lib/features/travel/travelExec.js.map +1 -0
  476. package/lib/features/travel/travelHistoryStore.js +108 -0
  477. package/lib/features/travel/travelHistoryStore.js.map +1 -0
  478. package/lib/features/travel/travelRuntime.js +62 -0
  479. package/lib/features/travel/travelRuntime.js.map +1 -0
  480. package/lib/features/travel/types.js +9 -0
  481. package/lib/features/travel/types.js.map +1 -0
  482. package/lib/features/travel/useTravelSearch.js +330 -0
  483. package/lib/features/travel/useTravelSearch.js.map +1 -0
  484. package/lib/features/travel/workspaceContent.js +548 -0
  485. package/lib/features/travel/workspaceContent.js.map +1 -0
  486. package/lib/hooks/useCdecliChannel.js +128 -6
  487. package/lib/hooks/useCdecliChannel.js.map +1 -1
  488. package/lib/hooks/useChatApi.js +4 -2
  489. package/lib/hooks/useChatApi.js.map +1 -1
  490. package/lib/hooks/useChatStream.js +77 -63
  491. package/lib/hooks/useChatStream.js.map +1 -1
  492. package/lib/hooks/useHostConnectorCard.js +24 -0
  493. package/lib/hooks/useHostConnectorCard.js.map +1 -0
  494. package/lib/hooks/useObtainSystemToken.js +23 -5
  495. package/lib/hooks/useObtainSystemToken.js.map +1 -1
  496. package/lib/hooks/webViewRetentionPolicy.js +1 -0
  497. package/lib/hooks/webViewRetentionPolicy.js.map +1 -1
  498. package/lib/index.js +1 -1
  499. package/lib/index.js.map +1 -1
  500. package/lib/screens/Chat/index.js +51 -22
  501. package/lib/screens/Chat/index.js.map +1 -1
  502. package/lib/screens/ChatNative/index.js +13 -2
  503. package/lib/screens/ChatNative/index.js.map +1 -1
  504. package/lib/screens/Home/HomeScreen.js +3 -3
  505. package/lib/screens/Home/HomeScreen.js.map +1 -1
  506. package/lib/screens/Home/components/ChatHistoryLanding.js +32 -32
  507. package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
  508. package/lib/screens/JobSearchNative/useJobSearchHostChat.js +12 -6
  509. package/lib/screens/JobSearchNative/useJobSearchHostChat.js.map +1 -1
  510. package/lib/screens/ResumeNative/useResumeHostChat.js +12 -6
  511. package/lib/screens/ResumeNative/useResumeHostChat.js.map +1 -1
  512. package/lib/screens/ShoppingNative/useShoppingHostChat.js +12 -6
  513. package/lib/screens/ShoppingNative/useShoppingHostChat.js.map +1 -1
  514. package/lib/screens/TravelNative/useTravelHostChat.js +12 -6
  515. package/lib/screens/TravelNative/useTravelHostChat.js.map +1 -1
  516. package/lib/screens/WebBuilder/WebViewWithNavigation.js +2 -2
  517. package/lib/screens/WebBuilder/WebViewWithNavigation.js.map +1 -1
  518. package/lib/services/brainQuickReply.js +38 -1
  519. package/lib/services/brainQuickReply.js.map +1 -1
  520. package/lib/state/chatThreadMerge.js +6 -1
  521. package/lib/state/chatThreadMerge.js.map +1 -1
  522. package/package.json +6 -4
@@ -1 +1 @@
1
- {"version":3,"file":"useShoppingHostChat.js","sources":["../../../src/screens/ShoppingNative/useShoppingHostChat.ts"],"sourcesContent":["/**\n * Host chat lane for native Shop Agent — same role as web `services.hostChat`.\n * Lives on the Shop screen (MF host), not in the shopping remote, so Apollo /\n * cdecli stay out of the federated bundle.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useRoute } from '@react-navigation/native';\nimport { v4 as uuidv4 } from 'uuid';\nimport { useCdecliConnection } from '../../contexts/CdecliConnectionContext';\nimport { useChatMutations } from '../../hooks/useChatApi';\nimport { useChatStream, type MessageAttachment, type UseChatStreamRouting } from '../../hooks/useChatStream';\nimport { usePrerequisiteIds } from '../../hooks/usePrerequisiteIds';\nimport type { AgentChatMessage } from '../../features/agent-chat';\nimport type { ShoppingHostChat } from '../../features/shopping/hostChat';\n\nconst TESTING_PROJECT_UUID = '9a8ac704-1040-4836-9b72-48b771ca91b1';\n\nexport function useShoppingHostChat(): ShoppingHostChat {\n const route = useRoute<any>();\n const routeOrg = typeof route?.params?.orgName === 'string' ? route.params.orgName.trim() : '';\n const { orgName, projectId } = usePrerequisiteIds();\n const effectiveOrg = routeOrg || orgName || '';\n const submitProjectId = projectId || TESTING_PROJECT_UUID;\n\n const [channelId] = useState(() => uuidv4());\n const createdRef = useRef(false);\n const { createChannel } = useChatMutations();\n\n const cdecli = useCdecliConnection();\n useEffect(() => {\n cdecli.setActiveChannelId(channelId);\n return undefined;\n }, [channelId, cdecli.setActiveChannelId]);\n\n useEffect(() => {\n if (createdRef.current || !effectiveOrg) return;\n createdRef.current = true;\n void createChannel({\n id: channelId,\n title: `chat-channel-${channelId}`,\n isShared: false,\n sharedSlug: null,\n isArchived: false,\n isPinned: false,\n model: null,\n systemPrompt: null,\n orgName: effectiveOrg,\n projectId: submitProjectId,\n } as never).catch((err) => {\n console.error('[ShoppingNative] createChannel failed:', err);\n });\n }, [channelId, createChannel, effectiveOrg, submitProjectId]);\n\n const persistenceMode = cdecli.persistenceMode ?? 'backend';\n const chatRouting: UseChatStreamRouting = useMemo(\n () => ({\n channelConnected: cdecli.channelConnected,\n accountId: cdecli.accountId,\n persistenceMode,\n recoverAgentAuth: cdecli.recoverAgentAuth,\n }),\n [cdecli.channelConnected, cdecli.accountId, cdecli.recoverAgentAuth, persistenceMode],\n );\n\n const chat = useChatStream(channelId, chatRouting);\n\n const messages: AgentChatMessage[] = useMemo(\n () =>\n chat.messages.map((m, index) => ({\n id: `${m.role}-${index}`,\n role: m.role,\n content: m.content,\n attachments: m.attachments,\n })),\n [chat.messages],\n );\n\n const send = useCallback(\n (text: string, attachments?: MessageAttachment[]) => {\n void chat.sendMessage(text, attachments, channelId);\n },\n [chat, channelId],\n );\n\n return useMemo(\n () => ({\n messages,\n streaming: chat.response || null,\n busy: chat.isLoading || chat.isStreaming,\n error: chat.error,\n connected: cdecli.channelConnected,\n send,\n clear: chat.clearMessages,\n }),\n [\n messages,\n chat.response,\n chat.isLoading,\n chat.isStreaming,\n chat.error,\n cdecli.channelConnected,\n send,\n chat.clearMessages,\n ],\n );\n}\n"],"names":["uuidv4"],"mappings":"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"}
1
+ {"version":3,"file":"useShoppingHostChat.js","sources":["../../../src/screens/ShoppingNative/useShoppingHostChat.ts"],"sourcesContent":["/**\n * Host chat lane for native Shop Agent — same role as web `services.hostChat`.\n * Lives on the Shop screen (MF host), not in the shopping remote, so Apollo /\n * cdecli stay out of the federated bundle.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useRoute } from '@react-navigation/native';\nimport { v4 as uuidv4 } from 'uuid';\nimport { useCdecliConnection } from '../../contexts/CdecliConnectionContext';\nimport { useChatMutations } from '../../hooks/useChatApi';\nimport { useChatStream, type MessageAttachment, type UseChatStreamRouting } from '../../hooks/useChatStream';\nimport { usePrerequisiteIds } from '../../hooks/usePrerequisiteIds';\nimport { useHostConnectorCard } from '../../hooks/useHostConnectorCard';\nimport type { AgentChatMessage } from '../../features/agent-chat';\nimport type { ShoppingHostChat } from '../../features/shopping/hostChat';\n\nconst TESTING_PROJECT_UUID = '9a8ac704-1040-4836-9b72-48b771ca91b1';\n\nexport function useShoppingHostChat(): ShoppingHostChat {\n const route = useRoute<any>();\n const routeOrg = typeof route?.params?.orgName === 'string' ? route.params.orgName.trim() : '';\n const { orgName, projectId } = usePrerequisiteIds();\n const effectiveOrg = routeOrg || orgName || '';\n const submitProjectId = projectId || TESTING_PROJECT_UUID;\n\n const [channelId] = useState(() => uuidv4());\n const createdRef = useRef(false);\n const { createChannel } = useChatMutations();\n\n const cdecli = useCdecliConnection();\n useEffect(() => {\n cdecli.setActiveChannelId(channelId);\n return undefined;\n }, [channelId, cdecli.setActiveChannelId]);\n\n useEffect(() => {\n if (createdRef.current || !effectiveOrg) return;\n createdRef.current = true;\n void createChannel({\n id: channelId,\n title: `chat-channel-${channelId}`,\n isShared: false,\n sharedSlug: null,\n isArchived: false,\n isPinned: false,\n model: null,\n systemPrompt: null,\n orgName: effectiveOrg,\n projectId: submitProjectId,\n } as never).catch((err) => {\n console.error('[ShoppingNative] createChannel failed:', err);\n });\n }, [channelId, createChannel, effectiveOrg, submitProjectId]);\n\n const persistenceMode = cdecli.persistenceMode ?? 'backend';\n const chatRouting: UseChatStreamRouting = useMemo(\n () => ({\n channelConnected: cdecli.channelConnected,\n accountId: cdecli.accountId,\n persistenceMode,\n recoverAgentAuth: cdecli.recoverAgentAuth,\n }),\n [cdecli.channelConnected, cdecli.accountId, cdecli.recoverAgentAuth, persistenceMode],\n );\n\n const chat = useChatStream(channelId, chatRouting);\n\n // A `[CONNECTOR_CONNECT]` request is answered by a card the host renders; the\n // remote gets the thread without the markers and the card's replies.\n const { displayMessages, displayStreaming, renderConnectorCard } = useHostConnectorCard(chat, channelId);\n\n const messages: AgentChatMessage[] = useMemo(\n () =>\n displayMessages(\n chat.messages.map((m, index) => ({\n id: `${m.role}-${index}`,\n role: m.role,\n content: m.content,\n attachments: m.attachments,\n })),\n ),\n [chat.messages, displayMessages],\n );\n\n const send = useCallback(\n (text: string, attachments?: MessageAttachment[]) => {\n void chat.sendMessage(text, attachments, channelId);\n },\n [chat, channelId],\n );\n\n return useMemo(\n () => ({\n messages,\n streaming: displayStreaming(chat.response),\n busy: chat.isLoading || chat.isStreaming,\n error: chat.error,\n connected: cdecli.channelConnected,\n send,\n clear: chat.clearMessages,\n renderConnectorCard,\n }),\n [\n messages,\n chat.response,\n displayStreaming,\n chat.isLoading,\n chat.isStreaming,\n chat.error,\n cdecli.channelConnected,\n send,\n chat.clearMessages,\n renderConnectorCard,\n ],\n );\n}\n"],"names":["uuidv4"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {useState,useRef,useEffect,useMemo,useCallback}from'react';import {useRoute}from'@react-navigation/native';import {v4}from'uuid';import {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {useChatMutations}from'../../hooks/useChatApi.js';import {useChatStream}from'../../hooks/useChatStream.js';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';const TESTING_PROJECT_UUID = "9a8ac704-1040-4836-9b72-48b771ca91b1";
1
+ import {useState,useRef,useEffect,useMemo,useCallback}from'react';import {useRoute}from'@react-navigation/native';import {v4}from'uuid';import {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {useChatMutations}from'../../hooks/useChatApi.js';import {useChatStream}from'../../hooks/useChatStream.js';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {useHostConnectorCard}from'../../hooks/useHostConnectorCard.js';const TESTING_PROJECT_UUID = "9a8ac704-1040-4836-9b72-48b771ca91b1";
2
2
  function useTravelHostChat() {
3
3
  var _a, _b;
4
4
  const route = useRoute();
@@ -45,22 +45,28 @@ function useTravelHostChat() {
45
45
  recoverAgentAuth: cdecli.recoverAgentAuth
46
46
  }), [cdecli.channelConnected, cdecli.accountId, cdecli.recoverAgentAuth, persistenceMode]);
47
47
  const chat = useChatStream(channelId, chatRouting);
48
- const messages = useMemo(() => chat.messages.map((m, index) => ({
48
+ const {
49
+ displayMessages,
50
+ displayStreaming,
51
+ renderConnectorCard
52
+ } = useHostConnectorCard(chat, channelId);
53
+ const messages = useMemo(() => displayMessages(chat.messages.map((m, index) => ({
49
54
  id: `${m.role}-${index}`,
50
55
  role: m.role,
51
56
  content: m.content,
52
57
  attachments: m.attachments
53
- })), [chat.messages]);
58
+ }))), [chat.messages, displayMessages]);
54
59
  const send = useCallback((text, attachments) => {
55
60
  void chat.sendMessage(text, attachments, channelId);
56
61
  }, [chat, channelId]);
57
62
  return useMemo(() => ({
58
63
  messages,
59
- streaming: chat.response || null,
64
+ streaming: displayStreaming(chat.response),
60
65
  busy: chat.isLoading || chat.isStreaming,
61
66
  error: chat.error,
62
67
  connected: cdecli.channelConnected,
63
68
  send,
64
- clear: chat.clearMessages
65
- }), [messages, chat.response, chat.isLoading, chat.isStreaming, chat.error, cdecli.channelConnected, send, chat.clearMessages]);
69
+ clear: chat.clearMessages,
70
+ renderConnectorCard
71
+ }), [messages, chat.response, displayStreaming, chat.isLoading, chat.isStreaming, chat.error, cdecli.channelConnected, send, chat.clearMessages, renderConnectorCard]);
66
72
  }export{useTravelHostChat};//# sourceMappingURL=useTravelHostChat.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useTravelHostChat.js","sources":["../../../src/screens/TravelNative/useTravelHostChat.ts"],"sourcesContent":["/**\n * Host chat lane for native Travel Agent — same role as web `services.hostChat`.\n * Lives on the Travel screen (MF host), not in the travel remote.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useRoute } from '@react-navigation/native';\nimport { v4 as uuidv4 } from 'uuid';\nimport { useCdecliConnection } from '../../contexts/CdecliConnectionContext';\nimport { useChatMutations } from '../../hooks/useChatApi';\nimport { useChatStream, type MessageAttachment, type UseChatStreamRouting } from '../../hooks/useChatStream';\nimport { usePrerequisiteIds } from '../../hooks/usePrerequisiteIds';\nimport type { AgentChatMessage } from '../../features/agent-chat';\nimport type { TravelHostChat } from '../../features/travel/hostChat';\n\nconst TESTING_PROJECT_UUID = '9a8ac704-1040-4836-9b72-48b771ca91b1';\n\nexport function useTravelHostChat(): TravelHostChat {\n const route = useRoute<any>();\n const routeOrg = typeof route?.params?.orgName === 'string' ? route.params.orgName.trim() : '';\n const { orgName, projectId } = usePrerequisiteIds();\n const effectiveOrg = routeOrg || orgName || '';\n const submitProjectId = projectId || TESTING_PROJECT_UUID;\n\n const [channelId] = useState(() => uuidv4());\n const createdRef = useRef(false);\n const { createChannel } = useChatMutations();\n\n const cdecli = useCdecliConnection();\n useEffect(() => {\n cdecli.setActiveChannelId(channelId);\n return undefined;\n }, [channelId, cdecli.setActiveChannelId]);\n\n useEffect(() => {\n if (createdRef.current || !effectiveOrg) return;\n createdRef.current = true;\n void createChannel({\n id: channelId,\n title: `chat-channel-${channelId}`,\n isShared: false,\n sharedSlug: null,\n isArchived: false,\n isPinned: false,\n model: null,\n systemPrompt: null,\n orgName: effectiveOrg,\n projectId: submitProjectId,\n } as never).catch((err) => {\n console.error('[TravelNative] createChannel failed:', err);\n });\n }, [channelId, createChannel, effectiveOrg, submitProjectId]);\n\n const persistenceMode = cdecli.persistenceMode ?? 'backend';\n const chatRouting: UseChatStreamRouting = useMemo(\n () => ({\n channelConnected: cdecli.channelConnected,\n accountId: cdecli.accountId,\n persistenceMode,\n recoverAgentAuth: cdecli.recoverAgentAuth,\n }),\n [cdecli.channelConnected, cdecli.accountId, cdecli.recoverAgentAuth, persistenceMode],\n );\n\n const chat = useChatStream(channelId, chatRouting);\n\n const messages: AgentChatMessage[] = useMemo(\n () =>\n chat.messages.map((m, index) => ({\n id: `${m.role}-${index}`,\n role: m.role,\n content: m.content,\n attachments: m.attachments,\n })),\n [chat.messages],\n );\n\n const send = useCallback(\n (text: string, attachments?: MessageAttachment[]) => {\n void chat.sendMessage(text, attachments, channelId);\n },\n [chat, channelId],\n );\n\n return useMemo(\n () => ({\n messages,\n streaming: chat.response || null,\n busy: chat.isLoading || chat.isStreaming,\n error: chat.error,\n connected: cdecli.channelConnected,\n send,\n clear: chat.clearMessages,\n }),\n [\n messages,\n chat.response,\n chat.isLoading,\n chat.isStreaming,\n chat.error,\n cdecli.channelConnected,\n send,\n chat.clearMessages,\n ],\n );\n}\n"],"names":["uuidv4"],"mappings":"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"}
1
+ {"version":3,"file":"useTravelHostChat.js","sources":["../../../src/screens/TravelNative/useTravelHostChat.ts"],"sourcesContent":["/**\n * Host chat lane for native Travel Agent — same role as web `services.hostChat`.\n * Lives on the Travel screen (MF host), not in the travel remote.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useRoute } from '@react-navigation/native';\nimport { v4 as uuidv4 } from 'uuid';\nimport { useCdecliConnection } from '../../contexts/CdecliConnectionContext';\nimport { useChatMutations } from '../../hooks/useChatApi';\nimport { useChatStream, type MessageAttachment, type UseChatStreamRouting } from '../../hooks/useChatStream';\nimport { usePrerequisiteIds } from '../../hooks/usePrerequisiteIds';\nimport { useHostConnectorCard } from '../../hooks/useHostConnectorCard';\nimport type { AgentChatMessage } from '../../features/agent-chat';\nimport type { TravelHostChat } from '../../features/travel/hostChat';\n\nconst TESTING_PROJECT_UUID = '9a8ac704-1040-4836-9b72-48b771ca91b1';\n\nexport function useTravelHostChat(): TravelHostChat {\n const route = useRoute<any>();\n const routeOrg = typeof route?.params?.orgName === 'string' ? route.params.orgName.trim() : '';\n const { orgName, projectId } = usePrerequisiteIds();\n const effectiveOrg = routeOrg || orgName || '';\n const submitProjectId = projectId || TESTING_PROJECT_UUID;\n\n const [channelId] = useState(() => uuidv4());\n const createdRef = useRef(false);\n const { createChannel } = useChatMutations();\n\n const cdecli = useCdecliConnection();\n useEffect(() => {\n cdecli.setActiveChannelId(channelId);\n return undefined;\n }, [channelId, cdecli.setActiveChannelId]);\n\n useEffect(() => {\n if (createdRef.current || !effectiveOrg) return;\n createdRef.current = true;\n void createChannel({\n id: channelId,\n title: `chat-channel-${channelId}`,\n isShared: false,\n sharedSlug: null,\n isArchived: false,\n isPinned: false,\n model: null,\n systemPrompt: null,\n orgName: effectiveOrg,\n projectId: submitProjectId,\n } as never).catch((err) => {\n console.error('[TravelNative] createChannel failed:', err);\n });\n }, [channelId, createChannel, effectiveOrg, submitProjectId]);\n\n const persistenceMode = cdecli.persistenceMode ?? 'backend';\n const chatRouting: UseChatStreamRouting = useMemo(\n () => ({\n channelConnected: cdecli.channelConnected,\n accountId: cdecli.accountId,\n persistenceMode,\n recoverAgentAuth: cdecli.recoverAgentAuth,\n }),\n [cdecli.channelConnected, cdecli.accountId, cdecli.recoverAgentAuth, persistenceMode],\n );\n\n const chat = useChatStream(channelId, chatRouting);\n\n // A `[CONNECTOR_CONNECT]` request is answered by a card the host renders; the\n // remote gets the thread without the markers and the card's replies.\n const { displayMessages, displayStreaming, renderConnectorCard } = useHostConnectorCard(chat, channelId);\n\n const messages: AgentChatMessage[] = useMemo(\n () =>\n displayMessages(\n chat.messages.map((m, index) => ({\n id: `${m.role}-${index}`,\n role: m.role,\n content: m.content,\n attachments: m.attachments,\n })),\n ),\n [chat.messages, displayMessages],\n );\n\n const send = useCallback(\n (text: string, attachments?: MessageAttachment[]) => {\n void chat.sendMessage(text, attachments, channelId);\n },\n [chat, channelId],\n );\n\n return useMemo(\n () => ({\n messages,\n streaming: displayStreaming(chat.response),\n busy: chat.isLoading || chat.isStreaming,\n error: chat.error,\n connected: cdecli.channelConnected,\n send,\n clear: chat.clearMessages,\n renderConnectorCard,\n }),\n [\n messages,\n chat.response,\n displayStreaming,\n chat.isLoading,\n chat.isStreaming,\n chat.error,\n cdecli.channelConnected,\n send,\n chat.clearMessages,\n renderConnectorCard,\n ],\n );\n}\n"],"names":["uuidv4"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import React from'react';import {BackHandler}from'react-native';import {useFocusEffect}from'@react-navigation/native';import {tryWebBuilderBack}from'./webbuilderBackHandler.js';function WebViewWithNavigation({
1
+ import React__default from'react';import {BackHandler}from'react-native';import {useFocusEffect}from'@react-navigation/native';import {tryWebBuilderBack}from'./webbuilderBackHandler.js';function WebViewWithNavigation({
2
2
  onGoBack
3
3
  }) {
4
- useFocusEffect(React.useCallback(() => {
4
+ useFocusEffect(React__default.useCallback(() => {
5
5
  const onBackPress = () => {
6
6
  if (tryWebBuilderBack()) {
7
7
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"WebViewWithNavigation.js","sources":["../../../src/screens/WebBuilder/WebViewWithNavigation.tsx"],"sourcesContent":["import React from 'react';\nimport { BackHandler } from 'react-native';\nimport { useFocusEffect } from '@react-navigation/native';\nimport { tryWebBuilderBack } from './webbuilderBackHandler';\n\n/**\n * Hardware back: dismiss in-app preview if open, otherwise leave WebBuilder.\n */\nexport function WebViewWithNavigation({\n onGoBack,\n}: {\n /** Kept for call-site compatibility; SPA history is no longer used. */\n webViewRef?: React.RefObject<unknown>;\n canGoBack?: boolean;\n onGoBack: () => void;\n}): null {\n useFocusEffect(\n React.useCallback(() => {\n const onBackPress = () => {\n // Preview dismiss only (via setWebBuilderBackHandler). SPA history\n // must not trap Android back on this screen.\n if (tryWebBuilderBack()) {\n return true;\n }\n onGoBack();\n return true;\n };\n\n const subscription = BackHandler.addEventListener('hardwareBackPress', onBackPress);\n return () => subscription.remove();\n }, [onGoBack]),\n );\n\n return null;\n}\n"],"names":[],"mappings":"iLAQO,SAAS,qBAAsB,CAAA;AAAA,EACpC;AACF,CAKS,EAAA;AACP,EAAe,cAAA,CAAA,KAAA,CAAM,YAAY,MAAM;AACrC,IAAA,MAAM,cAAc,MAAM;AAGxB,MAAA,IAAI,mBAAqB,EAAA;AACvB,QAAO,OAAA,IAAA;AAAA;AAET,MAAS,QAAA,EAAA;AACT,MAAO,OAAA,IAAA;AAAA,KACT;AACA,IAAA,MAAM,YAAe,GAAA,WAAA,CAAY,gBAAiB,CAAA,mBAAA,EAAqB,WAAW,CAAA;AAClF,IAAO,OAAA,MAAM,aAAa,MAAO,EAAA;AAAA,GAChC,EAAA,CAAC,QAAQ,CAAC,CAAC,CAAA;AACd,EAAO,OAAA,IAAA;AACT"}
1
+ {"version":3,"file":"WebViewWithNavigation.js","sources":["../../../src/screens/WebBuilder/WebViewWithNavigation.tsx"],"sourcesContent":["import React from 'react';\nimport { BackHandler } from 'react-native';\nimport { useFocusEffect } from '@react-navigation/native';\nimport { tryWebBuilderBack } from './webbuilderBackHandler';\n\n/**\n * Hardware back: dismiss in-app preview if open, otherwise leave WebBuilder.\n */\nexport function WebViewWithNavigation({\n onGoBack,\n}: {\n /** Kept for call-site compatibility; SPA history is no longer used. */\n webViewRef?: React.RefObject<unknown>;\n canGoBack?: boolean;\n onGoBack: () => void;\n}): null {\n useFocusEffect(\n React.useCallback(() => {\n const onBackPress = () => {\n // Preview dismiss only (via setWebBuilderBackHandler). SPA history\n // must not trap Android back on this screen.\n if (tryWebBuilderBack()) {\n return true;\n }\n onGoBack();\n return true;\n };\n\n const subscription = BackHandler.addEventListener('hardwareBackPress', onBackPress);\n return () => subscription.remove();\n }, [onGoBack]),\n );\n\n return null;\n}\n"],"names":["React"],"mappings":"0LAQO,SAAS,qBAAsB,CAAA;AAAA,EACpC;AACF,CAKS,EAAA;AACP,EAAe,cAAA,CAAAA,cAAA,CAAM,YAAY,MAAM;AACrC,IAAA,MAAM,cAAc,MAAM;AAGxB,MAAA,IAAI,mBAAqB,EAAA;AACvB,QAAO,OAAA,IAAA;AAAA;AAET,MAAS,QAAA,EAAA;AACT,MAAO,OAAA,IAAA;AAAA,KACT;AACA,IAAA,MAAM,YAAe,GAAA,WAAA,CAAY,gBAAiB,CAAA,mBAAA,EAAqB,WAAW,CAAA;AAClF,IAAO,OAAA,MAAM,aAAa,MAAO,EAAA;AAAA,GAChC,EAAA,CAAC,QAAQ,CAAC,CAAC,CAAA;AACd,EAAO,OAAA,IAAA;AACT"}
@@ -159,4 +159,41 @@ async function parseShoppingViaBrain(text, opts = {}) {
159
159
  "status"
160
160
  ]);
161
161
  return rest;
162
- }export{brainEndpoint,classifyIntentViaBrain,classifyShoppingViaBrain,parseShoppingViaBrain,quickReplyViaBrain};//# sourceMappingURL=brainQuickReply.js.map
162
+ }
163
+ const BRAIN_COMPLETE_PATH = "/resources/yantra-brain-complete";
164
+ async function brainCompleteViaBrain(messages, opts = {}) {
165
+ var _a, _b;
166
+ const base = (config.CLIENT_URL || "").trim().replace(/\/+$/, "");
167
+ const endpoint = base ? `${base}${BRAIN_COMPLETE_PATH}` : "";
168
+ if (!endpoint || messages.length === 0) return null;
169
+ const controller = new AbortController();
170
+ const timeout = setTimeout(() => controller.abort(), (_a = opts.timeoutMs) != null ? _a : 15e3);
171
+ if (opts.signal) {
172
+ if (opts.signal.aborted) controller.abort();
173
+ else opts.signal.addEventListener("abort", () => controller.abort(), {
174
+ once: true
175
+ });
176
+ }
177
+ try {
178
+ const res = await fetch(endpoint, {
179
+ method: "POST",
180
+ headers: {
181
+ "Content-Type": "application/json"
182
+ },
183
+ body: JSON.stringify({
184
+ messages,
185
+ model: "yantra-brain/fast",
186
+ max_tokens: (_b = opts.maxTokens) != null ? _b : 220
187
+ }),
188
+ signal: controller.signal
189
+ });
190
+ if (!res.ok) return null;
191
+ const data = await res.json();
192
+ const content = typeof (data == null ? void 0 : data.content) === "string" ? data.content.trim() : "";
193
+ return content || null;
194
+ } catch (e) {
195
+ return null;
196
+ } finally {
197
+ clearTimeout(timeout);
198
+ }
199
+ }export{brainCompleteViaBrain,brainEndpoint,classifyIntentViaBrain,classifyShoppingViaBrain,parseShoppingViaBrain,quickReplyViaBrain};//# sourceMappingURL=brainQuickReply.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"brainQuickReply.js","sources":["../../src/services/brainQuickReply.ts"],"sourcesContent":["/**\n * brainQuickReply - a fast first answer from `yantra-brain` while the real agent works.\n *\n * On mobile the first turn of a session is the slow one: the agent session has to\n * bootstrap (sandbox, connectors, memory) before a single delta arrives, and on a\n * cold pod that can run to minutes. The web client only reaches for the brain after\n * the full 300s stall budget expires; mobile did not reach for it at all, so a user\n * saw nothing, then an error. This asks the brain the SAME question in parallel and\n * paints its answer as a provisional reply the moment it lands. When the agent's\n * stream starts, that provisional text is replaced in place - the brain fills the\n * silence, it never wins over the real answer.\n *\n * The brain proxy is the web app's same-origin Remix resource route\n * (`/resources/yantra-brain-classify`, `task: 'assist'`). Mobile has no same\n * origin, so it targets the web app's public URL (CLIENT_URL) explicitly. The\n * route holds the model, prompt and secret server-side - the phone still never\n * sees a provider key.\n *\n * Best-effort and never throws: null on timeout, network error or empty answer.\n */\nimport { config } from '../config/env-config';\n\nconst BRAIN_PATH = '/resources/yantra-brain-classify';\n\n// Server-side upstream cap is ASSIST_TIMEOUT_MS (12s); give the phone headroom\n// past it so a slow-but-successful answer is not aborted at the same instant.\nconst DEFAULT_TIMEOUT_MS = 15000;\n\n/** The web app origin that serves the brain proxy, or '' when unconfigured. */\nexport function brainEndpoint(): string {\n const base = (config.CLIENT_URL || '').trim().replace(/\\/+$/, '');\n return base ? `${base}${BRAIN_PATH}` : '';\n}\n\nexport async function quickReplyViaBrain(\n text: string,\n opts: { timeoutMs?: number; signal?: AbortSignal } = {},\n): Promise<string | null> {\n const trimmed = (text || '').trim();\n const endpoint = brainEndpoint();\n if (!trimmed || !endpoint) return null;\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n if (opts.signal) {\n if (opts.signal.aborted) controller.abort();\n else opts.signal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n\n try {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ text: trimmed.slice(0, 4000), task: 'assist' }),\n signal: controller.signal,\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { answer?: string | null };\n const answer = typeof data?.answer === 'string' ? data.answer.trim() : '';\n return answer || null;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nexport interface BrainIntent {\n intent: string;\n confidence?: number;\n}\n\nconst CLASSIFY_TIMEOUT_MS = 2000;\n\nasync function postBrainJson(\n text: string,\n extra: Record<string, unknown>,\n timeoutMs: number,\n signal?: AbortSignal,\n): Promise<Record<string, unknown> | null> {\n const trimmed = (text || '').trim();\n const endpoint = brainEndpoint();\n if (!trimmed || !endpoint) return null;\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n if (signal) {\n if (signal.aborted) controller.abort();\n else signal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n\n try {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ text: trimmed.slice(0, 4000), ...extra }),\n signal: controller.signal,\n });\n if (!res.ok) return null;\n return (await res.json()) as Record<string, unknown>;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/** cdecli yantra-brain classify — same default task as web intentRouter. */\nexport async function classifyIntentViaBrain(\n text: string,\n opts: { timeoutMs?: number; signal?: AbortSignal } = {},\n): Promise<BrainIntent | null> {\n const data = await postBrainJson(text, {}, opts.timeoutMs ?? CLASSIFY_TIMEOUT_MS, opts.signal);\n const intent = typeof data?.intent === 'string' ? data.intent.trim().toLowerCase() : '';\n if (!intent) return null;\n return {\n intent,\n confidence: typeof data?.confidence === 'number' ? data.confidence : undefined,\n };\n}\n\n/** cdecli shopping parse — `task: 'shopping'`. */\nexport type ShoppingBrainVerdict =\n | { status: 'unreachable' }\n | { status: 'declined' }\n | {\n status: 'ok';\n query: string;\n productType?: string;\n synonyms?: string[];\n excludes?: string[];\n monitor?: 'watch' | 'stop';\n targetPrice?: number;\n budget?: number;\n departmentId?: string;\n };\n\nexport async function classifyShoppingViaBrain(\n text: string,\n opts: { timeoutMs?: number; signal?: AbortSignal } = {},\n): Promise<ShoppingBrainVerdict> {\n const data = await postBrainJson(text, { task: 'shopping' }, opts.timeoutMs ?? CLASSIFY_TIMEOUT_MS, opts.signal);\n if (!data) return { status: 'unreachable' };\n if (data.intent === null || data.intent === undefined) return { status: 'declined' };\n const payload = data.intent;\n if (!payload || typeof payload !== 'object') return { status: 'declined' };\n const row = payload as Record<string, unknown>;\n const query = typeof row.query === 'string' ? row.query.trim() : '';\n const monitorRaw = typeof row.monitor === 'string' ? row.monitor.trim().toLowerCase() : '';\n const monitor = monitorRaw === 'watch' || monitorRaw === 'stop' ? monitorRaw : undefined;\n if (!query && !monitor) return { status: 'declined' };\n return {\n status: 'ok',\n query,\n ...(typeof row.productType === 'string' && row.productType.trim()\n ? { productType: row.productType.trim().toLowerCase() }\n : {}),\n ...(Array.isArray(row.synonyms)\n ? {\n synonyms: row.synonyms\n .filter((s): s is string => typeof s === 'string')\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean),\n }\n : {}),\n ...(Array.isArray(row.excludes)\n ? {\n excludes: row.excludes\n .filter((s): s is string => typeof s === 'string')\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean),\n }\n : {}),\n ...(monitor ? { monitor } : {}),\n ...(typeof row.targetPrice === 'number' && row.targetPrice > 0 ? { targetPrice: row.targetPrice } : {}),\n ...(typeof row.budget === 'number' && row.budget > 0 ? { budget: Math.round(row.budget) } : {}),\n ...(typeof row.departmentId === 'string' && row.departmentId.trim()\n ? { departmentId: row.departmentId.trim().toLowerCase() }\n : {}),\n };\n}\n\nexport async function parseShoppingViaBrain(\n text: string,\n opts: { timeoutMs?: number; signal?: AbortSignal } = {},\n): Promise<{\n query: string;\n productType?: string;\n synonyms?: string[];\n excludes?: string[];\n monitor?: 'watch' | 'stop';\n targetPrice?: number;\n budget?: number;\n departmentId?: string;\n} | null> {\n const verdict = await classifyShoppingViaBrain(text, opts);\n if (verdict.status !== 'ok') return null;\n const { status: _status, ...rest } = verdict;\n return rest;\n}\n\nconst BRAIN_COMPLETE_PATH = '/resources/yantra-brain-complete';\n\n/** Keyless chat completion via the same web origin as the classify proxy. */\nexport async function brainCompleteViaBrain(\n messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>,\n opts: { maxTokens?: number; timeoutMs?: number; signal?: AbortSignal } = {},\n): Promise<string | null> {\n const base = (config.CLIENT_URL || '').trim().replace(/\\/+$/, '');\n const endpoint = base ? `${base}${BRAIN_COMPLETE_PATH}` : '';\n if (!endpoint || messages.length === 0) return null;\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts.timeoutMs ?? 15000);\n if (opts.signal) {\n if (opts.signal.aborted) controller.abort();\n else opts.signal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n\n try {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages,\n model: 'yantra-brain/fast',\n max_tokens: opts.maxTokens ?? 220,\n }),\n signal: controller.signal,\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { content?: string | null };\n const content = typeof data?.content === 'string' ? data.content.trim() : '';\n return content || null;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"brainQuickReply.js","sources":["../../src/services/brainQuickReply.ts"],"sourcesContent":["/**\n * brainQuickReply - a fast first answer from `yantra-brain` while the real agent works.\n *\n * On mobile the first turn of a session is the slow one: the agent session has to\n * bootstrap (sandbox, connectors, memory) before a single delta arrives, and on a\n * cold pod that can run to minutes. The web client only reaches for the brain after\n * the full 300s stall budget expires; mobile did not reach for it at all, so a user\n * saw nothing, then an error. This asks the brain the SAME question in parallel and\n * paints its answer as a provisional reply the moment it lands. When the agent's\n * stream starts, that provisional text is replaced in place - the brain fills the\n * silence, it never wins over the real answer.\n *\n * The brain proxy is the web app's same-origin Remix resource route\n * (`/resources/yantra-brain-classify`, `task: 'assist'`). Mobile has no same\n * origin, so it targets the web app's public URL (CLIENT_URL) explicitly. The\n * route holds the model, prompt and secret server-side - the phone still never\n * sees a provider key.\n *\n * Best-effort and never throws: null on timeout, network error or empty answer.\n */\nimport { config } from '../config/env-config';\n\nconst BRAIN_PATH = '/resources/yantra-brain-classify';\n\n// Server-side upstream cap is ASSIST_TIMEOUT_MS (12s); give the phone headroom\n// past it so a slow-but-successful answer is not aborted at the same instant.\nconst DEFAULT_TIMEOUT_MS = 15000;\n\n/** The web app origin that serves the brain proxy, or '' when unconfigured. */\nexport function brainEndpoint(): string {\n const base = (config.CLIENT_URL || '').trim().replace(/\\/+$/, '');\n return base ? `${base}${BRAIN_PATH}` : '';\n}\n\nexport async function quickReplyViaBrain(\n text: string,\n opts: { timeoutMs?: number; signal?: AbortSignal } = {},\n): Promise<string | null> {\n const trimmed = (text || '').trim();\n const endpoint = brainEndpoint();\n if (!trimmed || !endpoint) return null;\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n if (opts.signal) {\n if (opts.signal.aborted) controller.abort();\n else opts.signal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n\n try {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ text: trimmed.slice(0, 4000), task: 'assist' }),\n signal: controller.signal,\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { answer?: string | null };\n const answer = typeof data?.answer === 'string' ? data.answer.trim() : '';\n return answer || null;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\nexport interface BrainIntent {\n intent: string;\n confidence?: number;\n}\n\nconst CLASSIFY_TIMEOUT_MS = 2000;\n\nasync function postBrainJson(\n text: string,\n extra: Record<string, unknown>,\n timeoutMs: number,\n signal?: AbortSignal,\n): Promise<Record<string, unknown> | null> {\n const trimmed = (text || '').trim();\n const endpoint = brainEndpoint();\n if (!trimmed || !endpoint) return null;\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n if (signal) {\n if (signal.aborted) controller.abort();\n else signal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n\n try {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ text: trimmed.slice(0, 4000), ...extra }),\n signal: controller.signal,\n });\n if (!res.ok) return null;\n return (await res.json()) as Record<string, unknown>;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/** cdecli yantra-brain classify — same default task as web intentRouter. */\nexport async function classifyIntentViaBrain(\n text: string,\n opts: { timeoutMs?: number; signal?: AbortSignal } = {},\n): Promise<BrainIntent | null> {\n const data = await postBrainJson(text, {}, opts.timeoutMs ?? CLASSIFY_TIMEOUT_MS, opts.signal);\n const intent = typeof data?.intent === 'string' ? data.intent.trim().toLowerCase() : '';\n if (!intent) return null;\n return {\n intent,\n confidence: typeof data?.confidence === 'number' ? data.confidence : undefined,\n };\n}\n\n/** cdecli shopping parse — `task: 'shopping'`. */\nexport type ShoppingBrainVerdict =\n | { status: 'unreachable' }\n | { status: 'declined' }\n | {\n status: 'ok';\n query: string;\n productType?: string;\n synonyms?: string[];\n excludes?: string[];\n monitor?: 'watch' | 'stop';\n targetPrice?: number;\n budget?: number;\n departmentId?: string;\n };\n\nexport async function classifyShoppingViaBrain(\n text: string,\n opts: { timeoutMs?: number; signal?: AbortSignal } = {},\n): Promise<ShoppingBrainVerdict> {\n const data = await postBrainJson(text, { task: 'shopping' }, opts.timeoutMs ?? CLASSIFY_TIMEOUT_MS, opts.signal);\n if (!data) return { status: 'unreachable' };\n if (data.intent === null || data.intent === undefined) return { status: 'declined' };\n const payload = data.intent;\n if (!payload || typeof payload !== 'object') return { status: 'declined' };\n const row = payload as Record<string, unknown>;\n const query = typeof row.query === 'string' ? row.query.trim() : '';\n const monitorRaw = typeof row.monitor === 'string' ? row.monitor.trim().toLowerCase() : '';\n const monitor = monitorRaw === 'watch' || monitorRaw === 'stop' ? monitorRaw : undefined;\n if (!query && !monitor) return { status: 'declined' };\n return {\n status: 'ok',\n query,\n ...(typeof row.productType === 'string' && row.productType.trim()\n ? { productType: row.productType.trim().toLowerCase() }\n : {}),\n ...(Array.isArray(row.synonyms)\n ? {\n synonyms: row.synonyms\n .filter((s): s is string => typeof s === 'string')\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean),\n }\n : {}),\n ...(Array.isArray(row.excludes)\n ? {\n excludes: row.excludes\n .filter((s): s is string => typeof s === 'string')\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean),\n }\n : {}),\n ...(monitor ? { monitor } : {}),\n ...(typeof row.targetPrice === 'number' && row.targetPrice > 0 ? { targetPrice: row.targetPrice } : {}),\n ...(typeof row.budget === 'number' && row.budget > 0 ? { budget: Math.round(row.budget) } : {}),\n ...(typeof row.departmentId === 'string' && row.departmentId.trim()\n ? { departmentId: row.departmentId.trim().toLowerCase() }\n : {}),\n };\n}\n\nexport async function parseShoppingViaBrain(\n text: string,\n opts: { timeoutMs?: number; signal?: AbortSignal } = {},\n): Promise<{\n query: string;\n productType?: string;\n synonyms?: string[];\n excludes?: string[];\n monitor?: 'watch' | 'stop';\n targetPrice?: number;\n budget?: number;\n departmentId?: string;\n} | null> {\n const verdict = await classifyShoppingViaBrain(text, opts);\n if (verdict.status !== 'ok') return null;\n // Destructured only to leave `status` out of what is returned.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { status: _status, ...rest } = verdict;\n return rest;\n}\n\nconst BRAIN_COMPLETE_PATH = '/resources/yantra-brain-complete';\n\n/** Keyless chat completion via the same web origin as the classify proxy. */\nexport async function brainCompleteViaBrain(\n messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>,\n opts: { maxTokens?: number; timeoutMs?: number; signal?: AbortSignal } = {},\n): Promise<string | null> {\n const base = (config.CLIENT_URL || '').trim().replace(/\\/+$/, '');\n const endpoint = base ? `${base}${BRAIN_COMPLETE_PATH}` : '';\n if (!endpoint || messages.length === 0) return null;\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts.timeoutMs ?? 15000);\n if (opts.signal) {\n if (opts.signal.aborted) controller.abort();\n else opts.signal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n\n try {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages,\n model: 'yantra-brain/fast',\n max_tokens: opts.maxTokens ?? 220,\n }),\n signal: controller.signal,\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { content?: string | null };\n const content = typeof data?.content === 'string' ? data.content.trim() : '';\n return content || null;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n}\n"],"names":[],"mappings":"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"}
@@ -62,6 +62,11 @@ function appendOrReplaceAssistant(prev, assistant) {
62
62
  }
63
63
  return [...prev, assistant];
64
64
  }
65
+ function appendFollowUpAssistant(prev, assistant) {
66
+ const last = prev[prev.length - 1];
67
+ if ((last == null ? void 0 : last.role) === "assistant" && last.content.trim() === assistant.content.trim()) return prev;
68
+ return [...prev, assistant];
69
+ }
65
70
  function mergeOptimisticGatewayMessages(optimistic, backend) {
66
71
  var _a;
67
72
  if (!optimistic.length || !backend.length) return backend;
@@ -115,4 +120,4 @@ function mergeOptimisticGatewayMessages(optimistic, backend) {
115
120
  cursor += 1;
116
121
  }
117
122
  return collapseConsecutiveAssistants(merged);
118
- }export{appendOrReplaceAssistant,collapseConsecutiveAssistants,isEphemeralStreamStatus,mergeOptimisticGatewayMessages,takeCanonicalAssistantRun};//# sourceMappingURL=chatThreadMerge.js.map
123
+ }export{appendFollowUpAssistant,appendOrReplaceAssistant,collapseConsecutiveAssistants,isEphemeralStreamStatus,mergeOptimisticGatewayMessages,takeCanonicalAssistantRun};//# sourceMappingURL=chatThreadMerge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chatThreadMerge.js","sources":["../../src/state/chatThreadMerge.ts"],"sourcesContent":["/**\n * Positional thread merge, mirroring the browser package's\n * `state/chatThreadMerge.ts` (yantra-app PR #750). Kept as a dependency-free leaf\n * so it can be unit-tested without dragging in the Apollo / inversify import chain\n * that `useChatStream` pulls in.\n *\n * Mobile chat routes exclusively through CDeCLI (messenger-gateway) and lets the\n * gateway persist posts (`persistenceMode: 'backend'`). Many gateway lanes -\n * notably cdecli-serve skill turns - NEVER persist the assistant post: no\n * `chatMessageAdded` ever arrives and the reply lives only in the in-memory\n * thread. Before this merge the hydration effect wholesale-replaced the visible\n * thread with the backend snapshot on every refetch, so those replies vanished\n * the moment the next backend snapshot landed (and were gone on reopen).\n *\n * The merge keeps backend rows authoritative wherever they content-match, while\n * preserving optimistic-only rows in place:\n * - a user send the backend has not written yet stays visible (on mobile every\n * send is a gateway send, so there is no separate frontend-save lane that would\n * re-deliver it);\n * - an assistant reply the backend has no row for stays visible, unless the\n * backend's next row is itself an assistant for that turn (prefer the persisted\n * text, e.g. a webbuilder RESULT) or the text is an ephemeral status line.\n *\n * Attachment previews are intentionally NOT handled here - the caller composes\n * this with `preserveAttachmentPreviews`, which owns grafting the in-memory\n * data-URL onto the persisted user row.\n */\n\ntype MergeableMessage = {\n role: string;\n content: string;\n};\n\n/** Short gateway/workflow progress lines that must not stick under a final reply. */\nexport function isEphemeralStreamStatus(text: string | null | undefined): boolean {\n const t = (text ?? '').trim();\n if (!t) return false;\n return /^(Initializing\\.?\\.?\\.?|Setting up( your (project|workspace))?\\.?\\.?\\.?)$/i.test(t);\n}\n\n/**\n * One user turn must not keep both a quick-reply persist and the final persist.\n * Consecutive assistant rows from the backend are the same turn — keep the\n * longest non-ephemeral text (the completed answer).\n */\nexport function takeCanonicalAssistantRun<T extends MergeableMessage>(\n rows: readonly T[],\n start: number,\n): { row: T; next: number } {\n let end = start;\n while (end + 1 < rows.length && rows[end + 1].role === 'assistant') end += 1;\n let best = start;\n let bestLen = -1;\n for (let i = start; i <= end; i++) {\n if (isEphemeralStreamStatus(rows[i].content)) continue;\n const n = (rows[i].content ?? '').trim().length;\n if (n >= bestLen) {\n best = i;\n bestLen = n;\n }\n }\n return { row: rows[best], next: end + 1 };\n}\n\nexport function collapseConsecutiveAssistants<T extends MergeableMessage>(rows: T[]): T[] {\n const out: T[] = [];\n let i = 0;\n while (i < rows.length) {\n if (rows[i].role === 'assistant') {\n const run = takeCanonicalAssistantRun(rows, i);\n out.push(run.row);\n i = run.next;\n } else {\n out.push(rows[i]);\n i += 1;\n }\n }\n return out;\n}\n\n/** After stream complete, replace an assistant already on the last turn instead of stacking a second bubble. */\nexport function appendOrReplaceAssistant<T extends MergeableMessage>(prev: T[], assistant: T): T[] {\n if (prev[prev.length - 1]?.role === 'assistant') {\n const next = prev.slice();\n next[next.length - 1] = { ...next[next.length - 1], ...assistant };\n return next;\n }\n return [...prev, assistant];\n}\n\nexport function mergeOptimisticGatewayMessages<T extends MergeableMessage>(optimistic: T[], backend: T[]): T[] {\n if (!optimistic.length || !backend.length) return backend;\n\n const norm = (value: string) => value.trim();\n\n const merged: T[] = [];\n let cursor = 0;\n for (const message of optimistic) {\n let matchIndex = -1;\n for (let j = cursor; j < backend.length; j++) {\n const candidate = backend[j];\n if (candidate.role === message.role && norm(candidate.content) === norm(message.content)) {\n matchIndex = j;\n break;\n }\n }\n if (matchIndex >= 0) {\n while (cursor <= matchIndex) {\n if (backend[cursor].role === 'assistant') {\n const run = takeCanonicalAssistantRun(backend, cursor);\n merged.push(run.row);\n cursor = run.next;\n continue;\n }\n merged.push(backend[cursor]);\n cursor += 1;\n }\n continue;\n }\n if (message.role === 'user') {\n // Every mobile send is a gateway send; keep it until the backend writes it.\n merged.push(message);\n continue;\n }\n // Assistant reply with no backend row. If the backend's next row is itself an\n // assistant (this turn's canonical reply, possibly different text), prefer it.\n // Otherwise keep the optimistic reply - dropping it here is what made replies\n // vanish the moment the next message was sent. Ephemeral status lines never\n // earn a permanent bubble.\n if (backend[cursor]?.role === 'assistant') {\n const run = takeCanonicalAssistantRun(backend, cursor);\n merged.push(run.row);\n cursor = run.next;\n continue;\n }\n if (norm(message.content) && !isEphemeralStreamStatus(message.content)) {\n merged.push(message);\n }\n }\n // Backend rows past the last match (e.g. the assistant post landing mid-merge)\n // still belong at the end. Consecutive assistants are one turn — keep one.\n while (cursor < backend.length) {\n if (backend[cursor].role === 'assistant') {\n const run = takeCanonicalAssistantRun(backend, cursor);\n merged.push(run.row);\n cursor = run.next;\n continue;\n }\n merged.push(backend[cursor]);\n cursor += 1;\n }\n\n return collapseConsecutiveAssistants(merged);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chatThreadMerge.js","sources":["../../src/state/chatThreadMerge.ts"],"sourcesContent":["/**\n * Positional thread merge, mirroring the browser package's\n * `state/chatThreadMerge.ts` (yantra-app PR #750). Kept as a dependency-free leaf\n * so it can be unit-tested without dragging in the Apollo / inversify import chain\n * that `useChatStream` pulls in.\n *\n * Mobile chat routes exclusively through CDeCLI (messenger-gateway) and lets the\n * gateway persist posts (`persistenceMode: 'backend'`). Many gateway lanes -\n * notably cdecli-serve skill turns - NEVER persist the assistant post: no\n * `chatMessageAdded` ever arrives and the reply lives only in the in-memory\n * thread. Before this merge the hydration effect wholesale-replaced the visible\n * thread with the backend snapshot on every refetch, so those replies vanished\n * the moment the next backend snapshot landed (and were gone on reopen).\n *\n * The merge keeps backend rows authoritative wherever they content-match, while\n * preserving optimistic-only rows in place:\n * - a user send the backend has not written yet stays visible (on mobile every\n * send is a gateway send, so there is no separate frontend-save lane that would\n * re-deliver it);\n * - an assistant reply the backend has no row for stays visible, unless the\n * backend's next row is itself an assistant for that turn (prefer the persisted\n * text, e.g. a webbuilder RESULT) or the text is an ephemeral status line.\n *\n * Attachment previews are intentionally NOT handled here - the caller composes\n * this with `preserveAttachmentPreviews`, which owns grafting the in-memory\n * data-URL onto the persisted user row.\n */\n\ntype MergeableMessage = {\n role: string;\n content: string;\n};\n\n/** Short gateway/workflow progress lines that must not stick under a final reply. */\nexport function isEphemeralStreamStatus(text: string | null | undefined): boolean {\n const t = (text ?? '').trim();\n if (!t) return false;\n return /^(Initializing\\.?\\.?\\.?|Setting up( your (project|workspace))?\\.?\\.?\\.?)$/i.test(t);\n}\n\n/**\n * One user turn must not keep both a quick-reply persist and the final persist.\n * Consecutive assistant rows from the backend are the same turn — keep the\n * longest non-ephemeral text (the completed answer).\n */\nexport function takeCanonicalAssistantRun<T extends MergeableMessage>(\n rows: readonly T[],\n start: number,\n): { row: T; next: number } {\n let end = start;\n while (end + 1 < rows.length && rows[end + 1].role === 'assistant') end += 1;\n let best = start;\n let bestLen = -1;\n for (let i = start; i <= end; i++) {\n if (isEphemeralStreamStatus(rows[i].content)) continue;\n const n = (rows[i].content ?? '').trim().length;\n if (n >= bestLen) {\n best = i;\n bestLen = n;\n }\n }\n return { row: rows[best], next: end + 1 };\n}\n\nexport function collapseConsecutiveAssistants<T extends MergeableMessage>(rows: T[]): T[] {\n const out: T[] = [];\n let i = 0;\n while (i < rows.length) {\n if (rows[i].role === 'assistant') {\n const run = takeCanonicalAssistantRun(rows, i);\n out.push(run.row);\n i = run.next;\n } else {\n out.push(rows[i]);\n i += 1;\n }\n }\n return out;\n}\n\n/** After stream complete, replace an assistant already on the last turn instead of stacking a second bubble. */\nexport function appendOrReplaceAssistant<T extends MergeableMessage>(prev: T[], assistant: T): T[] {\n if (prev[prev.length - 1]?.role === 'assistant') {\n const next = prev.slice();\n next[next.length - 1] = { ...next[next.length - 1], ...assistant };\n return next;\n }\n return [...prev, assistant];\n}\n\n/**\n * A follow-up the agent sent with no send behind it (the answer to a request\n * the gateway queued while the agent was busy) is a bubble of its own:\n * replacing the last assistant would overwrite the reply it follows. The same\n * text twice is one delivery, not two.\n */\nexport function appendFollowUpAssistant<T extends MergeableMessage>(prev: T[], assistant: T): T[] {\n const last = prev[prev.length - 1];\n if (last?.role === 'assistant' && last.content.trim() === assistant.content.trim()) return prev;\n return [...prev, assistant];\n}\n\nexport function mergeOptimisticGatewayMessages<T extends MergeableMessage>(optimistic: T[], backend: T[]): T[] {\n if (!optimistic.length || !backend.length) return backend;\n\n const norm = (value: string) => value.trim();\n\n const merged: T[] = [];\n let cursor = 0;\n for (const message of optimistic) {\n let matchIndex = -1;\n for (let j = cursor; j < backend.length; j++) {\n const candidate = backend[j];\n if (candidate.role === message.role && norm(candidate.content) === norm(message.content)) {\n matchIndex = j;\n break;\n }\n }\n if (matchIndex >= 0) {\n while (cursor <= matchIndex) {\n if (backend[cursor].role === 'assistant') {\n const run = takeCanonicalAssistantRun(backend, cursor);\n merged.push(run.row);\n cursor = run.next;\n continue;\n }\n merged.push(backend[cursor]);\n cursor += 1;\n }\n continue;\n }\n if (message.role === 'user') {\n // Every mobile send is a gateway send; keep it until the backend writes it.\n merged.push(message);\n continue;\n }\n // Assistant reply with no backend row. If the backend's next row is itself an\n // assistant (this turn's canonical reply, possibly different text), prefer it.\n // Otherwise keep the optimistic reply - dropping it here is what made replies\n // vanish the moment the next message was sent. Ephemeral status lines never\n // earn a permanent bubble.\n if (backend[cursor]?.role === 'assistant') {\n const run = takeCanonicalAssistantRun(backend, cursor);\n merged.push(run.row);\n cursor = run.next;\n continue;\n }\n if (norm(message.content) && !isEphemeralStreamStatus(message.content)) {\n merged.push(message);\n }\n }\n // Backend rows past the last match (e.g. the assistant post landing mid-merge)\n // still belong at the end. Consecutive assistants are one turn — keep one.\n while (cursor < backend.length) {\n if (backend[cursor].role === 'assistant') {\n const run = takeCanonicalAssistantRun(backend, cursor);\n merged.push(run.row);\n cursor = run.next;\n continue;\n }\n merged.push(backend[cursor]);\n cursor += 1;\n }\n\n return collapseConsecutiveAssistants(merged);\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminide-stack/yantra-mobile",
3
- "version": "12.0.69-alpha.9",
3
+ "version": "12.0.70-alpha.0",
4
4
  "description": "Sample core for higher packages to depend on",
5
5
  "license": "ISC",
6
6
  "author": "CDMBase LLC",
@@ -13,6 +13,7 @@
13
13
  "build:clean": "rimraf lib",
14
14
  "build:lib": "rollup -c rollup.config.mjs",
15
15
  "build:lib:watch": "yarn build:lib -- --watch",
16
+ "gen:emoji-keywords": "node tools/gen-emoji-keywords.mjs",
16
17
  "jest": "./node_modules/.bin/jest",
17
18
  "prepublish": "yarn build",
18
19
  "test": "jest",
@@ -25,7 +26,7 @@
25
26
  "uuid": "^9.0.0"
26
27
  },
27
28
  "devDependencies": {
28
- "common": "12.0.69-alpha.9"
29
+ "common": "12.0.70-alpha.0"
29
30
  },
30
31
  "peerDependencies": {
31
32
  "@admin-layout/gluestack-ui-mobile": "*",
@@ -41,9 +42,10 @@
41
42
  "@messenger-box/platform-mobile": "*",
42
43
  "@react-native-async-storage/async-storage": "*",
43
44
  "@react-navigation/native": "*",
44
- "common": "12.0.69-alpha.8",
45
+ "common": "12.0.69-alpha.25",
45
46
  "expo-constants": "*",
46
47
  "expo-secure-store": "*",
48
+ "expo-web-browser": "*",
47
49
  "lodash": "*",
48
50
  "react-native": "*",
49
51
  "react-native-keyboard-controller": "*",
@@ -57,5 +59,5 @@
57
59
  "typescript": {
58
60
  "definition": "lib/index.d.ts"
59
61
  },
60
- "gitHead": "cb6edc3fe77c2ceb67e0d26e593dd659162c6e28"
62
+ "gitHead": "b15e1b2ed56e147d8258d1584830c85f91c37e9f"
61
63
  }