diff --git a/.agent/workflows/plugin-development.md b/.agent/workflows/plugin-development.md index 31d4ca5..3eee058 100644 --- a/.agent/workflows/plugin-development.md +++ b/.agent/workflows/plugin-development.md @@ -12,11 +12,11 @@ Reference: `.github/copilot-instructions.md` ### Bilingual Requirement -Every plugin **MUST** have bilingual versions for both code and documentation: +Every plugin **MUST** have a single internationalized code file and bilingual documentation: -- **Code**: - - English: `plugins/{type}/{name}/{name}.py` - - Chinese: `plugins/{type}/{name}/{name_cn}.py` (or `中文名.py`) +- **Code (i18n)**: + - `plugins/{type}/{name}/{name}.py` + - The single `.py` file must implement internal i18n (e.g., using `navigator.language` or backend headers) to support multiple languages natively, rather than splitting into separate files. - **README**: - English: `plugins/{type}/{name}/README.md` - Chinese: `plugins/{type}/{name}/README_CN.md` @@ -81,14 +81,13 @@ Reference: `.github/workflows/release.yml` - **Release Information Compliance**: When a release is requested, the agent must generate a standard release summary (English commit title + bilingual bullet points) as defined in Section 3 & 5. - **Default Action (Prepare Only)**: When performing a version bump or update, the agent should update all files locally but **STOP** before committing. Present the changes and the **proposed Release/Commit Message** to the user and wait for explicit confirmation to commit/push. - **Consistency**: When bumping, update version in **ALL** locations: - 1. English Code (`.py`) - 2. Chinese Code (`.py`) - 3. English README (`README.md`) - 4. Chinese README (`README_CN.md`) - 5. Docs Index (`docs/.../index.md`) - 6. Docs Index CN (`docs/.../index.zh.md`) - 7. Docs Detail (`docs/.../{name}.md`) - 8. Docs Detail CN (`docs/.../{name}.zh.md`) + 1. Code (`.py`) + 2. English README (`README.md`) + 3. Chinese README (`README_CN.md`) + 4. Docs Index (`docs/.../index.md`) + 5. Docs Index CN (`docs/.../index.zh.md`) + 6. Docs Detail (`docs/.../{name}.md`) + 7. Docs Detail CN (`docs/.../{name}.zh.md`) ### Automated Release Process @@ -120,7 +119,7 @@ When the user confirms a release, the agent **MUST** follow these content standa - Before committing, present a "Release Draft" containing: - **Title**: e.g., `Release v0.1.1: [Plugin Name] - [Brief Summary]` - **Changelog**: English-only list of commits since the last release, including hashes (e.g., `896de02 docs(config): reorder antigravity model alias example`). - - **Verification Status**: Confirm all 8+ files have been updated and synced. + - **Verification Status**: Confirm all 7+ files have been updated and synced. 3. **Internal Documentation**: Ensure "What's New" sections in READMEs and `docs/` match exactly the changes being released. ### Pull Request Check @@ -134,7 +133,7 @@ When the user confirms a release, the agent **MUST** follow these content standa Before committing: -- [ ] Code is bilingual and functional? +- [ ] Code is internal i18n supported (`.py`) and fully functional? - [ ] Docstrings have updated version? - [ ] READMEs are updated and bilingual? - [ ] **Key Capabilities** in READMEs still cover all legacy core features + new features? diff --git a/.git-worktrees/feature-copilot-cli b/.git-worktrees/feature-copilot-cli new file mode 160000 index 0000000..1bbddb2 --- /dev/null +++ b/.git-worktrees/feature-copilot-cli @@ -0,0 +1 @@ +Subproject commit 1bbddb2222969f3ac72a7f5e51fb55c352c5569f diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index c9d8afb..2012c4e 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -8,27 +8,26 @@ This document defines the standard conventions and best practices for OpenWebUI ## 🏗️ 项目结构与命名 (Project Structure & Naming) -### 1. 双语版本要求 (Bilingual Version Requirements) +### 1. 语言与代码规范 (Language & Code Requirements) #### 插件代码 (Plugin Code) -每个插件必须提供两个版本: +每个插件**必须**采用单文件国际化 (i18n) 设计。严禁为不同语言创建独立的源代码文件(如 `_cn.py`)。 -1. **英文版本**: `plugin_name.py` - 英文界面、提示词和注释 -2. **中文版本**: `plugin_name_cn.py` - 中文界面、提示词和注释 +1. **单代码文件**: `plugins/{type}/{name}/{name}.py` +2. **内置 i18n**: 必须在代码中根据前端传来的用户语言(如 `__user__` 中的 `language` 或通过 `get_user_language` 脚本读取)动态切换界面显示、提示词和状态日志。 -示例: +示例目录结构: ``` plugins/actions/export_to_docx/ -├── export_to_word.py # English version -├── export_to_word_cn.py # Chinese version -├── README.md # English documentation -└── README_CN.md # Chinese documentation +├── export_to_word.py # 单个代码文件,内置多语言支持 +├── README.md # 英文文档 (English documentation) +└── README_CN.md # 中文文档 ``` #### 文档 (Documentation) -每个插件目录必须包含双语 README 文件: +尽管代码是合一的,但为了市场展示和 SEO,每个插件目录仍**必须**包含双语 README 文件: - `README.md` - English documentation - `README_CN.md` - 中文文档 @@ -58,12 +57,10 @@ plugins/actions/export_to_docx/ plugins/ ├── actions/ # Action 插件 (用户触发的功能) │ ├── my_action/ -│ │ ├── my_action.py # English version -│ │ ├── 我的动作.py # Chinese version +│ │ ├── my_action.py # 单文件,内置 i18n │ │ ├── README.md # English documentation │ │ └── README_CN.md # Chinese documentation -│ ├── ACTION_PLUGIN_TEMPLATE.py # English template -│ ├── ACTION_PLUGIN_TEMPLATE_CN.py # Chinese template +│ ├── ACTION_PLUGIN_TEMPLATE.py # 通用 i18n 模板 │ └── README.md ├── filters/ # Filter 插件 (输入处理) │ └── ... @@ -474,7 +471,7 @@ async def get_user_language(self): #### 适用场景与引导 (Usage Guidelines) -- **语言适配**: 动态获取界面语言 (`ru-RU`, `zh-CN`) 自动切换输出语言。 +- **语言适配**: 动态获取界面语言 (`ru-RU`, `zh-CN`) 自动切换输出语言和 UI 翻译。这对于单文件 i18n 插件至关重要。 - **时区处理**: 获取 `Intl.DateTimeFormat().resolvedOptions().timeZone` 处理时间。 - **客户端存储**: 读取 `localStorage` 中的用户偏好设置。 - **硬件能力**: 获取 `navigator.clipboard` 或 `navigator.geolocation` (需授权)。 @@ -932,8 +929,7 @@ Filter 实例是**单例 (Singleton)**。 ### 1. ✅ 开发检查清单 (Development Checklist) -- [ ] 创建英文版插件代码 (`plugin_name.py`) -- [ ] 创建中文版插件代码 (`plugin_name_cn.py`) +- [ ] 代码实现了内置 i18n 逻辑 (`.py`) - [ ] 编写英文 README (`README.md`) - [ ] 编写中文 README (`README_CN.md`) - [ ] 包含标准化文档字符串 @@ -941,7 +937,7 @@ Filter 实例是**单例 (Singleton)**。 - [ ] 使用 Lucide 图标 - [ ] 实现 Valves 配置 - [ ] 使用 logging 而非 print -- [ ] 测试双语界面 +- [ ] 测试 i18n 界面适配 - [ ] **一致性检查**: 确保文档、代码、README 同步 - [ ] **README 结构**: - **Key Capabilities** (英文) / **核心功能** (中文): 必须包含所有核心功能 @@ -988,7 +984,7 @@ Filter 实例是**单例 (Singleton)**。 2. **变更列表 (Bilingual Changes)**: - 英文: Clear descriptions of technical/functional changes. - 中文: 清晰描述用户可见的功能改进或修复。 -3. **核查状态 (Verification)**: 确认版本号已在相关 8+ 处位置同步更新。 +3. **核查状态 (Verification)**: 确认版本号已在相关 7+ 处位置同步更新(1 个代码文件 + 2 个 README + 4 个 Docs 文件)。 ### 4. 🤖 Git 提交与推送规范 (Git Operations & Push Rules) @@ -1004,8 +1000,7 @@ Filter 实例是**单例 (Singleton)**。 ## 📚 参考资源 (Reference Resources) -- [Action 插件模板 (英文)](plugins/actions/ACTION_PLUGIN_TEMPLATE.py) -- [Action 插件模板 (中文)](plugins/actions/ACTION_PLUGIN_TEMPLATE_CN.py) +- [Action 插件模板](plugins/actions/ACTION_PLUGIN_TEMPLATE.py) - [插件开发指南](plugins/actions/PLUGIN_DEVELOPMENT_GUIDE.md) - [Lucide Icons](https://lucide.dev/icons/) - [OpenWebUI 文档](https://docs.openwebui.com/) diff --git a/docs/plugins/actions/index.md b/docs/plugins/actions/index.md index 676195c..48e5d38 100644 --- a/docs/plugins/actions/index.md +++ b/docs/plugins/actions/index.md @@ -23,7 +23,7 @@ Actions are interactive plugins that: Intelligently analyzes text content and generates interactive mind maps with beautiful visualizations. - **Version:** 0.9.2 + **Version:** 1.0.0 [:octicons-arrow-right-24: Documentation](smart-mind-map.md) diff --git a/docs/plugins/actions/index.zh.md b/docs/plugins/actions/index.zh.md index d41ab5b..708f17b 100644 --- a/docs/plugins/actions/index.zh.md +++ b/docs/plugins/actions/index.zh.md @@ -23,7 +23,7 @@ Actions 是交互式插件,能够: 智能分析文本并生成交互式、精美的思维导图。 - **版本:** 0.8.0 + **版本:** 1.0.0 [:octicons-arrow-right-24: 查看文档](smart-mind-map.md) diff --git a/docs/plugins/actions/smart-mind-map.md b/docs/plugins/actions/smart-mind-map.md index f175ec3..7de5ed6 100644 --- a/docs/plugins/actions/smart-mind-map.md +++ b/docs/plugins/actions/smart-mind-map.md @@ -1,7 +1,7 @@ # Smart Mind Map Action -v0.9.2 +v1.0.0 Intelligently analyzes text content and generates interactive mind maps for better visualization and understanding. @@ -17,7 +17,8 @@ The Smart Mind Map plugin transforms text content into beautiful, interactive mi - :material-gesture-swipe: **Rich Controls**: Zoom, reset view, expand level selector (All/2/3) and fullscreen - :material-palette: **Theme Aware**: Auto-detects OpenWebUI light/dark theme with manual toggle - :material-download: **One-Click Export**: Download high-res PNG, copy SVG, or copy Markdown source -- :material-translate: **Multi-language**: Matches output language to the input text +- :material-translate: **i18n Embedded**: One code file smartly detects frontend languages and translates the output. +- :material-arrow-all: **Auto-Sizing & Direct Embed**: Seamlessly scales to display massive canvas inline (requires setting toggle). --- @@ -50,6 +51,7 @@ The Smart Mind Map plugin transforms text content into beautiful, interactive mi | `MIN_TEXT_LENGTH` | integer | `100` | Minimum characters required before analysis runs | | `CLEAR_PREVIOUS_HTML` | boolean | `false` | Clear previous plugin HTML instead of merging | | `MESSAGE_COUNT` | integer | `1` | Number of recent messages to include (1–5) | +| `ENABLE_DIRECT_EMBED_MODE` | boolean | `false` | Enable inline full-width UI for OpenWebUI 0.8.0+ | --- diff --git a/docs/plugins/actions/smart-mind-map.zh.md b/docs/plugins/actions/smart-mind-map.zh.md index eaf2498..48d4824 100644 --- a/docs/plugins/actions/smart-mind-map.zh.md +++ b/docs/plugins/actions/smart-mind-map.zh.md @@ -1,7 +1,7 @@ # Smart Mind Map(智能思维导图) Action -v0.9.2 +v1.0.0 智能分析文本内容,生成交互式思维导图,帮助你更直观地理解信息结构。 @@ -17,7 +17,8 @@ Smart Mind Map 会将文本转换成漂亮的交互式思维导图。插件会 - :material-gesture-swipe: **丰富控制**:缩放/重置、展开层级(全部/2/3 级)与全屏 - :material-palette: **主题感知**:自动检测 OpenWebUI 亮/暗色主题并支持手动切换 - :material-download: **一键导出**:下载高分辨率 PNG、复制 SVG 或 Markdown -- :material-translate: **多语言**:输出语言与输入文本一致 +- :material-translate: **内置 i18n 语言识别**:单个文件自动检测控制台前端语言,无需繁杂的各种语言包版本。 +- :material-arrow-all: **直出全屏版体验 (需配置开启)**:新版直出渲染抛开沙盒限制,纵情铺满屏幕,享受原生的图表体验。 --- @@ -50,6 +51,7 @@ Smart Mind Map 会将文本转换成漂亮的交互式思维导图。插件会 | `MIN_TEXT_LENGTH` | integer | `100` | 开始分析所需的最少字符数 | | `CLEAR_PREVIOUS_HTML` | boolean | `false` | 生成新导图时是否清除之前的插件 HTML | | `MESSAGE_COUNT` | integer | `1` | 用于生成的最近消息数量(1–5) | +| `ENABLE_DIRECT_EMBED_MODE` | boolean | `false` | 是否开启沉浸式直出模式 (需要 Open WebUI 0.8.0+ ) | --- diff --git a/plugins/actions/smart-mind-map/README.md b/plugins/actions/smart-mind-map/README.md index 7c08a3b..2b18b03 100644 --- a/plugins/actions/smart-mind-map/README.md +++ b/plugins/actions/smart-mind-map/README.md @@ -2,21 +2,26 @@ Smart Mind Map is a powerful OpenWebUI action plugin that intelligently analyzes long-form text content and automatically generates interactive mind maps, helping users structure and visualize knowledge. -**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** 0.9.2 | **Project:** [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) | **License:** MIT +**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** 1.0.0 | **Project:** [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) | **License:** MIT -## What's New in v0.9.2 +## What's New in v1.0.0 -**Language Rule Alignment** +### Direct Embed & UI Refinements -- **Input Language First**: Mind map output now strictly matches the input text language. -- **Consistent Behavior**: Matches the infographic language rule for predictable multilingual output. +- **Native Multi-language UI (i18n)**: The plugin interface (buttons, settings, status) now automatically adapts to your browser's language setting for a seamless global experience. +- **Direct Embed Mode**: Introduced a native-like inline display mode for Open WebUI 0.8.0+, enabling a seamless full-width canvas. +- **Adaptive Auto-Sizing**: Mind map now dynamically scales its height and perfectly refits to the window to eliminate scrollbar artifacts. +- **Subdued & Compact UI**: Completely redesigned the header tooling bar to a slender, single-line configuration to maximize visual rendering space. +- **Configurable Experience**: Added `ENABLE_DIRECT_EMBED_MODE` valve to explicitly toggle the new inline rendering behavior. ## Key Features 🔑 - ✅ **Intelligent Text Analysis**: Automatically identifies core themes, key concepts, and hierarchical structures. +- ✅ **Native Multi-language UI**: Automatic interface translation (i18n) based on system language for a native feel. - ✅ **Interactive Visualization**: Generates beautiful interactive mind maps based on Markmap.js. +- ✅ **Direct Embed Mode**: (Optional) For Open WebUI 0.8.0+, render natively inline to fill entire UI width. - ✅ **High-Resolution PNG Export**: Export mind maps as high-quality PNG images (9x scale). -- ✅ **Complete Control Panel**: Zoom controls, expand level selection, and fullscreen mode. +- ✅ **Complete Control Panel**: Zoom controls, expand level selection, and fullscreen mode within a compact toolbar. - ✅ **Theme Switching**: Manual theme toggle button with automatic theme detection. - ✅ **Image Output Mode**: Generate static SVG images embedded directly in Markdown for cleaner history. @@ -37,6 +42,7 @@ Smart Mind Map is a powerful OpenWebUI action plugin that intelligently analyzes | `CLEAR_PREVIOUS_HTML` | `false` | Whether to clear previous plugin-generated HTML content. | | `MESSAGE_COUNT` | `1` | Number of recent messages to use for generation (1-5). | | `OUTPUT_MODE` | `html` | Output mode: `html` (interactive) or `image` (static). | +| `ENABLE_DIRECT_EMBED_MODE` | `false` | Enable Direct Embed Mode (Open WebUI 0.8.0+ native layout) instead of Legacy Mode. | ## ⭐ Support diff --git a/plugins/actions/smart-mind-map/README_CN.md b/plugins/actions/smart-mind-map/README_CN.md index b1374c1..c74ca49 100644 --- a/plugins/actions/smart-mind-map/README_CN.md +++ b/plugins/actions/smart-mind-map/README_CN.md @@ -2,21 +2,26 @@ 思维导图是一个强大的 OpenWebUI 动作插件,能够智能分析长篇文本内容,自动生成交互式思维导图,帮助用户结构化和可视化知识。 -**作者:** [Fu-Jie](https://github.com/Fu-Jie) | **版本:** 0.9.2 | **项目:** [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) | **许可证:** MIT +**作者:** [Fu-Jie](https://github.com/Fu-Jie) | **版本:** 1.0.0 | **项目:** [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) | **许可证:** MIT -## v0.9.2 更新亮点 +## v1.0.0 最新更新 -**语言规则对齐** +### 嵌入式直出与 UI 细节全线重构 -- **输入语言优先**:导图输出严格与输入文本语言一致。 -- **一致性提升**:与信息图语言规则保持一致,多语言输出更可预期。 +- **原生多语言界面 (Native i18n)**:插件界面(按钮、设置说明、状态提示)现在会根据您浏览器的语言设置自动适配系统语言。 +- **原生态嵌入模式 (Direct Embed)**:针对 Open WebUI 0.8.0+ 的前端架构支持了纯正的内容内联(Inline)直出模式,不再受气泡和 Markdown 隔离,真正撑满屏幕宽度。 +- **自动响应边界 (Auto-Sizing)**:突破以前高度僵死的问题。思维导图现在可以根据您的当前屏幕大小弹性伸缩(动态 `clamp()` 高度),彻底消灭丑陋的局部滚动条与白边。 +- **极简专业 UI (Compact UI)**:推倒重做了头部的菜单栏,统一使用了一套干净、单行的极简全透明微拟物 Toolbar 设计,为导图画布省下极大的垂直空间。 +- **模式配置自由**:为了照顾阅读流连贯的习惯,新增了 `ENABLE_DIRECT_EMBED_MODE` 配置开关。您必须在设置中显式开启才能体验宽广内联全屏模式。 ## 核心特性 🔑 - ✅ **智能文本分析**:自动识别文本的核心主题、关键概念和层次结构。 +- ✅ **原生多语言界面**:根据系统语言自动切换界面语言 (i18n),提供原生交互体验。 - ✅ **交互式可视化**:基于 Markmap.js 生成美观的交互式思维导图。 +- ✅ **直出全景内嵌 (Direct Embed)**:(可选开关) 对于 Open WebUI 0.8.0+,直接填补整个前端宽度,去除气泡剥离感。 - ✅ **高分辨率 PNG 导出**:导出高质量的 PNG 图片(9 倍分辨率)。 -- ✅ **完整控制面板**:缩放控制、展开层级选择、全屏模式。 +- ✅ **完整控制面板**:极简清爽的单行大屏缩放控制、展开层级选择、全局全屏等核心操作。 - ✅ **主题切换**:手动主题切换按钮与自动主题检测。 - ✅ **图片输出模式**:生成静态 SVG 图片直接嵌入 Markdown,聊天记录更简洁。 @@ -37,6 +42,7 @@ | `CLEAR_PREVIOUS_HTML` | `false` | 在生成新的思维导图时,是否清除之前的 HTML 内容。 | | `MESSAGE_COUNT` | `1` | 用于生成思维导图的最近消息数量(1-5)。 | | `OUTPUT_MODE` | `html` | 输出模式:`html`(交互式)或 `image`(静态图片)。 | +| `ENABLE_DIRECT_EMBED_MODE` | `false` | 是否开启沉浸式直出嵌入模式(需要 Open WebUI v0.8.0+ 环境)。如果保持 `false` 将会维持旧版的对话流 Markdown 渲染模式。 | ## ⭐ 支持 diff --git a/plugins/actions/smart-mind-map/smart_mind_map.py b/plugins/actions/smart-mind-map/smart_mind_map.py index 4ff0d7e..7a559a4 100644 --- a/plugins/actions/smart-mind-map/smart_mind_map.py +++ b/plugins/actions/smart-mind-map/smart_mind_map.py @@ -3,7 +3,7 @@ title: Smart Mind Map author: Fu-Jie author_url: https://github.com/Fu-Jie/openwebui-extensions funding_url: https://github.com/open-webui -version: 0.9.4 +version: 1.0.0 openwebui_id: 3094c59a-b4dd-4e0c-9449-15e2dd547dc4 icon_url: data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxyZWN0IHg9IjE2IiB5PSIxNiIgd2lkdGg9IjYiIGhlaWdodD0iNiIgcng9IjEiLz48cmVjdCB4PSIyIiB5PSIxNiIgd2lkdGg9IjYiIGhlaWdodD0iNiIgcng9IjEiLz48cmVjdCB4PSI5IiB5PSIyIiB3aWR0aD0iNiIgaGVpZ2h0PSI2IiByeD0iMSIvPjxwYXRoIGQ9Ik01IDE2di0zYTEgMSAwIDAgMSAxLTFoMTJhMSAxIDAgMCAxIDEgMXYzIi8+PHBhdGggZD0iTTEyIDEyVjgiLz48L3N2Zz4= description: Intelligently analyzes text content and generates interactive mind maps to help users structure and visualize knowledge. @@ -24,6 +24,12 @@ from pydantic import BaseModel, Field from open_webui.utils.chat import generate_chat_completion from open_webui.models.users import Users +try: + from open_webui.env import VERSION as open_webui_version +except ImportError: + open_webui_version = "0.0.0" + + logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" ) @@ -59,7 +65,7 @@ TRANSLATIONS = { "ui_depth_3": "Level 3", "ui_fullscreen": "Fullscreen", "ui_theme": "Theme", - "ui_footer": "© {year} Smart Mind Map • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ Unable to load mind map: Missing valid content.", "html_error_load_failed": "⚠️ Resource loading failed, please try again later.", "js_done": "Done", @@ -67,7 +73,7 @@ TRANSLATIONS = { "js_generating": "Generating...", "js_filename": "mindmap.png", "js_upload_failed": "Upload failed: ", - "md_image_alt": "🧠 Mind Map" + "md_image_alt": "🧠 Mind Map", }, "zh-CN": { "status_starting": "思维导图已启动,正在为您生成思维导图...", @@ -98,7 +104,7 @@ TRANSLATIONS = { "ui_depth_3": "展开 3 级", "ui_fullscreen": "全屏", "ui_theme": "主题", - "ui_footer": "© {year} 智能思维导图 • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ 无法加载思维导图:缺少有效内容。", "html_error_load_failed": "⚠️ 资源加载失败,请稍后重试。", "js_done": "完成", @@ -106,7 +112,7 @@ TRANSLATIONS = { "js_generating": "生成中...", "js_filename": "思维导图.png", "js_upload_failed": "上传失败:", - "md_image_alt": "🧠 思维导图" + "md_image_alt": "🧠 思维导图", }, "zh-HK": { "status_starting": "思維導圖已啟動,正在為您生成思維導圖...", @@ -137,7 +143,7 @@ TRANSLATIONS = { "ui_depth_3": "展開 3 級", "ui_fullscreen": "全屏", "ui_theme": "主題", - "ui_footer": "© {year} 智能思維導圖 • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ 無法加載思維導圖:缺少有效內容。", "html_error_load_failed": "⚠️ 資源加載失敗,請稍後重試。", "js_done": "完成", @@ -145,7 +151,7 @@ TRANSLATIONS = { "js_generating": "生成中...", "js_filename": "思維導圖.png", "js_upload_failed": "上傳失敗:", - "md_image_alt": "🧠 思維導圖" + "md_image_alt": "🧠 思維導圖", }, "zh-TW": { "status_starting": "思維導圖已啟動,正在為您生成思維導圖...", @@ -176,7 +182,7 @@ TRANSLATIONS = { "ui_depth_3": "展開 3 級", "ui_fullscreen": "全屏", "ui_theme": "主題", - "ui_footer": "© {year} 智能思維導圖 • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ 無法加載思維導圖:缺少有效內容。", "html_error_load_failed": "⚠️ 資源加載失敗,請稍後重試。", "js_done": "完成", @@ -184,7 +190,7 @@ TRANSLATIONS = { "js_generating": "生成中...", "js_filename": "思維導圖.png", "js_upload_failed": "上傳失敗:", - "md_image_alt": "🧠 思維導圖" + "md_image_alt": "🧠 思維導圖", }, "ko-KR": { "status_starting": "스마트 마인드맵이 시작되었습니다, 마인드맵을 생성 중입니다...", @@ -215,7 +221,7 @@ TRANSLATIONS = { "ui_depth_3": "레벨 3", "ui_fullscreen": "전체 화면", "ui_theme": "테마", - "ui_footer": "© {year} 스마트 마인드맵 • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ 마인드맵을 로드할 수 없습니다: 유효한 내용이 없습니다.", "html_error_load_failed": "⚠️ 리소스 로드 실패, 나중에 다시 시도해 주세요.", "js_done": "완료", @@ -223,7 +229,7 @@ TRANSLATIONS = { "js_generating": "생성 중...", "js_filename": "mindmap.png", "js_upload_failed": "업로드 실패: ", - "md_image_alt": "🧠 마인드맵" + "md_image_alt": "🧠 마인드맵", }, "ja-JP": { "status_starting": "スマートマインドマップが起動しました。マインドマップを生成しています...", @@ -254,7 +260,7 @@ TRANSLATIONS = { "ui_depth_3": "レベル3", "ui_fullscreen": "全画面", "ui_theme": "テーマ", - "ui_footer": "© {year} スマートマインドマップ • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ マインドマップを読み込めません:有効なコンテンツがありません。", "html_error_load_failed": "⚠️ リソースの読み込みに失敗しました。後でもう一度お試しください。", "js_done": "完了", @@ -262,7 +268,7 @@ TRANSLATIONS = { "js_generating": "生成中...", "js_filename": "mindmap.png", "js_upload_failed": "アップロード失敗:", - "md_image_alt": "🧠 マインドマップ" + "md_image_alt": "🧠 マインドマップ", }, "fr-FR": { "status_starting": "Smart Mind Map démarre, génération de la carte heuristique en cours...", @@ -293,7 +299,7 @@ TRANSLATIONS = { "ui_depth_3": "Niveau 3", "ui_fullscreen": "Plein écran", "ui_theme": "Thème", - "ui_footer": "© {year} Smart Mind Map • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ Impossible de charger la carte heuristique : contenu valide manquant.", "html_error_load_failed": "⚠️ Échec du chargement des ressources, veuillez réessayer plus tard.", "js_done": "Terminé", @@ -301,7 +307,7 @@ TRANSLATIONS = { "js_generating": "Génération...", "js_filename": "carte_heuristique.png", "js_upload_failed": "Échec du téléchargement : ", - "md_image_alt": "🧠 Carte Heuristique" + "md_image_alt": "🧠 Carte Heuristique", }, "de-DE": { "status_starting": "Smart Mind Map startet, Mindmap wird für Sie erstellt...", @@ -332,7 +338,7 @@ TRANSLATIONS = { "ui_depth_3": "Ebene 3", "ui_fullscreen": "Vollbild", "ui_theme": "Thema", - "ui_footer": "© {year} Smart Mind Map • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ Mindmap kann nicht geladen werden: Gültiger Inhalt fehlt.", "html_error_load_failed": "⚠️ Ressourcenladen fehlgeschlagen, bitte versuchen Sie es später erneut.", "js_done": "Fertig", @@ -340,7 +346,7 @@ TRANSLATIONS = { "js_generating": "Generiere...", "js_filename": "mindmap.png", "js_upload_failed": "Upload fehlgeschlagen: ", - "md_image_alt": "🧠 Mindmap" + "md_image_alt": "🧠 Mindmap", }, "es-ES": { "status_starting": "Smart Mind Map se está iniciando, generando mapa mental para usted...", @@ -371,7 +377,7 @@ TRANSLATIONS = { "ui_depth_3": "Nivel 3", "ui_fullscreen": "Pantalla completa", "ui_theme": "Tema", - "ui_footer": "© {year} Smart Mind Map • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ No se puede cargar el mapa mental: Falta contenido válido.", "html_error_load_failed": "⚠️ Falló la carga de recursos, inténtelo de nuevo más tarde.", "js_done": "Hecho", @@ -379,7 +385,7 @@ TRANSLATIONS = { "js_generating": "Generando...", "js_filename": "mapa_mental.png", "js_upload_failed": "Carga fallida: ", - "md_image_alt": "🧠 Mapa Mental" + "md_image_alt": "🧠 Mapa Mental", }, "it-IT": { "status_starting": "Smart Mind Map si sta avviando, generazione mappa mentale in corso...", @@ -410,7 +416,7 @@ TRANSLATIONS = { "ui_depth_3": "Livello 3", "ui_fullscreen": "Schermo intero", "ui_theme": "Tema", - "ui_footer": "© {year} Smart Mind Map • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ Impossibile caricare la mappa mentale: Contenuto valido mancante.", "html_error_load_failed": "⚠️ Caricamento risorse fallito, riprovare più tardi.", "js_done": "Fatto", @@ -418,7 +424,7 @@ TRANSLATIONS = { "js_generating": "Generazione...", "js_filename": "mappa_mentale.png", "js_upload_failed": "Caricamento fallito: ", - "md_image_alt": "🧠 Mappa Mentale" + "md_image_alt": "🧠 Mappa Mentale", }, "vi-VN": { "status_starting": "Smart Mind Map đang khởi động, đang tạo sơ đồ tư duy cho bạn...", @@ -449,7 +455,7 @@ TRANSLATIONS = { "ui_depth_3": "Cấp độ 3", "ui_fullscreen": "Toàn màn hình", "ui_theme": "Chủ đề", - "ui_footer": "© {year} Smart Mind Map • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ Không thể tải sơ đồ tư duy: Thiếu nội dung hợp lệ.", "html_error_load_failed": "⚠️ Tải tài nguyên thất bại, vui lòng thử lại sau.", "js_done": "Xong", @@ -457,7 +463,7 @@ TRANSLATIONS = { "js_generating": "Đang tạo...", "js_filename": "sodo_tuduy.png", "js_upload_failed": "Tải lên thất bại: ", - "md_image_alt": "🧠 Sơ đồ Tư duy" + "md_image_alt": "🧠 Sơ đồ Tư duy", }, "id-ID": { "status_starting": "Smart Mind Map sedang dimulai, membuat peta pikiran untuk Anda...", @@ -488,7 +494,7 @@ TRANSLATIONS = { "ui_depth_3": "Level 3", "ui_fullscreen": "Layar Penuh", "ui_theme": "Tema", - "ui_footer": "© {year} Smart Mind Map • Markmap", + "ui_footer": "Powered by Markmap", "html_error_missing_content": "⚠️ Tidak dapat memuat peta pikiran: Konten valid hilang.", "html_error_load_failed": "⚠️ Gagal memuat sumber daya, silakan coba lagi nanti.", "js_done": "Selesai", @@ -496,8 +502,8 @@ TRANSLATIONS = { "js_generating": "Membuat...", "js_filename": "peta_pikiran.png", "js_upload_failed": "Unggah gagal: ", - "md_image_alt": "🧠 Peta Pikiran" - } + "md_image_alt": "🧠 Peta Pikiran", + }, } SYSTEM_PROMPT_MINDMAP_ASSISTANT = """ @@ -509,8 +515,15 @@ Please strictly follow these guidelines: - **Format**: Your output must strictly be in Markdown list format, wrapped with ```markdown and ```. - Use `#` to define the central theme (root node). - Use `-` with two-space indentation to represent branches and sub-branches. -- **Content**: - - Identify the central theme of the text as the `#` heading. +- **Root Node (Central Theme) — Strict Length Limits**: + - The `#` root node must be an ultra-compact title, like a newspaper headline. It should be a keyword or short phrase, NEVER a full sentence. + - **CJK scripts (Chinese, Japanese, Korean)**: Maximum **10 characters** (e.g., `# 老人缓解呼吸困难方法` ✓ / `# 老人在家时感到呼吸困难的缓解方法` ✗) + - **Latin-script languages (English, Spanish, French, Italian, Portuguese)**: Maximum **5 words or 35 characters** (e.g., `# Methods to Relieve Dyspnea` ✓ / `# How Elderly People Can Relieve Breathing Difficulty at Home` ✗) + - **German, Dutch or languages with long compound words**: Maximum **4 words or 30 characters** + - **Arabic, Hebrew and other RTL scripts**: Maximum **5 words or 25 characters** + - **All other languages**: Maximum **5 words or 30 characters** + - If the identified theme would exceed the limit, distill it further into the single most essential keyword or 2-3 word phrase. +- **Branch Node Content**: - Identify main concepts as first-level list items. - Identify supporting details or sub-concepts as nested list items. - Node content should be concise and clear, avoiding verbosity. @@ -520,6 +533,9 @@ Please strictly follow these guidelines: # Unable to Generate Mind Map - Reason: Insufficient or unclear text content ``` +- **Awareness of Target Audience Layout**: You will be provided `Target Rendering Mode`. + - If `Target Rendering Mode` is `direct`: The client has massive horizontal space but limited scrolling vertically. Extract more first-level concepts to make the mind map spread wide like a sprawling fan, rather than deep single columns. + - If `Target Rendering Mode` is `legacy`: The client uses a narrow, portrait sidebar. Extract fewer top-level nodes, and break points into deeper, tighter sub-branches so the map grows vertically downwards. """ USER_PROMPT_GENERATE_MINDMAP = """ @@ -532,6 +548,7 @@ Current Date & Time: {current_date_time_str} Current Weekday: {current_weekday} Current Timezone: {current_timezone_str} User Language: {user_language} +Target Rendering Mode: Auto-adapting (Dynamic width based on viewport) --- **Long-form Text Content:** @@ -549,7 +566,7 @@ HTML_WRAPPER_TEMPLATE = """ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; margin: 0; - padding: 10px; + padding: 2px; background-color: transparent; } #main-container { @@ -609,6 +626,14 @@ CSS_TEMPLATE_MINDMAP = """ --header-gradient: linear-gradient(135deg, #0ea5e9, #22c55e); --shadow: 0 10px 20px rgba(0, 0, 0, 0.3); } + html, body { + margin: 0; + padding: 0; + width: 100vw; + height: 100vh; + background: var(--card-bg-color); + overflow: hidden; + } .mindmap-container-wrapper { font-family: var(--font-family); line-height: 1.6; @@ -617,64 +642,76 @@ CSS_TEMPLATE_MINDMAP = """ padding: 0; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - height: 100%; display: flex; flex-direction: column; - background: var(--background-color); - border: 1px solid var(--border-color); - border-radius: var(--border-radius); - box-shadow: var(--shadow); + background: var(--card-bg-color); + width: 100vw; + height: 100vh; + box-sizing: border-box; + overflow: hidden; + border: none; + border-radius: 0; + box-shadow: none; } .header { - background: var(--header-gradient); - color: white; - padding: 18px 20px; - text-align: center; - border-top-left-radius: var(--border-radius); - border-top-right-radius: var(--border-radius); + background: var(--card-bg-color); + color: var(--text-color); + padding: 12px 16px; + display: flex; + flex-direction: column; + gap: 12px; + flex-shrink: 0; + border-bottom: 1px solid var(--border-color); + z-index: 10; + } + .header-top { + display: flex; + align-items: center; + gap: 12px; } .header h1 { margin: 0; - font-size: 1.4em; + font-size: 1.2em; font-weight: 600; - letter-spacing: 0.3px; - } - .user-context { - font-size: 0.85em; - color: var(--muted-text-color); - background-color: rgba(255, 255, 255, 0.6); - padding: 8px 14px; + letter-spacing: 0.5px; display: flex; - justify-content: space-between; - flex-wrap: wrap; - border-bottom: 1px solid var(--border-color); - gap: 6px; + align-items: center; + gap: 8px; } - .theme-dark .user-context { - background-color: rgba(31, 41, 55, 0.7); + .header-credits { + font-size: 0.8em; + color: var(--muted-text-color); + opacity: 0.8; + white-space: nowrap; } - .user-context span { margin: 2px 6px; } + .header-credits a { + color: var(--primary-color); + text-decoration: none; + border-bottom: 1px dotted var(--link-color); + } + .content-area { - padding: 16px; - flex-grow: 1; - background: var(--card-bg-color); + padding: 0; + flex: 1 1 0; + background: transparent; + position: relative; + overflow: hidden; + width: 100%; + min-height: 0; + /* Height will be computed dynamically by JS below */ } .markmap-container { - position: relative; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; background-color: var(--card-bg-color); - border-radius: 10px; - padding: 12px; - display: flex; - justify-content: center; - align-items: center; - border: 1px solid var(--border-color); - width: 100%; - min-height: 60vh; - overflow: visible; } .markmap-container svg { width: 100%; height: 100%; + display: block; } .markmap-container svg text { fill: var(--text-color) !important; @@ -688,6 +725,10 @@ CSS_TEMPLATE_MINDMAP = """ } .markmap-container svg .markmap-link { stroke: var(--link-color) !important; + stroke-opacity: 0.6; + } + .theme-dark .markmap-node circle { + fill: var(--card-bg-color) !important; } .markmap-container svg .markmap-node circle, .markmap-container svg .markmap-node rect { @@ -695,32 +736,54 @@ CSS_TEMPLATE_MINDMAP = """ } .control-rows { display: flex; + align-items: center; flex-wrap: wrap; - gap: 10px; - justify-content: center; - margin-top: 12px; + gap: 12px; + margin-left: auto; /* Push controls to the right */ } .btn-group { display: inline-flex; - gap: 6px; + gap: 4px; align-items: center; + border: 1px solid var(--border-color); + border-radius: 6px; + padding: 2px; + background: var(--background-color); } .control-btn { - background-color: var(--primary-color); - color: white; + background-color: transparent; + color: var(--text-color); border: none; - padding: 8px 12px; - border-radius: 8px; - font-size: 0.9em; + padding: 4px 10px; + border-radius: 4px; + font-size: 0.85em; font-weight: 500; cursor: pointer; - transition: background-color 0.15s ease, transform 0.15s ease; + transition: all 0.2s ease; display: inline-flex; align-items: center; - gap: 6px; - height: 36px; + justify-content: center; + height: 28px; box-sizing: border-box; + opacity: 0.8; } + .control-btn:hover { + background-color: var(--card-bg-color); + opacity: 1; + box-shadow: 0 1px 3px rgba(0,0,0,0.1); + } + .control-btn:active { + transform: translateY(1px); + } + .control-btn.primary { + background-color: var(--primary-color); + color: white; + opacity: 1; + } + .control-btn.primary:hover { + box-shadow: 0 2px 5px rgba(30,136,229,0.3); + } + select.control-btn { appearance: none; padding-right: 28px; @@ -729,28 +792,10 @@ CSS_TEMPLATE_MINDMAP = """ background-position: right 8px center; background-size: 10px; } - .control-btn.secondary { background-color: var(--secondary-color); } - .control-btn.neutral { background-color: #64748b; } - .control-btn:hover { transform: translateY(-1px); } - .control-btn.copied { background-color: #2e7d32; } - .control-btn:disabled { opacity: 0.6; cursor: not-allowed; } - .footer { - text-align: center; - padding: 12px; - font-size: 0.85em; - color: var(--muted-text-color); + .control-btn option { background-color: var(--card-bg-color); - border-top: 1px solid var(--border-color); - border-bottom-left-radius: var(--border-radius); - border-bottom-right-radius: var(--border-radius); + color: var(--text-color); } - - .footer a { - color: var(--primary-color); - text-decoration: none; - font-weight: 500; - } - .footer a:hover { text-decoration: underline; } .error-message { color: #c62828; background-color: #ffcdd2; @@ -759,50 +804,67 @@ CSS_TEMPLATE_MINDMAP = """ border-radius: 8px; font-weight: 500; font-size: 1em; + margin: 10px; + } + + /* Mobile Responsive Adjustments */ + @media screen and (max-width: 768px) { + .mindmap-container-wrapper { + min-height: 400px; + height: 80vh; + } + .header { + flex-direction: column; + gap: 10px; + } + .btn-group { + padding: 2px; + } + .control-btn { + padding: 4px 6px; + font-size: 0.75em; + height: 28px; + } + select.control-btn { + padding-right: 20px; + background-position: right 4px center; + } } """ CONTENT_TEMPLATE_MINDMAP = """