Browse Source

feat: browser search engine support

Timothy J. Baek 1 year ago
parent
commit
f58eb0d266
5 changed files with 42 additions and 1 deletions
  1. 3 0
      backend/config.py
  2. 17 1
      backend/main.py
  3. 6 0
      src/app.html
  4. 8 0
      src/routes/(app)/+page.svelte
  5. 8 0
      static/opensearch.xml

+ 3 - 0
backend/config.py

@@ -76,8 +76,11 @@ WEBUI_NAME = os.environ.get("WEBUI_NAME", "Open WebUI")
 if WEBUI_NAME != "Open WebUI":
 if WEBUI_NAME != "Open WebUI":
     WEBUI_NAME += " (Open WebUI)"
     WEBUI_NAME += " (Open WebUI)"
 
 
+WEBUI_URL = os.environ.get("WEBUI_URL", "http://localhost:3000")
+
 WEBUI_FAVICON_URL = "https://openwebui.com/favicon.png"
 WEBUI_FAVICON_URL = "https://openwebui.com/favicon.png"
 
 
+
 ####################################
 ####################################
 # ENV (dev,test,prod)
 # ENV (dev,test,prod)
 ####################################
 ####################################

+ 17 - 1
backend/main.py

@@ -15,7 +15,7 @@ from fastapi.middleware.wsgi import WSGIMiddleware
 from fastapi.middleware.cors import CORSMiddleware
 from fastapi.middleware.cors import CORSMiddleware
 from starlette.exceptions import HTTPException as StarletteHTTPException
 from starlette.exceptions import HTTPException as StarletteHTTPException
 from starlette.middleware.base import BaseHTTPMiddleware
 from starlette.middleware.base import BaseHTTPMiddleware
-from starlette.responses import StreamingResponse
+from starlette.responses import StreamingResponse, Response
 
 
 from apps.ollama.main import app as ollama_app
 from apps.ollama.main import app as ollama_app
 from apps.openai.main import app as openai_app
 from apps.openai.main import app as openai_app
@@ -43,6 +43,7 @@ from apps.rag.utils import rag_messages
 from config import (
 from config import (
     CONFIG_DATA,
     CONFIG_DATA,
     WEBUI_NAME,
     WEBUI_NAME,
+    WEBUI_URL,
     ENV,
     ENV,
     VERSION,
     VERSION,
     CHANGELOG,
     CHANGELOG,
@@ -350,6 +351,21 @@ async def get_manifest_json():
     }
     }
 
 
 
 
+@app.get("/opensearch.xml")
+async def get_opensearch_xml():
+    xml_content = rf"""
+    <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
+    <ShortName>{WEBUI_NAME}</ShortName>
+    <Description>Search {WEBUI_NAME}</Description>
+    <InputEncoding>UTF-8</InputEncoding>
+    <Image width="16" height="16" type="image/x-icon">{WEBUI_URL}/favicon.png</Image>
+    <Url type="text/html" method="get" template="{WEBUI_URL}/?q={"{searchTerms}"}"/>
+    <moz:SearchForm>{WEBUI_URL}</moz:SearchForm>
+    </OpenSearchDescription>
+    """
+    return Response(content=xml_content, media_type="application/xml")
+
+
 app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
 app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
 app.mount("/cache", StaticFiles(directory=CACHE_DIR), name="cache")
 app.mount("/cache", StaticFiles(directory=CACHE_DIR), name="cache")
 
 

+ 6 - 0
src/app.html

@@ -6,6 +6,12 @@
 		<link rel="manifest" href="%sveltekit.assets%/manifest.json" crossorigin="use-credentials" />
 		<link rel="manifest" href="%sveltekit.assets%/manifest.json" crossorigin="use-credentials" />
 		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
 		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
 		<meta name="robots" content="noindex,nofollow" />
 		<meta name="robots" content="noindex,nofollow" />
+		<link
+			rel="search"
+			type="application/opensearchdescription+xml"
+			title="Open WebUI"
+			href="/opensearch.xml"
+		/>
 		<script>
 		<script>
 			// On page load or when changing themes, best to add inline in `head` to avoid FOUC
 			// On page load or when changing themes, best to add inline in `head` to avoid FOUC
 			(() => {
 			(() => {

+ 8 - 0
src/routes/(app)/+page.svelte

@@ -134,6 +134,14 @@
 			selectedModels = [''];
 			selectedModels = [''];
 		}
 		}
 
 
+		if ($page.url.searchParams.get('q')) {
+			prompt = $page.url.searchParams.get('q') ?? '';
+			if (prompt) {
+				await tick();
+				submitPrompt(prompt);
+			}
+		}
+
 		selectedModels = selectedModels.map((modelId) =>
 		selectedModels = selectedModels.map((modelId) =>
 			$models.map((m) => m.id).includes(modelId) ? modelId : ''
 			$models.map((m) => m.id).includes(modelId) ? modelId : ''
 		);
 		);

+ 8 - 0
static/opensearch.xml

@@ -0,0 +1,8 @@
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
+<ShortName>Open WebUI</ShortName>
+<Description>Search Open WebUI</Description>
+<InputEncoding>UTF-8</InputEncoding>
+<Image width="16" height="16" type="image/x-icon">http://localhost:5137/favicon.png</Image>
+<Url type="text/html" method="get" template="http://localhost:5137/?q={searchTerms}"/>
+<moz:SearchForm>http://localhost:5137</moz:SearchForm>
+</OpenSearchDescription>