forked from open-webui/open-webui
		
	main #2
					 18 changed files with 538 additions and 204 deletions
				
			
		
							
								
								
									
										10
									
								
								CHANGELOG.md
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								CHANGELOG.md
									
										
									
									
									
								
							|  | @ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. | |||
| The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), | ||||
| and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||||
| 
 | ||||
| ## [0.1.112] - 2024-03-XX | ||||
| ## [0.1.113] - 2024-03-XX | ||||
| 
 | ||||
| ### Added | ||||
| 
 | ||||
|  | @ -15,6 +15,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 
 | ||||
| - 🌑 **Dark background on select fields**: Added dark background to select fields, as this caused bad readability on some browsers/devices. | ||||
| 
 | ||||
| ## [0.1.112] - 2024-03-15 | ||||
| 
 | ||||
| ### Fixed | ||||
| 
 | ||||
| - 🗨️ Resolved chat malfunction after image generation. | ||||
| - 🎨 Fixed various RAG issues. | ||||
| - 🧪 Rectified experimental broken GGUF upload logic. | ||||
| 
 | ||||
| ## [0.1.111] - 2024-03-10 | ||||
| 
 | ||||
| ### Added | ||||
|  |  | |||
|  | @ -293,6 +293,7 @@ def generate_image( | |||
|                 "size": form_data.size if form_data.size else app.state.IMAGE_SIZE, | ||||
|                 "response_format": "b64_json", | ||||
|             } | ||||
| 
 | ||||
