Add search mode settings and textarea focus on form submission
This commit is contained in:
		
							parent
							
								
									a87c56061c
								
							
						
					
					
						commit
						1b689c91c0
					
				| @ -212,7 +212,7 @@ export const ModelsBody = () => { | |||||||
| 
 | 
 | ||||||
|           <button |           <button | ||||||
|             type="submit" |             type="submit" | ||||||
|             className="inline-flex justify-center w-full text-center mt-4 items-center rounded-md border border-transparent bg-black px-2 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50 "> |             className="inline-flex justify-center w-full text-center mt-4 items-center rounded-md border border-transparent bg-black px-2 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50 "> | ||||||
|             <Download className="w-5 h-5 mr-3" /> |             <Download className="w-5 h-5 mr-3" /> | ||||||
|             Pull Model |             Pull Model | ||||||
|           </button> |           </button> | ||||||
|  | |||||||
| @ -17,8 +17,20 @@ type Props = { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export const PlaygroundForm = ({ dropedFile }: Props) => { | export const PlaygroundForm = ({ dropedFile }: Props) => { | ||||||
|   const textareaRef = React.useRef<HTMLTextAreaElement>(null) |  | ||||||
|   const inputRef = React.useRef<HTMLInputElement>(null) |   const inputRef = React.useRef<HTMLInputElement>(null) | ||||||
|  |   const { | ||||||
|  |     onSubmit, | ||||||
|  |     selectedModel, | ||||||
|  |     chatMode, | ||||||
|  |     speechToTextLanguage, | ||||||
|  |     stopStreamingRequest, | ||||||
|  |     streaming: isSending, | ||||||
|  |     webSearch, | ||||||
|  |     setWebSearch, | ||||||
|  |     selectedQuickPrompt, | ||||||
|  |     textareaRef, | ||||||
|  |     setSelectedQuickPrompt | ||||||
|  |   } = useMessageOption() | ||||||
| 
 | 
 | ||||||
|   const textAreaFocus = () => { |   const textAreaFocus = () => { | ||||||
|     if (textareaRef.current) { |     if (textareaRef.current) { | ||||||
| @ -62,19 +74,6 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { | |||||||
| 
 | 
 | ||||||
|   useDynamicTextareaSize(textareaRef, form.values.message, 300) |   useDynamicTextareaSize(textareaRef, form.values.message, 300) | ||||||
| 
 | 
 | ||||||
|   const { |  | ||||||
|     onSubmit, |  | ||||||
|     selectedModel, |  | ||||||
|     chatMode, |  | ||||||
|     speechToTextLanguage, |  | ||||||
|     stopStreamingRequest, |  | ||||||
|     streaming: isSending, |  | ||||||
|     webSearch, |  | ||||||
|     setWebSearch, |  | ||||||
|     selectedQuickPrompt, |  | ||||||
|     setSelectedQuickPrompt |  | ||||||
|   } = useMessageOption() |  | ||||||
| 
 |  | ||||||
|   const { isListening, start, stop, transcript } = useSpeechRecognition() |   const { isListening, start, stop, transcript } = useSpeechRecognition() | ||||||
|   const { sendWhenEnter, setSendWhenEnter } = useWebUI() |   const { sendWhenEnter, setSendWhenEnter } = useWebUI() | ||||||
| 
 | 
 | ||||||
| @ -92,6 +91,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { | |||||||
|         textareaRef.current?.focus() |         textareaRef.current?.focus() | ||||||
|         const interval = setTimeout(() => { |         const interval = setTimeout(() => { | ||||||
|           textareaRef.current?.setSelectionRange(word.start, word.end) |           textareaRef.current?.setSelectionRange(word.start, word.end) | ||||||
|  |           setSelectedQuickPrompt(null) | ||||||
|         }, 100) |         }, 100) | ||||||
|         return () => { |         return () => { | ||||||
|           clearInterval(interval) |           clearInterval(interval) | ||||||
|  | |||||||
| @ -224,7 +224,7 @@ export const PromptBody = () => { | |||||||
|           <Form.Item> |           <Form.Item> | ||||||
|             <button |             <button | ||||||
|               disabled={savePromptLoading} |               disabled={savePromptLoading} | ||||||
|               className="inline-flex justify-center w-full text-center mt-4 items-center rounded-md border border-transparent bg-black px-2 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50 "> |               className="inline-flex justify-center w-full text-center mt-4 items-center rounded-md border border-transparent bg-black px-2 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50 "> | ||||||
|               {savePromptLoading ? "Adding Prompt..." : "Add Prompt"} |               {savePromptLoading ? "Adding Prompt..." : "Add Prompt"} | ||||||
|             </button> |             </button> | ||||||
|           </Form.Item> |           </Form.Item> | ||||||
| @ -268,7 +268,7 @@ export const PromptBody = () => { | |||||||
|           <Form.Item> |           <Form.Item> | ||||||
|             <button |             <button | ||||||
|               disabled={isUpdatingPrompt} |               disabled={isUpdatingPrompt} | ||||||
|               className="inline-flex justify-center w-full text-center mt-4 items-center rounded-md border border-transparent bg-black px-2 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50 "> |               className="inline-flex justify-center w-full text-center mt-4 items-center rounded-md border border-transparent bg-black px-2 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50 "> | ||||||
|               {isUpdatingPrompt ? "Updating Prompt..." : "Update Prompt"} |               {isUpdatingPrompt ? "Updating Prompt..." : "Update Prompt"} | ||||||
|             </button> |             </button> | ||||||
|           </Form.Item> |           </Form.Item> | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ import { PageAssitDatabase } from "~libs/db" | |||||||
| import { Select } from "antd" | import { Select } from "antd" | ||||||
| import { SUPPORTED_LANGUAGES } from "~utils/supporetd-languages" | import { SUPPORTED_LANGUAGES } from "~utils/supporetd-languages" | ||||||
| import { MoonIcon, SunIcon } from "lucide-react" | import { MoonIcon, SunIcon } from "lucide-react" | ||||||
|  | import { SearchModeSettings } from "./search-mode" | ||||||
| 
 | 
 | ||||||
| export const SettingOther = () => { | export const SettingOther = () => { | ||||||
|   const { clearChat, speechToTextLanguage, setSpeechToTextLanguage } = |   const { clearChat, speechToTextLanguage, setSpeechToTextLanguage } = | ||||||
| @ -82,6 +83,7 @@ export const SettingOther = () => { | |||||||
|           Delete |           Delete | ||||||
|         </button> |         </button> | ||||||
|       </div> |       </div> | ||||||
|  |       <SearchModeSettings /> | ||||||
|     </dl> |     </dl> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										37
									
								
								src/components/Option/Settings/search-mode.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/components/Option/Settings/search-mode.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | import { useQuery, useQueryClient } from "@tanstack/react-query" | ||||||
|  | import { Skeleton, Switch } from "antd" | ||||||
|  | import { | ||||||
|  |   getIsSimpleInternetSearch, | ||||||
|  |   setIsSimpleInternetSearch | ||||||
|  | } from "~services/ollama" | ||||||
|  | 
 | ||||||
|  | export const SearchModeSettings = () => { | ||||||
|  |   const { data, status } = useQuery({ | ||||||
|  |     queryKey: ["fetchIsSimpleInternetSearch"], | ||||||
|  |     queryFn: () => getIsSimpleInternetSearch() | ||||||
|  |   }) | ||||||
|  | 
 | ||||||
|  |   const queryClient = useQueryClient() | ||||||
|  | 
 | ||||||
|  |   if (status === "pending" || status === "error") { | ||||||
|  |     return <Skeleton active /> | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div className="flex flex-row justify-between"> | ||||||
|  |       <span className="text-gray-500 dark:text-gray-400 text-lg"> | ||||||
|  |         Perform Simple Internet Search | ||||||
|  |       </span> | ||||||
|  | 
 | ||||||
|  |       <Switch | ||||||
|  |         checked={data} | ||||||
|  |         onChange={(checked) => { | ||||||
|  |           setIsSimpleInternetSearch(checked) | ||||||
|  |           queryClient.invalidateQueries({ | ||||||
|  |             queryKey: ["fetchIsSimpleInternetSearch"] | ||||||
|  |           }) | ||||||
|  |         }} | ||||||
|  |       /> | ||||||
|  |     </div> | ||||||
|  |   ) | ||||||
|  | } | ||||||
| @ -115,6 +115,7 @@ export const useMessageOption = () => { | |||||||
|   } = useStoreMessageOption() |   } = useStoreMessageOption() | ||||||
| 
 | 
 | ||||||
|   const navigate = useNavigate() |   const navigate = useNavigate() | ||||||
|  |   const textareaRef = React.useRef<HTMLTextAreaElement>(null) | ||||||
| 
 | 
 | ||||||
|   const abortControllerRef = React.useRef<AbortController | null>(null) |   const abortControllerRef = React.useRef<AbortController | null>(null) | ||||||
| 
 | 
 | ||||||
| @ -126,6 +127,7 @@ export const useMessageOption = () => { | |||||||
|     setIsLoading(false) |     setIsLoading(false) | ||||||
|     setIsProcessing(false) |     setIsProcessing(false) | ||||||
|     setStreaming(false) |     setStreaming(false) | ||||||
|  |     textareaRef?.current?.focus() | ||||||
|     navigate("/") |     navigate("/") | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -671,6 +673,7 @@ export const useMessageOption = () => { | |||||||
|     selectedQuickPrompt, |     selectedQuickPrompt, | ||||||
|     setSelectedQuickPrompt, |     setSelectedQuickPrompt, | ||||||
|     selectedSystemPrompt, |     selectedSystemPrompt, | ||||||
|     setSelectedSystemPrompt |     setSelectedSystemPrompt, | ||||||
|  |     textareaRef | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -289,3 +289,17 @@ export const setWebPrompts = async (prompt: string, followUpPrompt: string) => { | |||||||
|   await setWebSearchPrompt(prompt) |   await setWebSearchPrompt(prompt) | ||||||
|   await setWebSearchFollowUpPrompt(followUpPrompt) |   await setWebSearchFollowUpPrompt(followUpPrompt) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | export const getIsSimpleInternetSearch = async () => { | ||||||
|  |   const isSimpleInternetSearch = await storage.get("isSimpleInternetSearch") | ||||||
|  |   if (!isSimpleInternetSearch || isSimpleInternetSearch.length === 0) { | ||||||
|  |     return true | ||||||
|  |   } | ||||||
|  |   return isSimpleInternetSearch === "true" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export const setIsSimpleInternetSearch = async (isSimpleInternetSearch: boolean) => { | ||||||
|  |   await storage.set("isSimpleInternetSearch", isSimpleInternetSearch.toString()) | ||||||
|  | } | ||||||
| @ -5,7 +5,7 @@ import { MemoryVectorStore } from "langchain/vectorstores/memory" | |||||||
| import { cleanUrl } from "~libs/clean-url" | import { cleanUrl } from "~libs/clean-url" | ||||||
| import { chromeRunTime } from "~libs/runtime" | import { chromeRunTime } from "~libs/runtime" | ||||||
| import { PageAssistHtmlLoader } from "~loader/html" | import { PageAssistHtmlLoader } from "~loader/html" | ||||||
| import { defaultEmbeddingChunkOverlap, defaultEmbeddingChunkSize, defaultEmbeddingModelForRag, getOllamaURL } from "~services/ollama" | import { defaultEmbeddingChunkOverlap, defaultEmbeddingChunkSize, defaultEmbeddingModelForRag, getIsSimpleInternetSearch, getOllamaURL } from "~services/ollama" | ||||||
| 
 | 
 | ||||||
| const BLOCKED_HOSTS = [ | const BLOCKED_HOSTS = [ | ||||||
|   "google.com", |   "google.com", | ||||||
| @ -40,13 +40,7 @@ export const localGoogleSearch = async (query: string) => { | |||||||
|     (result) => { |     (result) => { | ||||||
|       const title = result.querySelector("h3")?.textContent |       const title = result.querySelector("h3")?.textContent | ||||||
|       const link = result.querySelector("a")?.getAttribute("href") |       const link = result.querySelector("a")?.getAttribute("href") | ||||||
|       let content = result.querySelector("div[data-sncf='2']")?.textContent  |       const content = Array.from(result.querySelectorAll("span")).map((span) => span.textContent).join(" ") | ||||||
|       if(content === "") { |  | ||||||
|         content = result.querySelector("div[data-sncf='1']")?.textContent |  | ||||||
|         if(content === "") { |  | ||||||
|           content = result.querySelector("div[data-sncf='3']")?.textContent |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       return { title, link, content } |       return { title, link, content } | ||||||
|     } |     } | ||||||
|   ) |   ) | ||||||
| @ -65,6 +59,18 @@ export const webSearch = async (query: string) => { | |||||||
|   const results = await localGoogleSearch(query) |   const results = await localGoogleSearch(query) | ||||||
|   const searchResults = results.slice(0, TOTAL_SEARCH_RESULTS) |   const searchResults = results.slice(0, TOTAL_SEARCH_RESULTS) | ||||||
| 
 | 
 | ||||||
|  |   const isSimpleMode = await getIsSimpleInternetSearch() | ||||||
|  | 
 | ||||||
|  |   if (isSimpleMode) { | ||||||
|  |     await getOllamaURL() | ||||||
|  |     return searchResults.map((result) => { | ||||||
|  |       return { | ||||||
|  |         url: result.link, | ||||||
|  |         content: result.content | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   const docs: Document<Record<string, any>>[] = []; |   const docs: Document<Record<string, any>>[] = []; | ||||||
|   for (const result of searchResults) { |   for (const result of searchResults) { | ||||||
|     const loader = new PageAssistHtmlLoader({ |     const loader = new PageAssistHtmlLoader({ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user