diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e3e331ba..76939def1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ 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.3.19] - 2024-09-05 + +### Added + +- **🌐 Translation Update**: Improved Chinese translations. + +### Fixed + +- **📂 DATA_DIR Overriding**: Fixed an issue to avoid overriding DATA_DIR, preventing errors when directories are set identically, ensuring smoother operation and data management. +- **🛠️ Frontmatter Extraction**: Fixed the extraction process for frontmatter in tools and functions. + +### Changed + +- **🎨 UI Styling**: Refined the user interface styling for enhanced visual coherence and user experience. + ## [0.3.18] - 2024-09-04 ### Added diff --git a/backend/open_webui/apps/webui/main.py b/backend/open_webui/apps/webui/main.py index 074b3144c..45fe3cad9 100644 --- a/backend/open_webui/apps/webui/main.py +++ b/backend/open_webui/apps/webui/main.py @@ -152,29 +152,33 @@ async def get_pipe_models(): # Check if function is a manifold if hasattr(function_module, "pipes"): - manifold_pipes = [] + sub_pipes = [] # Check if pipes is a function or a list - if callable(function_module.pipes): - manifold_pipes = function_module.pipes() - else: - manifold_pipes = function_module.pipes - for p in manifold_pipes: - manifold_pipe_id = f'{pipe.id}.{p["id"]}' - manifold_pipe_name = p["name"] + try: + if callable(function_module.pipes): + sub_pipes = function_module.pipes() + else: + sub_pipes = function_module.pipes + except Exception as e: + log.exception(e) + sub_pipes = [] + + print(sub_pipes) + + for p in sub_pipes: + sub_pipe_id = f'{pipe.id}.{p["id"]}' + sub_pipe_name = p["name"] if hasattr(function_module, "name"): - manifold_pipe_name = f"{function_module.name}{manifold_pipe_name}" + sub_pipe_name = f"{function_module.name}{sub_pipe_name}" pipe_flag = {"type": pipe.type} - if hasattr(function_module, "ChatValves"): - pipe_flag["valves_spec"] = function_module.ChatValves.schema() - pipe_models.append( { - "id": manifold_pipe_id, - "name": manifold_pipe_name, + "id": sub_pipe_id, + "name": sub_pipe_name, "object": "model", "created": pipe.created_at, "owned_by": "openai", @@ -183,8 +187,6 @@ async def get_pipe_models(): ) else: pipe_flag = {"type": "pipe"} - if hasattr(function_module, "ChatValves"): - pipe_flag["valves_spec"] = function_module.ChatValves.schema() pipe_models.append( { diff --git a/backend/open_webui/apps/webui/utils.py b/backend/open_webui/apps/webui/utils.py index bdcd05bb3..2b017bf43 100644 --- a/backend/open_webui/apps/webui/utils.py +++ b/backend/open_webui/apps/webui/utils.py @@ -11,9 +11,9 @@ from open_webui.apps.webui.models.tools import Tools from open_webui.config import FUNCTIONS_DIR, TOOLS_DIR -def extract_frontmatter(file_path): +def extract_frontmatter(content): """ - Extract frontmatter as a dictionary from the specified file path. + Extract frontmatter as a dictionary from the provided content string. """ frontmatter = {} frontmatter_started = False @@ -21,29 +21,25 @@ def extract_frontmatter(file_path): frontmatter_pattern = re.compile(r"^\s*([a-z_]+):\s*(.*)\s*$", re.IGNORECASE) try: - with open(file_path, "r", encoding="utf-8") as file: - first_line = file.readline() - if first_line.strip() != '"""': - # The file doesn't start with triple quotes - return {} + lines = content.splitlines() + if len(lines) < 1 or lines[0].strip() != '"""': + # The content doesn't start with triple quotes + return {} - frontmatter_started = True + frontmatter_started = True - for line in file: - if '"""' in line: - if frontmatter_started: - frontmatter_ended = True - break + for line in lines[1:]: + if '"""' in line: + if frontmatter_started: + frontmatter_ended = True + break - if frontmatter_started and not frontmatter_ended: - match = frontmatter_pattern.match(line) - if match: - key, value = match.groups() - frontmatter[key.strip()] = value.strip() + if frontmatter_started and not frontmatter_ended: + match = frontmatter_pattern.match(line) + if match: + key, value = match.groups() + frontmatter[key.strip()] = value.strip() - except FileNotFoundError: - print(f"Error: The file {file_path} does not exist.") - return {} except Exception as e: print(f"An error occurred: {e}") return {} diff --git a/package-lock.json b/package-lock.json index 320223a4e..dc39b8a62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "open-webui", - "version": "0.3.18", + "version": "0.3.19", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "open-webui", - "version": "0.3.18", + "version": "0.3.19", "dependencies": { "@codemirror/lang-javascript": "^6.2.2", "@codemirror/lang-python": "^6.1.6", diff --git a/package.json b/package.json index 838c5b155..bfa1334f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-webui", - "version": "0.3.18", + "version": "0.3.19", "private": true, "scripts": { "dev": "npm run pyodide:fetch && vite dev --host", diff --git a/src/lib/components/chat/ChatControls.svelte b/src/lib/components/chat/ChatControls.svelte index 869c8459c..6e96d3831 100644 --- a/src/lib/components/chat/ChatControls.svelte +++ b/src/lib/components/chat/ChatControls.svelte @@ -5,6 +5,7 @@ import { onMount } from 'svelte'; import { mobile, showCallOverlay } from '$lib/stores'; import CallOverlay from './MessageInput/CallOverlay.svelte'; + import Drawer from '../common/Drawer.svelte'; export let show = false; @@ -43,65 +44,60 @@ }); -{#if largeScreen} +{#if !largeScreen} {#if show} -
-
-
- {#if $showCallOverlay} - - {:else} - { - show = false; - }} - {models} - bind:chatFiles - bind:params - /> - {/if} -
+ +
+ { + show = false; + }} + {models} + bind:chatFiles + bind:params + /> +
+
+ {/if} + + {#if $showCallOverlay} +
+
+ { + show = false; + }} + />
{/if} -{:else if $showCallOverlay} -
-
- { - show = false; - }} - /> +{:else if show} +
+
+
+ {#if $showCallOverlay} + + {:else} + { + show = false; + }} + {models} + bind:chatFiles + bind:params + /> + {/if} +
-{:else} - -
- { - show = false; - }} - {models} - bind:chatFiles - bind:params - /> -
-
{/if} diff --git a/src/lib/components/chat/Messages/Placeholder.svelte b/src/lib/components/chat/Messages/Placeholder.svelte index 15ea8576a..51cc7c9eb 100644 --- a/src/lib/components/chat/Messages/Placeholder.svelte +++ b/src/lib/components/chat/Messages/Placeholder.svelte @@ -34,9 +34,9 @@ {#key mounted} -
+
-
+
{#each models as model, modelIdx}
{#if selectedModelIdx === 0} -
+
{:else} -
+
-{#if showSetDefault && !$mobile} -
+{#if showSetDefault} +
{/if} diff --git a/src/lib/components/chat/ModelSelector/Selector.svelte b/src/lib/components/chat/ModelSelector/Selector.svelte index 10f5092ae..34ffb9bb2 100644 --- a/src/lib/components/chat/ModelSelector/Selector.svelte +++ b/src/lib/components/chat/ModelSelector/Selector.svelte @@ -302,7 +302,7 @@ >
{#if $mobile && (item?.model?.info?.meta?.tags ?? []).length > 0} -
+
{#each item.model?.info?.meta.tags as tag}
{#if value === item.value} -
+
{/if} diff --git a/src/lib/components/common/Drawer.svelte b/src/lib/components/common/Drawer.svelte new file mode 100644 index 000000000..e638f0f07 --- /dev/null +++ b/src/lib/components/common/Drawer.svelte @@ -0,0 +1,94 @@ + + + + + + + + diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte index cbc82e7d9..168f7eaf2 100644 --- a/src/lib/components/layout/Sidebar.svelte +++ b/src/lib/components/layout/Sidebar.svelte @@ -261,7 +261,7 @@ id="sidebar" class="h-screen max-h-[100dvh] min-h-screen select-none {$showSidebar ? 'md:relative w-[260px]' - : '-translate-x-[260px] w-[0px]'} bg-gray-50 text-gray-900 dark:bg-gray-950 dark:text-gray-200 text-sm transition fixed z-50 top-0 left-0 rounded-r-2xl + : '-translate-x-[260px] w-[0px]'} bg-gray-50 text-gray-900 dark:bg-gray-950 dark:text-gray-200 text-sm transition fixed z-50 top-0 left-0 " data-state={$showSidebar} > @@ -273,7 +273,7 @@
{ diff --git a/src/lib/i18n/locales/zh-CN/translation.json b/src/lib/i18n/locales/zh-CN/translation.json index 9cdbdfa95..05ab8802d 100644 --- a/src/lib/i18n/locales/zh-CN/translation.json +++ b/src/lib/i18n/locales/zh-CN/translation.json @@ -248,8 +248,8 @@ "Enter model tag (e.g. {{modelTag}})": "输入模型标签 (例如:{{modelTag}})", "Enter Number of Steps (e.g. 50)": "输入步骤数 (Steps) (例如:50)", "Enter Score": "输入评分", - "Enter SearchApi API Key": "", - "Enter SearchApi Engine": "", + "Enter SearchApi API Key": "输入 SearchApi API 密钥", + "Enter SearchApi Engine": "输入 SearchApi 引擎", "Enter Searxng Query URL": "输入 Searxng 查询地址", "Enter Serper API Key": "输入 Serper API 密钥", "Enter Serply API Key": "输入 Serply API 密钥", @@ -272,7 +272,7 @@ "Export All Chats (All Users)": "导出所有用户对话", "Export chat (.json)": "JSON 文件 (.json)", "Export Chats": "导出对话", - "Export Config to JSON File": "", + "Export Config to JSON File": "导出配置信息至 JSON 文件中", "Export Documents Mapping": "导出文档映射", "Export Functions": "导出函数", "Export LiteLLM config.yaml": "导出 LteLLM config.yaml 文件", @@ -337,7 +337,7 @@ "Image Settings": "图像设置", "Images": "图像", "Import Chats": "导入对话记录", - "Import Config from JSON File": "", + "Import Config from JSON File": "导入 JSON 文件中的配置信息", "Import Documents Mapping": "导入文档映射", "Import Functions": "导入函数", "Import Models": "导入模型", @@ -541,8 +541,8 @@ "Search Query Generation Prompt Length Threshold": "搜索查询生成提示长度阈值", "Search Result Count": "搜索结果数量", "Search Tools": "搜索工具", - "SearchApi API Key": "", - "SearchApi Engine": "", + "SearchApi API Key": "SearchApi API 密钥", + "SearchApi Engine": "SearchApi 引擎", "Searched {{count}} sites_other": "搜索到 {{count}} 个结果", "Searching \"{{searchQuery}}\"": "搜索 \"{{searchQuery}}\" 中", "Searching Knowledge for \"{{searchQuery}}\"": "检索有关 \"{{searchQuery}}\" 的知识中",