|             r = requests.post( | ||||
|                 url=f"https://api.openai.com/v1/images/generations", | ||||
|                 json=data, | ||||
|  | @ -300,7 +301,6 @@ def generate_image( | |||
|             ) | ||||
| 
 | ||||
|             r.raise_for_status() | ||||
| 
 | ||||
|             res = r.json() | ||||
| 
 | ||||
|             images = [] | ||||
|  | @ -356,7 +356,10 @@ def generate_image( | |||
|             return images | ||||
| 
 | ||||
|     except Exception as e: | ||||
|         print(e) | ||||
|         if r: | ||||
|             print(r.json()) | ||||
|         raise HTTPException(status_code=400, detail=ERROR_MESSAGES.DEFAULT(e)) | ||||
|         error = e | ||||
| 
 | ||||
|         if r != None: | ||||
|             data = r.json() | ||||
|             if "error" in data: | ||||
|                 error = data["error"]["message"] | ||||
|         raise HTTPException(status_code=400, detail=ERROR_MESSAGES.DEFAULT(error)) | ||||
|  |  | |||
|  | @ -123,6 +123,7 @@ async def get_all_models(): | |||
|             map(lambda response: response["models"], responses) | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     app.state.MODELS = {model["model"]: model for model in models["models"]} | ||||
| 
 | ||||
|     return models | ||||
|  | @ -181,11 +182,17 @@ async def get_ollama_versions(url_idx: Optional[int] = None): | |||
|         responses = await asyncio.gather(*tasks) | ||||
|         responses = list(filter(lambda x: x is not None, responses)) | ||||
| 
 | ||||
|         if len(responses) > 0: | ||||
|             lowest_version = min( | ||||
|                 responses, key=lambda x: tuple(map(int, x["version"].split("."))) | ||||
|             ) | ||||
| 
 | ||||
|             return {"version": lowest_version["version"]} | ||||
|         else: | ||||
|             raise HTTPException( | ||||
|                 status_code=500, | ||||
|                 detail=ERROR_MESSAGES.OLLAMA_NOT_FOUND, | ||||
|             ) | ||||
|     else: | ||||
|         url = app.state.OLLAMA_BASE_URLS[url_idx] | ||||
|         try: | ||||
|  |  | |||
|  | @ -400,9 +400,9 @@ def get_loader(filename: str, file_content_type: str, file_path: str): | |||
|     elif file_ext in known_source_ext or ( | ||||
|         file_content_type and file_content_type.find("text/") >= 0 | ||||
|     ): | ||||
|         loader = TextLoader(file_path) | ||||
|         loader = TextLoader(file_path, autodetect_encoding=True) | ||||
|     else: | ||||
|         loader = TextLoader(file_path) | ||||
|         loader = TextLoader(file_path, autodetect_encoding=True) | ||||
|         known_type = False | ||||
| 
 | ||||
|     return loader, known_type | ||||
|  |  | |||
|  | @ -91,9 +91,8 @@ def query_collection( | |||
| 
 | ||||
| 
 | ||||
| def rag_template(template: str, context: str, query: str): | ||||
|     template = re.sub(r"\[context\]", context, template) | ||||
|     template = re.sub(r"\[query\]", query, template) | ||||
| 
 | ||||
|     template = template.replace("[context]", context) | ||||
|     template = template.replace("[query]", query) | ||||
|     return template | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -75,7 +75,7 @@ async def download_file_stream(url, file_path, file_name, chunk_size=1024 * 1024 | |||
|                     hashed = calculate_sha256(file) | ||||
|                     file.seek(0) | ||||
| 
 | ||||
|                     url = f"{OLLAMA_BASE_URLS[0]}/blobs/sha256:{hashed}" | ||||
|                     url = f"{OLLAMA_BASE_URLS[0]}/api/blobs/sha256:{hashed}" | ||||
|                     response = requests.post(url, data=file) | ||||
| 
 | ||||
|                     if response.ok: | ||||
|  |  | |||
|  | @ -52,3 +52,4 @@ class ERROR_MESSAGES(str, Enum): | |||
| 
 | ||||
|     MODEL_NOT_FOUND = lambda name="": f"Model '{name}' was not found" | ||||
|     OPENAI_NOT_FOUND = lambda name="": f"OpenAI API was not found" | ||||
|     OLLAMA_NOT_FOUND = "WebUI could not connect to Ollama" | ||||
|  |  | |||
							
								
								
									
										265
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										265
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							|  | @ -1,15 +1,16 @@ | |||
| { | ||||
| 	"name": "open-webui", | ||||
| 	"version": "0.1.110", | ||||
| 	"version": "0.1.112", | ||||
| 	"lockfileVersion": 2, | ||||
| 	"requires": true, | ||||
| 	"packages": { | ||||
| 		"": { | ||||
| 			"name": "open-webui", | ||||
| 			"version": "0.1.110", | ||||
| 			"version": "0.1.112", | ||||
| 			"dependencies": { | ||||
| 				"@sveltejs/adapter-node": "^1.3.1", | ||||
| 				"async": "^3.2.5", | ||||
| 				"bits-ui": "^0.19.7", | ||||
| 				"dayjs": "^1.11.10", | ||||
| 				"file-saver": "^2.0.5", | ||||
| 				"highlight.js": "^11.9.0", | ||||
|  | @ -517,9 +518,9 @@ | |||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@fastify/busboy": { | ||||
| 			"version": "2.0.0", | ||||
| 			"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", | ||||
| 			"integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", | ||||
| 			"version": "2.1.1", | ||||
| 			"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", | ||||
| 			"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", | ||||
| 			"engines": { | ||||
| 				"node": ">=14" | ||||
| 			} | ||||
|  | @ -536,6 +537,28 @@ | |||
| 				"node": ">=10.13.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@floating-ui/core": { | ||||
| 			"version": "1.6.0", | ||||
| 			"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", | ||||
| 			"integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", | ||||
| 			"dependencies": { | ||||
| 				"@floating-ui/utils": "^0.2.1" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@floating-ui/dom": { | ||||
| 			"version": "1.6.3", | ||||
| 			"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", | ||||
| 			"integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", | ||||
| 			"dependencies": { | ||||
| 				"@floating-ui/core": "^1.0.0", | ||||
| 				"@floating-ui/utils": "^0.2.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@floating-ui/utils": { | ||||
| 			"version": "0.2.1", | ||||
| 			"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", | ||||
| 			"integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" | ||||
| 		}, | ||||
| 		"node_modules/@humanwhocodes/config-array": { | ||||
| 			"version": "0.11.13", | ||||
| 			"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", | ||||
|  | @ -569,6 +592,14 @@ | |||
| 			"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"node_modules/@internationalized/date": { | ||||
| 			"version": "3.5.2", | ||||
| 			"resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.2.tgz", | ||||
| 			"integrity": "sha512-vo1yOMUt2hzp63IutEaTUxROdvQg1qlMRsbCvbay2AK2Gai7wIgCyK5weEX3nHkiLgo4qCXHijFNC/ILhlRpOQ==", | ||||
| 			"dependencies": { | ||||
| 				"@swc/helpers": "^0.5.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@jridgewell/gen-mapping": { | ||||
| 			"version": "0.3.3", | ||||
| 			"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", | ||||
|  | @ -612,6 +643,39 @@ | |||
| 				"@jridgewell/sourcemap-codec": "^1.4.14" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@melt-ui/svelte": { | ||||
| 			"version": "0.76.0", | ||||
| 			"resolved": "https://registry.npmjs.org/@melt-ui/svelte/-/svelte-0.76.0.tgz", | ||||
| 			"integrity": "sha512-X1ktxKujjLjOBt8LBvfckHGDMrkHWceRt1jdsUTf0EH76ikNPP1ofSoiV0IhlduDoCBV+2YchJ8kXCDfDXfC9Q==", | ||||
| 			"dependencies": { | ||||
| 				"@floating-ui/core": "^1.3.1", | ||||
| 				"@floating-ui/dom": "^1.4.5", | ||||
| 				"@internationalized/date": "^3.5.0", | ||||
| 				"dequal": "^2.0.3", | ||||
| 				"focus-trap": "^7.5.2", | ||||
| 				"nanoid": "^5.0.4" | ||||
| 			}, | ||||
| 			"peerDependencies": { | ||||
| 				"svelte": ">=3 <5" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@melt-ui/svelte/node_modules/nanoid": { | ||||
| 			"version": "5.0.6", | ||||
| 			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.6.tgz", | ||||
| 			"integrity": "sha512-rRq0eMHoGZxlvaFOUdK1Ev83Bd1IgzzR+WJ3IbDJ7QOSdAxYjlurSPqFs9s4lJg29RT6nPwizFtJhQS6V5xgiA==", | ||||
| 			"funding": [ | ||||
| 				{ | ||||
| 					"type": "github", | ||||
| 					"url": "https://github.com/sponsors/ai" | ||||
| 				} | ||||
| 			], | ||||
| 			"bin": { | ||||
| 				"nanoid": "bin/nanoid.js" | ||||
| 			}, | ||||
| 			"engines": { | ||||
| 				"node": "^18 || >=20" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@nodelib/fs.scandir": { | ||||
| 			"version": "2.1.5", | ||||
| 			"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", | ||||
|  | @ -851,9 +915,9 @@ | |||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@sveltejs/kit": { | ||||
| 			"version": "1.30.3", | ||||
| 			"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.30.3.tgz", | ||||
| 			"integrity": "sha512-0DzVXfU4h+tChFvoc8C61IqErCyskD4ydSIDjpKS2lYlEzIYrtYrY7juSqACFxqcvZAnOEXvSY+zZ8br0+ZMMg==", | ||||
| 			"version": "1.30.4", | ||||
| 			"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.30.4.tgz", | ||||
| 			"integrity": "sha512-JSQIQT6XvdchCRQEm7BABxPC56WP5RYVONAi+09S8tmzeP43fBsRlr95bFmsTQM2RHBldfgQk+jgdnsKI75daA==", | ||||
| 			"hasInstallScript": true, | ||||
| 			"dependencies": { | ||||
| 				"@sveltejs/vite-plugin-svelte": "^2.5.0", | ||||
|  | @ -868,7 +932,7 @@ | |||
| 				"set-cookie-parser": "^2.6.0", | ||||
| 				"sirv": "^2.0.2", | ||||
| 				"tiny-glob": "^0.2.9", | ||||
| 				"undici": "~5.26.2" | ||||
| 				"undici": "^5.28.3" | ||||
| 			}, | ||||
| 			"bin": { | ||||
| 				"svelte-kit": "svelte-kit.js" | ||||
|  | @ -918,6 +982,14 @@ | |||
| 				"vite": "^4.0.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@swc/helpers": { | ||||
| 			"version": "0.5.6", | ||||
| 			"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.6.tgz", | ||||
| 			"integrity": "sha512-aYX01Ke9hunpoCexYAgQucEpARGQ5w/cqHFrIR+e9gdKb1QWTsVJuTJ2ozQzIAxLyRQe/m+2RqzkyOOGiMKRQA==", | ||||
| 			"dependencies": { | ||||
| 				"tslib": "^2.4.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@tailwindcss/typography": { | ||||
| 			"version": "0.5.10", | ||||
| 			"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.10.tgz", | ||||
|  | @ -1450,6 +1522,36 @@ | |||
| 			"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"node_modules/bits-ui": { | ||||
| 			"version": "0.19.7", | ||||
| 			"resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-0.19.7.tgz", | ||||
| 			"integrity": "sha512-GHUpKvN7QyazhnZNkUy0lxg6W1M6KJHWSZ4a/UGCjPE6nQgk6vKbGysY67PkDtQMknZTZAzVoMj1Eic4IKeCRQ==", | ||||
| 			"dependencies": { | ||||
| 				"@internationalized/date": "^3.5.1", | ||||
| 				"@melt-ui/svelte": "0.76.0", | ||||
| 				"nanoid": "^5.0.5" | ||||
| 			}, | ||||
| 			"peerDependencies": { | ||||
| 				"svelte": "^4.0.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/bits-ui/node_modules/nanoid": { | ||||
| 			"version": "5.0.6", | ||||
| 			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.6.tgz", | ||||
| 			"integrity": "sha512-rRq0eMHoGZxlvaFOUdK1Ev83Bd1IgzzR+WJ3IbDJ7QOSdAxYjlurSPqFs9s4lJg29RT6nPwizFtJhQS6V5xgiA==", | ||||
| 			"funding": [ | ||||
| 				{ | ||||
| 					"type": "github", | ||||
| 					"url": "https://github.com/sponsors/ai" | ||||
| 				} | ||||
| 			], | ||||
| 			"bin": { | ||||
| 				"nanoid": "bin/nanoid.js" | ||||
| 			}, | ||||
| 			"engines": { | ||||
| 				"node": "^18 || >=20" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/brace-expansion": { | ||||
| 			"version": "1.1.11", | ||||
| 			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | ||||
|  | @ -2813,6 +2915,14 @@ | |||
| 			"integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"node_modules/focus-trap": { | ||||
| 			"version": "7.5.4", | ||||
| 			"resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz", | ||||
| 			"integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==", | ||||
| 			"dependencies": { | ||||
| 				"tabbable": "^6.2.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/fraction.js": { | ||||
| 			"version": "4.3.6", | ||||
| 			"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", | ||||
|  | @ -5031,6 +5141,11 @@ | |||
| 			"integrity": "sha512-0K91MEXFpBUaywiwSSkmKjnGcasG/rVBXFLJz5DrgGabpYD6N+3yZrfD6uUIfpuTu65DZLHi7N8CizHc07BPZA==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"node_modules/tabbable": { | ||||
| 			"version": "6.2.0", | ||||
| 			"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", | ||||
| 			"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" | ||||
| 		}, | ||||
| 		"node_modules/tailwindcss": { | ||||
| 			"version": "3.3.3", | ||||
| 			"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", | ||||
|  | @ -5222,8 +5337,7 @@ | |||
| 		"node_modules/tslib": { | ||||
| 			"version": "2.6.2", | ||||
| 			"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", | ||||
| 			"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", | ||||
| 			"dev": true | ||||
| 			"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" | ||||
| 		}, | ||||
| 		"node_modules/type-check": { | ||||
| 			"version": "0.4.0", | ||||
|  | @ -5276,9 +5390,9 @@ | |||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/undici": { | ||||
| 			"version": "5.26.4", | ||||
| 			"resolved": "https://registry.npmjs.org/undici/-/undici-5.26.4.tgz", | ||||
| 			"integrity": "sha512-OG+QOf0fTLtazL9P9X7yqWxQ+Z0395Wk6DSkyTxtaq3wQEjIroVe7Y4asCX/vcCxYpNGMnwz8F0qbRYUoaQVMw==", | ||||
| 			"version": "5.28.3", | ||||
| 			"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz", | ||||
| 			"integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==", | ||||
| 			"dependencies": { | ||||
| 				"@fastify/busboy": "^2.0.0" | ||||
| 			}, | ||||
|  | @ -5433,9 +5547,9 @@ | |||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/vite": { | ||||
| 			"version": "4.5.1", | ||||
| 			"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.1.tgz", | ||||
| 			"integrity": "sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==", | ||||
| 			"version": "4.5.2", | ||||
| 			"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz", | ||||
| 			"integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==", | ||||
| 			"dependencies": { | ||||
| 				"esbuild": "^0.18.10", | ||||
| 				"postcss": "^8.4.27", | ||||
|  | @ -5810,9 +5924,31 @@ | |||
| 			"dev": true | ||||
| 		}, | ||||
| 		"@fastify/busboy": { | ||||
| 			"version": "2.0.0", | ||||
| 			"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", | ||||
| 			"integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==" | ||||
| 			"version": "2.1.1", | ||||
| 			"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", | ||||
| 			"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==" | ||||
| 		}, | ||||
| 		"@floating-ui/core": { | ||||
| 			"version": "1.6.0", | ||||
| 			"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", | ||||
| 			"integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", | ||||
| 			"requires": { | ||||
| 				"@floating-ui/utils": "^0.2.1" | ||||
| 			} | ||||
| 		}, | ||||
| 		"@floating-ui/dom": { | ||||
| 			"version": "1.6.3", | ||||
| 			"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", | ||||
| 			"integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", | ||||
| 			"requires": { | ||||
| 				"@floating-ui/core": "^1.0.0", | ||||
| 				"@floating-ui/utils": "^0.2.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"@floating-ui/utils": { | ||||
| 			"version": "0.2.1", | ||||
| 			"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", | ||||
| 			"integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" | ||||
| 		}, | ||||
| 		"@gulpjs/to-absolute-glob": { | ||||
| 			"version": "4.0.0", | ||||
|  | @ -5846,6 +5982,14 @@ | |||
| 			"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"@internationalized/date": { | ||||
| 			"version": "3.5.2", | ||||
| 			"resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.2.tgz", | ||||
| 			"integrity": "sha512-vo1yOMUt2hzp63IutEaTUxROdvQg1qlMRsbCvbay2AK2Gai7wIgCyK5weEX3nHkiLgo4qCXHijFNC/ILhlRpOQ==", | ||||
| 			"requires": { | ||||
| 				"@swc/helpers": "^0.5.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"@jridgewell/gen-mapping": { | ||||
| 			"version": "0.3.3", | ||||
| 			"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", | ||||
|  | @ -5880,6 +6024,26 @@ | |||
| 				"@jridgewell/sourcemap-codec": "^1.4.14" | ||||
| 			} | ||||
| 		}, | ||||
| 		"@melt-ui/svelte": { | ||||
| 			"version": "0.76.0", | ||||
| 			"resolved": "https://registry.npmjs.org/@melt-ui/svelte/-/svelte-0.76.0.tgz", | ||||
| 			"integrity": "sha512-X1ktxKujjLjOBt8LBvfckHGDMrkHWceRt1jdsUTf0EH76ikNPP1ofSoiV0IhlduDoCBV+2YchJ8kXCDfDXfC9Q==", | ||||
| 			"requires": { | ||||
| 				"@floating-ui/core": "^1.3.1", | ||||
| 				"@floating-ui/dom": "^1.4.5", | ||||
| 				"@internationalized/date": "^3.5.0", | ||||
| 				"dequal": "^2.0.3", | ||||
| 				"focus-trap": "^7.5.2", | ||||
| 				"nanoid": "^5.0.4" | ||||
| 			}, | ||||
| 			"dependencies": { | ||||
| 				"nanoid": { | ||||
| 					"version": "5.0.6", | ||||
| 					"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.6.tgz", | ||||
| 					"integrity": "sha512-rRq0eMHoGZxlvaFOUdK1Ev83Bd1IgzzR+WJ3IbDJ7QOSdAxYjlurSPqFs9s4lJg29RT6nPwizFtJhQS6V5xgiA==" | ||||
| 				} | ||||
| 			} | ||||
| 		}, | ||||
| 		"@nodelib/fs.scandir": { | ||||
| 			"version": "2.1.5", | ||||
| 			"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", | ||||
|  | @ -6046,9 +6210,9 @@ | |||
| 			"requires": {} | ||||
| 		}, | ||||
| 		"@sveltejs/kit": { | ||||
| 			"version": "1.30.3", | ||||
| 			"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.30.3.tgz", | ||||
| 			"integrity": "sha512-0DzVXfU4h+tChFvoc8C61IqErCyskD4ydSIDjpKS2lYlEzIYrtYrY7juSqACFxqcvZAnOEXvSY+zZ8br0+ZMMg==", | ||||
| 			"version": "1.30.4", | ||||
| 			"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.30.4.tgz", | ||||
| 			"integrity": "sha512-JSQIQT6XvdchCRQEm7BABxPC56WP5RYVONAi+09S8tmzeP43fBsRlr95bFmsTQM2RHBldfgQk+jgdnsKI75daA==", | ||||
| 			"requires": { | ||||
| 				"@sveltejs/vite-plugin-svelte": "^2.5.0", | ||||
| 				"@types/cookie": "^0.5.1", | ||||
|  | @ -6062,7 +6226,7 @@ | |||
| 				"set-cookie-parser": "^2.6.0", | ||||
| 				"sirv": "^2.0.2", | ||||
| 				"tiny-glob": "^0.2.9", | ||||
| 				"undici": "~5.26.2" | ||||
| 				"undici": "^5.28.3" | ||||
| 			} | ||||
| 		}, | ||||
| 		"@sveltejs/vite-plugin-svelte": { | ||||
|  | @ -6087,6 +6251,14 @@ | |||
| 				"debug": "^4.3.4" | ||||
| 			} | ||||
| 		}, | ||||
| 		"@swc/helpers": { | ||||
| 			"version": "0.5.6", | ||||
| 			"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.6.tgz", | ||||
| 			"integrity": "sha512-aYX01Ke9hunpoCexYAgQucEpARGQ5w/cqHFrIR+e9gdKb1QWTsVJuTJ2ozQzIAxLyRQe/m+2RqzkyOOGiMKRQA==", | ||||
| 			"requires": { | ||||
| 				"tslib": "^2.4.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"@tailwindcss/typography": { | ||||
| 			"version": "0.5.10", | ||||
| 			"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.10.tgz", | ||||
|  | @ -6454,6 +6626,23 @@ | |||
| 			"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"bits-ui": { | ||||
| 			"version": "0.19.7", | ||||
| 			"resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-0.19.7.tgz", | ||||
| 			"integrity": "sha512-GHUpKvN7QyazhnZNkUy0lxg6W1M6KJHWSZ4a/UGCjPE6nQgk6vKbGysY67PkDtQMknZTZAzVoMj1Eic4IKeCRQ==", | ||||
| 			"requires": { | ||||
| 				"@internationalized/date": "^3.5.1", | ||||
| 				"@melt-ui/svelte": "0.76.0", | ||||
| 				"nanoid": "^5.0.5" | ||||
| 			}, | ||||
| 			"dependencies": { | ||||
| 				"nanoid": { | ||||
| 					"version": "5.0.6", | ||||
| 					"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.6.tgz", | ||||
| 					"integrity": "sha512-rRq0eMHoGZxlvaFOUdK1Ev83Bd1IgzzR+WJ3IbDJ7QOSdAxYjlurSPqFs9s4lJg29RT6nPwizFtJhQS6V5xgiA==" | ||||
| 				} | ||||
| 			} | ||||
| 		}, | ||||
| 		"brace-expansion": { | ||||
| 			"version": "1.1.11", | ||||
| 			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | ||||
|  | @ -7347,6 +7536,14 @@ | |||
| 			"integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"focus-trap": { | ||||
| 			"version": "7.5.4", | ||||
| 			"resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz", | ||||
| 			"integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==", | ||||
| 			"requires": { | ||||
| 				"tabbable": "^6.2.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"fraction.js": { | ||||
| 			"version": "4.3.6", | ||||
| 			"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", | ||||
|  | @ -8900,6 +9097,11 @@ | |||
| 			"integrity": "sha512-0K91MEXFpBUaywiwSSkmKjnGcasG/rVBXFLJz5DrgGabpYD6N+3yZrfD6uUIfpuTu65DZLHi7N8CizHc07BPZA==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"tabbable": { | ||||
| 			"version": "6.2.0", | ||||
| 			"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", | ||||
| 			"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" | ||||
| 		}, | ||||
| 		"tailwindcss": { | ||||
| 			"version": "3.3.3", | ||||
| 			"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", | ||||
|  | @ -9047,8 +9249,7 @@ | |||
| 		"tslib": { | ||||
| 			"version": "2.6.2", | ||||
| 			"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", | ||||
| 			"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", | ||||
| 			"dev": true | ||||
| 			"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" | ||||
| 		}, | ||||
| 		"type-check": { | ||||
| 			"version": "0.4.0", | ||||
|  | @ -9082,9 +9283,9 @@ | |||
| 			} | ||||
| 		}, | ||||
| 		"undici": { | ||||
| 			"version": "5.26.4", | ||||
| 			"resolved": "https://registry.npmjs.org/undici/-/undici-5.26.4.tgz", | ||||
| 			"integrity": "sha512-OG+QOf0fTLtazL9P9X7yqWxQ+Z0395Wk6DSkyTxtaq3wQEjIroVe7Y4asCX/vcCxYpNGMnwz8F0qbRYUoaQVMw==", | ||||
| 			"version": "5.28.3", | ||||
| 			"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz", | ||||
| 			"integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==", | ||||
| 			"requires": { | ||||
| 				"@fastify/busboy": "^2.0.0" | ||||
| 			} | ||||
|  | @ -9191,9 +9392,9 @@ | |||
| 			} | ||||
| 		}, | ||||
| 		"vite": { | ||||
| 			"version": "4.5.1", | ||||
| 			"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.1.tgz", | ||||
| 			"integrity": "sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==", | ||||
| 			"version": "4.5.2", | ||||
| 			"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz", | ||||
| 			"integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==", | ||||
| 			"requires": { | ||||
| 				"esbuild": "^0.18.10", | ||||
| 				"fsevents": "~2.3.2", | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| { | ||||
| 	"name": "open-webui", | ||||
| 	"version": "0.1.111", | ||||
| 	"version": "0.1.112", | ||||
| 	"private": true, | ||||
| 	"scripts": { | ||||
| 		"dev": "vite dev --host", | ||||
|  | @ -44,6 +44,7 @@ | |||
| 	"dependencies": { | ||||
| 		"@sveltejs/adapter-node": "^1.3.1", | ||||
| 		"async": "^3.2.5", | ||||
| 		"bits-ui": "^0.19.7", | ||||
| 		"dayjs": "^1.11.10", | ||||
| 		"file-saver": "^2.0.5", | ||||
| 		"highlight.js": "^11.9.0", | ||||
|  |  | |||
|  | @ -118,11 +118,13 @@ | |||
| 	class="flex flex-col h-full justify-between space-y-3 text-sm" | ||||
| 	on:submit|preventDefault={async () => { | ||||
| 		loading = true; | ||||
| 
 | ||||
| 		if (imageGenerationEngine === 'openai') { | ||||
| 			await updateOpenAIKey(localStorage.token, OPENAI_API_KEY); | ||||
| 		} | ||||
| 
 | ||||
| 		await updateDefaultImageGenerationModel(localStorage.token, selectedModel); | ||||
| 
 | ||||
| 		await updateDefaultImageGenerationModel(localStorage.token, selectedModel); | ||||
| 		await updateImageSize(localStorage.token, imageSize).catch((error) => { | ||||
| 			toast.error(error); | ||||
| 			return null; | ||||
|  |  | |||
							
								
								
									
										30
									
								
								src/lib/components/common/Dropdown.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/lib/components/common/Dropdown.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | |||
| <script lang="ts"> | ||||
| 	import { DropdownMenu } from 'bits-ui'; | ||||
| </script> | ||||
| 
 | ||||
| <DropdownMenu.Root> | ||||
| 	<DropdownMenu.Trigger> | ||||
| 		<slot /> | ||||
| 	</DropdownMenu.Trigger> | ||||
| 
 | ||||
| 	<slot name="content"> | ||||
| 		<DropdownMenu.Content | ||||
| 			class="w-full max-w-[130px] rounded-lg px-1 py-1.5 border border-gray-700 z-50 bg-gray-850 text-white" | ||||
| 			sideOffset={8} | ||||
| 			side="bottom" | ||||
| 			align="start" | ||||
| 		> | ||||
| 			<DropdownMenu.Item class="flex items-center px-3 py-2 text-sm  font-medium"> | ||||
| 				<div class="flex items-center">Profile</div> | ||||
| 			</DropdownMenu.Item> | ||||
| 
 | ||||
| 			<DropdownMenu.Item class="flex items-center px-3 py-2 text-sm  font-medium"> | ||||
| 				<div class="flex items-center">Profile</div> | ||||
| 			</DropdownMenu.Item> | ||||
| 
 | ||||
| 			<DropdownMenu.Item class="flex items-center px-3 py-2 text-sm  font-medium"> | ||||
| 				<div class="flex items-center">Profile</div> | ||||
| 			</DropdownMenu.Item> | ||||
| 		</DropdownMenu.Content> | ||||
| 	</slot> | ||||
| </DropdownMenu.Root> | ||||
							
								
								
									
										19
									
								
								src/lib/components/icons/GarbageBin.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/lib/components/icons/GarbageBin.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| <script lang="ts"> | ||||
| 	export let className = 'w-4 h-4'; | ||||
| 	export let strokeWidth = '1.5'; | ||||
| </script> | ||||
| 
 | ||||
| <svg | ||||
| 	xmlns="http://www.w3.org/2000/svg" | ||||
| 	fill="none" | ||||
| 	viewBox="0 0 24 24" | ||||
| 	stroke-width={strokeWidth} | ||||
| 	stroke="currentColor" | ||||
| 	class={className} | ||||
| > | ||||
| 	<path | ||||
| 		stroke-linecap="round" | ||||
| 		stroke-linejoin="round" | ||||
| 		d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" | ||||
| 	/> | ||||
| </svg> | ||||
							
								
								
									
										19
									
								
								src/lib/components/icons/Pencil.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/lib/components/icons/Pencil.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| <script lang="ts"> | ||||
| 	export let className = 'w-4 h-4'; | ||||
| 	export let strokeWidth = '1.5'; | ||||
| </script> | ||||
| 
 | ||||
| <svg | ||||
| 	xmlns="http://www.w3.org/2000/svg" | ||||
| 	fill="none" | ||||
| 	viewBox="0 0 24 24" | ||||
| 	stroke-width={strokeWidth} | ||||
| 	stroke="currentColor" | ||||
| 	class={className} | ||||
| > | ||||
| 	<path | ||||
| 		stroke-linecap="round" | ||||
| 		stroke-linejoin="round" | ||||
| 		d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125" | ||||
| 	/> | ||||
| </svg> | ||||
|  | @ -23,6 +23,8 @@ | |||
| 	import { slide } from 'svelte/transition'; | ||||
| 	import { WEBUI_BASE_URL } from '$lib/constants'; | ||||
| 	import Tooltip from '../common/Tooltip.svelte'; | ||||
| 	import Dropdown from '../common/Dropdown.svelte'; | ||||
| 	import ChatMenu from './Sidebar/ChatMenu.svelte'; | ||||
| 
 | ||||
| 	let show = false; | ||||
| 	let navElement; | ||||
|  | @ -30,6 +32,8 @@ | |||
| 	let title: string = 'UI'; | ||||
| 	let search = ''; | ||||
| 
 | ||||
| 	let selectedChatId = null; | ||||
| 
 | ||||
| 	let chatDeleteId = null; | ||||
| 	let chatTitleEditId = null; | ||||
| 	let chatTitle = ''; | ||||
|  | @ -85,7 +89,10 @@ | |||
| 		}); | ||||
| 
 | ||||
| 		if (res) { | ||||
| 			if ($chatId === id) { | ||||
| 				goto('/'); | ||||
| 			} | ||||
| 
 | ||||
| 			await chats.set(await getChatList(localStorage.token)); | ||||
| 		} | ||||
| 	}; | ||||
|  | @ -375,24 +382,27 @@ | |||
| 						return title.includes(query) || contentMatches; | ||||
| 					} | ||||
| 				}) as chat, i} | ||||
| 					<div class=" w-full pr-2 relative"> | ||||
| 					<div class=" w-full pr-2 relative group"> | ||||
| 						{#if chatTitleEditId === chat.id} | ||||
| 							<div | ||||
| 								class=" w-full flex justify-between rounded-xl px-3 py-2 hover:bg-gray-900 {chat.id === | ||||
| 								$chatId | ||||
| 								class=" w-full flex justify-between rounded-xl px-3 py-2 {chat.id === $chatId | ||||
| 									? 'bg-gray-900' | ||||
| 									: ''} transition whitespace-nowrap text-ellipsis" | ||||
| 									: chat.id === selectedChatId | ||||
| 									? 'bg-gray-950' | ||||
| 									: 'group-hover:bg-gray-950'}  whitespace-nowrap text-ellipsis" | ||||
| 							> | ||||
| 								<input bind:value={chatTitle} class=" bg-transparent w-full outline-none mr-10" /> | ||||
| 							</div> | ||||
| 						{:else} | ||||
| 							<a | ||||
| 								class=" w-full flex justify-between rounded-xl px-3 py-2 hover:bg-gray-900 {chat.id === | ||||
| 								$chatId | ||||
| 								class=" w-full flex justify-between rounded-xl px-3 py-2 {chat.id === $chatId | ||||
| 									? 'bg-gray-900' | ||||
| 									: ''} transition whitespace-nowrap text-ellipsis" | ||||
| 									: chat.id === selectedChatId | ||||
| 									? 'bg-gray-950' | ||||
| 									: 'group-hover:bg-gray-950'}  whitespace-nowrap text-ellipsis" | ||||
| 								href="/c/{chat.id}" | ||||
| 								on:click={() => { | ||||
| 									selectedChatId = chat.id; | ||||
| 									if (window.innerWidth < 1024) { | ||||
| 										show = false; | ||||
| 									} | ||||
|  | @ -400,21 +410,27 @@ | |||
| 								draggable="false" | ||||
| 							> | ||||
| 								<div class=" flex self-center flex-1 w-full"> | ||||
| 									<div | ||||
| 										class=" text-left self-center overflow-hidden {chat.id === $chatId | ||||
| 											? 'w-[160px]' | ||||
| 											: 'w-full'}  h-[20px]" | ||||
| 									> | ||||
| 									<div class=" text-left self-center overflow-hidden w-full h-[20px]"> | ||||
| 										{chat.title} | ||||
| 									</div> | ||||
| 								</div> | ||||
| 							</a> | ||||
| 						{/if} | ||||
| 
 | ||||
| 						{#if chat.id === $chatId} | ||||
| 							<div class=" absolute right-[22px] top-[10px]"> | ||||
| 						<div | ||||
| 							class=" | ||||
| 							 | ||||
| 							{chat.id === $chatId | ||||
| 								? ' from-gray-900' | ||||
| 								: chat.id === selectedChatId | ||||
| 								? 'from-gray-950' | ||||
| 								: 'invisible group-hover:visible from-gray-950'} | ||||
| 								absolute right-[10px] top-[10px] pr-2 pl-5 bg-gradient-to-l from-80% | ||||
| 								 | ||||
| 								  to-transparent" | ||||
| 						> | ||||
| 							{#if chatTitleEditId === chat.id} | ||||
| 									<div class="flex self-center space-x-1.5"> | ||||
| 								<div class="flex self-center space-x-1.5 z-10"> | ||||
| 									<button | ||||
| 										class=" self-center hover:text-white transition" | ||||
| 										on:click={() => { | ||||
|  | @ -456,7 +472,7 @@ | |||
| 									</button> | ||||
| 								</div> | ||||
| 							{:else if chatDeleteId === chat.id} | ||||
| 									<div class="flex self-center space-x-1.5"> | ||||
| 								<div class="flex self-center space-x-1.5 z-10"> | ||||
| 									<button | ||||
| 										class=" self-center hover:text-white transition" | ||||
| 										on:click={() => { | ||||
|  | @ -495,61 +511,38 @@ | |||
| 									</button> | ||||
| 								</div> | ||||
| 							{:else} | ||||
| 									<div class="flex self-center space-x-1.5"> | ||||
| 										<button | ||||
| 											id="delete-chat-button" | ||||
| 											class=" hidden" | ||||
| 											on:click={() => { | ||||
| 												deleteChat(chat.id); | ||||
| 											}} | ||||
| 										/> | ||||
| 										<button | ||||
| 											class=" self-center hover:text-white transition" | ||||
| 											on:click={() => { | ||||
| 								<div class="flex self-center space-x-1.5 z-10"> | ||||
| 									<ChatMenu | ||||
| 										renameHandler={() => { | ||||
| 											chatTitle = chat.title; | ||||
| 											chatTitleEditId = chat.id; | ||||
| 										}} | ||||
| 										deleteHandler={() => { | ||||
| 											chatDeleteId = chat.id; | ||||
| 										}} | ||||
| 									> | ||||
| 											<svg | ||||
| 												xmlns="http://www.w3.org/2000/svg" | ||||
| 												fill="none" | ||||
| 												viewBox="0 0 24 24" | ||||
| 												stroke-width="1.5" | ||||
| 												stroke="currentColor" | ||||
| 												class="w-4 h-4" | ||||
| 											> | ||||
| 												<path | ||||
| 													stroke-linecap="round" | ||||
| 													stroke-linejoin="round" | ||||
| 													d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125" | ||||
| 												/> | ||||
| 											</svg> | ||||
| 										</button> | ||||
| 										<button | ||||
| 											aria-label="Chat Menu" | ||||
| 											class=" self-center hover:text-white transition" | ||||
| 											on:click={() => { | ||||
| 												chatDeleteId = chat.id; | ||||
| 												selectedChatId = chat.id; | ||||
| 											}} | ||||
| 										> | ||||
| 											<svg | ||||
| 												xmlns="http://www.w3.org/2000/svg" | ||||
| 												fill="none" | ||||
| 												viewBox="0 0 24 24" | ||||
| 												stroke-width="1.5" | ||||
| 												stroke="currentColor" | ||||
| 												viewBox="0 0 16 16" | ||||
| 												fill="currentColor" | ||||
| 												class="w-4 h-4" | ||||
| 											> | ||||
| 												<path | ||||
| 													stroke-linecap="round" | ||||
| 													stroke-linejoin="round" | ||||
| 													d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" | ||||
| 													d="M2 8a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0ZM6.5 8a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0ZM12.5 6.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Z" | ||||
| 												/> | ||||
| 											</svg> | ||||
| 										</button> | ||||
| 									</ChatMenu> | ||||
| 								</div> | ||||
| 							{/if} | ||||
| 						</div> | ||||
| 						{/if} | ||||
| 					</div> | ||||
| 				{/each} | ||||
| 			</div> | ||||
|  |  | |||
							
								
								
									
										43
									
								
								src/lib/components/layout/Sidebar/ChatMenu.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/lib/components/layout/Sidebar/ChatMenu.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| <script lang="ts"> | ||||
| 	import { DropdownMenu } from 'bits-ui'; | ||||
| 
 | ||||
| 	import Dropdown from '$lib/components/common/Dropdown.svelte'; | ||||
| 	import GarbageBin from '$lib/components/icons/GarbageBin.svelte'; | ||||
| 	import Pencil from '$lib/components/icons/Pencil.svelte'; | ||||
| 
 | ||||
| 	export let renameHandler: Function; | ||||
| 	export let deleteHandler: Function; | ||||
| </script> | ||||
| 
 | ||||
| <Dropdown> | ||||
| 	<slot /> | ||||
| 
 | ||||
| 	<div slot="content"> | ||||
| 		<DropdownMenu.Content | ||||
| 			class="w-full max-w-[130px] rounded-lg px-1 py-1.5 border border-gray-700 z-50 bg-gray-850 text-white" | ||||
| 			sideOffset={8} | ||||
| 			side="bottom" | ||||
| 			align="start" | ||||
| 		> | ||||
| 			<DropdownMenu.Item | ||||
| 				class="flex gap-2 items-center px-3 py-2 text-sm  font-medium cursor-pointer" | ||||
| 				on:click={() => { | ||||
| 					renameHandler(); | ||||
| 				}} | ||||
| 			> | ||||
| 				<Pencil strokeWidth="2" /> | ||||
| 				<div class="flex items-center">Rename</div> | ||||
| 			</DropdownMenu.Item> | ||||
| 
 | ||||
| 			<DropdownMenu.Item | ||||
| 				class="flex  gap-2  items-center px-3 py-2 text-sm  font-medium cursor-pointer" | ||||
| 				on:click={() => { | ||||
| 					deleteHandler(); | ||||
| 				}} | ||||
| 			> | ||||
| 				<GarbageBin strokeWidth="2" /> | ||||
| 				<div class="flex items-center">Delete</div> | ||||
| 			</DropdownMenu.Item> | ||||
| 		</DropdownMenu.Content> | ||||
| 	</div> | ||||
| </Dropdown> | ||||
|  | @ -143,7 +143,9 @@ | |||
| 	}; | ||||
| 
 | ||||
| 	const scrollToBottom = () => { | ||||
| 		if (messagesContainerElement) { | ||||
| 			messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight; | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	////////////////////////// | ||||
|  | @ -313,7 +315,7 @@ | |||
| 					.map((file) => file.url.slice(file.url.indexOf(',') + 1)); | ||||
| 
 | ||||
| 				// Add images array only if it contains elements | ||||
| 				if (imageUrls && imageUrls.length > 0) { | ||||
| 				if (imageUrls && imageUrls.length > 0 && message.role === 'user') { | ||||
| 					baseMessage.images = imageUrls; | ||||
| 				} | ||||
| 
 | ||||
|  | @ -543,7 +545,8 @@ | |||
| 					.filter((message) => message) | ||||
| 					.map((message, idx, arr) => ({ | ||||
| 						role: message.role, | ||||
| 						...(message.files?.filter((file) => file.type === 'image').length > 0 ?? false | ||||
| 						...((message.files?.filter((file) => file.type === 'image').length > 0 ?? false) && | ||||
| 						message.role === 'user' | ||||
| 							? { | ||||
| 									content: [ | ||||
| 										{ | ||||
|  |  | |||
|  | @ -162,7 +162,9 @@ | |||
| 	}; | ||||
| 
 | ||||
| 	const scrollToBottom = () => { | ||||
| 		if (messagesContainerElement) { | ||||
| 			messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight; | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	////////////////////////// | ||||
|  | @ -323,7 +325,7 @@ | |||
| 					.map((file) => file.url.slice(file.url.indexOf(',') + 1)); | ||||
| 
 | ||||
| 				// Add images array only if it contains elements | ||||
| 				if (imageUrls && imageUrls.length > 0) { | ||||
| 				if (imageUrls && imageUrls.length > 0 && message.role === 'user') { | ||||
| 					baseMessage.images = imageUrls; | ||||
| 				} | ||||
| 
 | ||||
|  | @ -553,7 +555,8 @@ | |||
| 					.filter((message) => message) | ||||
| 					.map((message, idx, arr) => ({ | ||||
| 						role: message.role, | ||||
| 						...(message.files?.filter((file) => file.type === 'image').length > 0 ?? false | ||||
| 						...((message.files?.filter((file) => file.type === 'image').length > 0 ?? false) && | ||||
| 						message.role === 'user' | ||||
| 							? { | ||||
| 									content: [ | ||||
| 										{ | ||||
|  | @ -702,8 +705,13 @@ | |||
| 
 | ||||
| 		if (messages.length == 2) { | ||||
| 			window.history.replaceState(history.state, '', `/c/${_chatId}`); | ||||
| 
 | ||||
| 			if ($settings?.titleAutoGenerateModel) { | ||||
| 				await generateChatTitle(_chatId, userPrompt); | ||||
| 			} else { | ||||
| 				await setChatTitle(_chatId, userPrompt); | ||||
| 			} | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	const stopResponse = () => { | ||||
|  |  | |||
|  | @ -3,16 +3,13 @@ | |||
| @tailwind utilities; | ||||
| 
 | ||||
| @layer base { | ||||
| 	html { | ||||
| 	html, pre { | ||||
| 		font-family: -apple-system, 'Arimo', ui-sans-serif, system-ui, 'Segoe UI', Roboto, Ubuntu, | ||||
| 			Cantarell, 'Noto Sans', sans-serif, 'Helvetica Neue', Arial, 'Apple Color Emoji', | ||||
| 			'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; | ||||
| 	} | ||||
| 
 | ||||
|   pre { | ||||
| 		font-family: -apple-system, 'Arimo', ui-sans-serif, system-ui, 'Segoe UI', Roboto, Ubuntu, | ||||
| 			Cantarell, 'Noto Sans', sans-serif, 'Helvetica Neue', Arial, 'Apple Color Emoji', | ||||
| 			'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; | ||||
|     white-space: pre-wrap; | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue