Compare commits
17 Commits
v2026.01.1
...
v2026.01.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06e8d30900 | ||
|
|
cbf2ff7f93 | ||
|
|
abbe3fb248 | ||
|
|
7e44dde979 | ||
|
|
3649d75539 | ||
|
|
d3b4219a9a | ||
|
|
9e98d55e11 | ||
|
|
4b8515f682 | ||
|
|
d2f35ce396 | ||
|
|
f479f23b38 | ||
|
|
51048f9e5d | ||
|
|
1118ae34c4 | ||
|
|
7a5e1a4e12 | ||
|
|
8e377e1794 | ||
|
|
d66360b02d | ||
|
|
1ece648006 | ||
|
|
a262a716a3 |
4
.github/copilot-instructions.md
vendored
4
.github/copilot-instructions.md
vendored
@@ -40,7 +40,7 @@ plugins/actions/export_to_docx/
|
|||||||
- 格式: `**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** x.x.x | **Project:** [Awesome OpenWebUI](https://github.com/Fu-Jie/awesome-openwebui)`
|
- 格式: `**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** x.x.x | **Project:** [Awesome OpenWebUI](https://github.com/Fu-Jie/awesome-openwebui)`
|
||||||
- **注意**: Author 和 Project 为固定值,仅需更新 Version 版本号
|
- **注意**: Author 和 Project 为固定值,仅需更新 Version 版本号
|
||||||
3. **描述 (Description)**: 一句话功能介绍
|
3. **描述 (Description)**: 一句话功能介绍
|
||||||
4. **最新更新 (What's New)**: **必须**放在描述之后,显著展示最新版本的变更点
|
4. **最新更新 (What's New)**: **必须**放在描述之后,显著展示最新版本的变更点 (仅展示最近 3 次更新)
|
||||||
5. **核心特性 (Key Features)**: 使用 Emoji + 粗体标题 + 描述格式
|
5. **核心特性 (Key Features)**: 使用 Emoji + 粗体标题 + 描述格式
|
||||||
6. **使用方法 (How to Use)**: 按步骤说明
|
6. **使用方法 (How to Use)**: 按步骤说明
|
||||||
7. **配置参数 (Configuration/Valves)**: 使用表格格式,包含参数名、默认值、描述
|
7. **配置参数 (Configuration/Valves)**: 使用表格格式,包含参数名、默认值、描述
|
||||||
@@ -96,7 +96,7 @@ example code or syntax here
|
|||||||
|
|
||||||
### 文档内容要求 (Content Requirements)
|
### 文档内容要求 (Content Requirements)
|
||||||
|
|
||||||
- **新增功能**: 必须在 "What's New" 章节中明确列出,使用 Emoji + 粗体标题格式。
|
- **新增功能**: 必须在 "What's New" 章节中明确列出,使用 Emoji + 粗体标题格式 (仅保留最近 3 个版本的更新记录)。
|
||||||
- **双语**: 必须提供 `README.md` (英文) 和 `README_CN.md` (中文)。
|
- **双语**: 必须提供 `README.md` (英文) 和 `README_CN.md` (中文)。
|
||||||
- **表格对齐**: 配置参数表格使用左对齐 `:---`。
|
- **表格对齐**: 配置参数表格使用左对齐 `:---`。
|
||||||
- **Emoji 规范**: 标题使用合适的 Emoji 增强可读性。
|
- **Emoji 规范**: 标题使用合适的 Emoji 增强可读性。
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -7,26 +7,26 @@ A collection of enhancements, plugins, and prompts for [OpenWebUI](https://githu
|
|||||||
<!-- STATS_START -->
|
<!-- STATS_START -->
|
||||||
## 📊 Community Stats
|
## 📊 Community Stats
|
||||||
|
|
||||||
> 🕐 Auto-updated: 2026-01-10 17:08
|
> 🕐 Auto-updated: 2026-01-11 02:11
|
||||||
|
|
||||||
| 👤 Author | 👥 Followers | ⭐ Points | 🏆 Contributions |
|
| 👤 Author | 👥 Followers | ⭐ Points | 🏆 Contributions |
|
||||||
|:---:|:---:|:---:|:---:|
|
|:---:|:---:|:---:|:---:|
|
||||||
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | **71** | **72** | **21** |
|
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | **75** | **77** | **22** |
|
||||||
|
|
||||||
| 📝 Posts | ⬇️ Downloads | 👁️ Views | 👍 Upvotes | 💾 Saves |
|
| 📝 Posts | ⬇️ Downloads | 👁️ Views | 👍 Upvotes | 💾 Saves |
|
||||||
|:---:|:---:|:---:|:---:|:---:|
|
|:---:|:---:|:---:|:---:|:---:|
|
||||||
| **14** | **1066** | **11486** | **64** | **66** |
|
| **14** | **1087** | **11853** | **68** | **67** |
|
||||||
|
|
||||||
### 🔥 Top 6 Popular Plugins
|
### 🔥 Top 6 Popular Plugins
|
||||||
|
|
||||||
| Rank | Plugin | Downloads | Views |
|
| Rank | Plugin | Downloads | Views |
|
||||||
|:---:|------|:---:|:---:|
|
|:---:|------|:---:|:---:|
|
||||||
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | 341 | 3080 |
|
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | 348 | 3165 |
|
||||||
| 🥈 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | 181 | 551 |
|
| 🥈 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | 181 | 559 |
|
||||||
| 🥉 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | 125 | 1390 |
|
| 🥉 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | 128 | 1437 |
|
||||||
| 4️⃣ | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | 116 | 1355 |
|
| 4️⃣ | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | 120 | 1393 |
|
||||||
| 5️⃣ | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | 92 | 1735 |
|
| 5️⃣ | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | 94 | 1766 |
|
||||||
| 6️⃣ | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | 87 | 800 |
|
| 6️⃣ | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | 87 | 814 |
|
||||||
|
|
||||||
*See full stats in [Community Stats Report](./docs/community-stats.md)*
|
*See full stats in [Community Stats Report](./docs/community-stats.md)*
|
||||||
<!-- STATS_END -->
|
<!-- STATS_END -->
|
||||||
|
|||||||
18
README_CN.md
18
README_CN.md
@@ -7,26 +7,26 @@ OpenWebUI 增强功能集合。包含个人开发与收集的插件、提示词
|
|||||||
<!-- STATS_START -->
|
<!-- STATS_START -->
|
||||||
## 📊 社区统计
|
## 📊 社区统计
|
||||||
|
|
||||||
> 🕐 自动更新于 2026-01-10 17:08
|
> 🕐 自动更新于 2026-01-11 02:11
|
||||||
|
|
||||||
| 👤 作者 | 👥 粉丝 | ⭐ 积分 | 🏆 贡献 |
|
| 👤 作者 | 👥 粉丝 | ⭐ 积分 | 🏆 贡献 |
|
||||||
|:---:|:---:|:---:|:---:|
|
|:---:|:---:|:---:|:---:|
|
||||||
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | **71** | **72** | **21** |
|
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | **75** | **77** | **22** |
|
||||||
|
|
||||||
| 📝 发布 | ⬇️ 下载 | 👁️ 浏览 | 👍 点赞 | 💾 收藏 |
|
| 📝 发布 | ⬇️ 下载 | 👁️ 浏览 | 👍 点赞 | 💾 收藏 |
|
||||||
|:---:|:---:|:---:|:---:|:---:|
|
|:---:|:---:|:---:|:---:|:---:|
|
||||||
| **14** | **1066** | **11486** | **64** | **66** |
|
| **14** | **1087** | **11853** | **68** | **67** |
|
||||||
|
|
||||||
### 🔥 热门插件 Top 6
|
### 🔥 热门插件 Top 6
|
||||||
|
|
||||||
| 排名 | 插件 | 下载 | 浏览 |
|
| 排名 | 插件 | 下载 | 浏览 |
|
||||||
|:---:|------|:---:|:---:|
|
|:---:|------|:---:|:---:|
|
||||||
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | 341 | 3080 |
|
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | 348 | 3165 |
|
||||||
| 🥈 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | 181 | 551 |
|
| 🥈 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | 181 | 559 |
|
||||||
| 🥉 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | 125 | 1390 |
|
| 🥉 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | 128 | 1437 |
|
||||||
| 4️⃣ | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | 116 | 1355 |
|
| 4️⃣ | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | 120 | 1393 |
|
||||||
| 5️⃣ | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | 92 | 1735 |
|
| 5️⃣ | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | 94 | 1766 |
|
||||||
| 6️⃣ | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | 87 | 800 |
|
| 6️⃣ | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | 87 | 814 |
|
||||||
|
|
||||||
*完整统计请查看 [社区统计报告](./docs/community-stats.zh.md)*
|
*完整统计请查看 [社区统计报告](./docs/community-stats.zh.md)*
|
||||||
<!-- STATS_END -->
|
<!-- STATS_END -->
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"total_posts": 14,
|
"total_posts": 14,
|
||||||
"total_downloads": 1066,
|
"total_downloads": 1087,
|
||||||
"total_views": 11486,
|
"total_views": 11853,
|
||||||
"total_upvotes": 64,
|
"total_upvotes": 68,
|
||||||
"total_downvotes": 2,
|
"total_downvotes": 2,
|
||||||
"total_saves": 66,
|
"total_saves": 67,
|
||||||
"total_comments": 15,
|
"total_comments": 17,
|
||||||
"by_type": {
|
"by_type": {
|
||||||
|
"filter": 2,
|
||||||
"unknown": 1,
|
"unknown": 1,
|
||||||
"action": 11,
|
"action": 11
|
||||||
"filter": 2
|
|
||||||
},
|
},
|
||||||
"posts": [
|
"posts": [
|
||||||
{
|
{
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
"version": "0.9.1",
|
"version": "0.9.1",
|
||||||
"author": "Fu-Jie",
|
"author": "Fu-Jie",
|
||||||
"description": "Intelligently analyzes text content and generates interactive mind maps to help users structure and visualize knowledge.",
|
"description": "Intelligently analyzes text content and generates interactive mind maps to help users structure and visualize knowledge.",
|
||||||
"downloads": 341,
|
"downloads": 348,
|
||||||
"views": 3080,
|
"views": 3165,
|
||||||
"upvotes": 10,
|
"upvotes": 10,
|
||||||
"saves": 21,
|
"saves": 21,
|
||||||
"comments": 10,
|
"comments": 10,
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"author": "Fu-Jie",
|
"author": "Fu-Jie",
|
||||||
"description": "Extracts tables from chat messages and exports them to Excel (.xlsx) files with smart formatting.",
|
"description": "Extracts tables from chat messages and exports them to Excel (.xlsx) files with smart formatting.",
|
||||||
"downloads": 181,
|
"downloads": 181,
|
||||||
"views": 551,
|
"views": 559,
|
||||||
"upvotes": 3,
|
"upvotes": 3,
|
||||||
"saves": 4,
|
"saves": 4,
|
||||||
"comments": 0,
|
"comments": 0,
|
||||||
@@ -48,16 +48,16 @@
|
|||||||
"title": "Async Context Compression",
|
"title": "Async Context Compression",
|
||||||
"slug": "async_context_compression_b1655bc8",
|
"slug": "async_context_compression_b1655bc8",
|
||||||
"type": "filter",
|
"type": "filter",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"author": "Fu-Jie",
|
"author": "Fu-Jie",
|
||||||
"description": "Reduces token consumption in long conversations while maintaining coherence through intelligent summarization and message compression.",
|
"description": "Reduces token consumption in long conversations while maintaining coherence through intelligent summarization and message compression.",
|
||||||
"downloads": 125,
|
"downloads": 128,
|
||||||
"views": 1390,
|
"views": 1437,
|
||||||
"upvotes": 5,
|
"upvotes": 5,
|
||||||
"saves": 9,
|
"saves": 9,
|
||||||
"comments": 0,
|
"comments": 0,
|
||||||
"created_at": "2025-11-08",
|
"created_at": "2025-11-08",
|
||||||
"updated_at": "2026-01-07",
|
"updated_at": "2026-01-10",
|
||||||
"url": "https://openwebui.com/posts/async_context_compression_b1655bc8"
|
"url": "https://openwebui.com/posts/async_context_compression_b1655bc8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -67,8 +67,8 @@
|
|||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"author": "jeff",
|
"author": "jeff",
|
||||||
"description": "AI-powered infographic generator based on AntV Infographic. Supports professional templates, auto-icon matching, and SVG/PNG downloads.",
|
"description": "AI-powered infographic generator based on AntV Infographic. Supports professional templates, auto-icon matching, and SVG/PNG downloads.",
|
||||||
"downloads": 116,
|
"downloads": 120,
|
||||||
"views": 1355,
|
"views": 1393,
|
||||||
"upvotes": 7,
|
"upvotes": 7,
|
||||||
"saves": 9,
|
"saves": 9,
|
||||||
"comments": 2,
|
"comments": 2,
|
||||||
@@ -83,8 +83,8 @@
|
|||||||
"version": "0.2.4",
|
"version": "0.2.4",
|
||||||
"author": "Fu-Jie",
|
"author": "Fu-Jie",
|
||||||
"description": "Quickly generates beautiful flashcards from text, extracting key points and categories.",
|
"description": "Quickly generates beautiful flashcards from text, extracting key points and categories.",
|
||||||
"downloads": 92,
|
"downloads": 94,
|
||||||
"views": 1735,
|
"views": 1766,
|
||||||
"upvotes": 8,
|
"upvotes": 8,
|
||||||
"saves": 6,
|
"saves": 6,
|
||||||
"comments": 2,
|
"comments": 2,
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
"author": "Fu-Jie",
|
"author": "Fu-Jie",
|
||||||
"description": "Export current conversation from Markdown to Word (.docx) with Mermaid diagrams rendered client-side (Mermaid.js, SVG+PNG), LaTeX math, real hyperlinks, improved tables, syntax highlighting, and blockquote support.",
|
"description": "Export current conversation from Markdown to Word (.docx) with Mermaid diagrams rendered client-side (Mermaid.js, SVG+PNG), LaTeX math, real hyperlinks, improved tables, syntax highlighting, and blockquote support.",
|
||||||
"downloads": 87,
|
"downloads": 87,
|
||||||
"views": 800,
|
"views": 814,
|
||||||
"upvotes": 5,
|
"upvotes": 5,
|
||||||
"saves": 8,
|
"saves": 8,
|
||||||
"comments": 0,
|
"comments": 0,
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
"author": "jeff",
|
"author": "jeff",
|
||||||
"description": "基于 AntV Infographic 的智能信息图生成插件。支持多种专业模板,自动图标匹配,并提供 SVG/PNG 下载功能。",
|
"description": "基于 AntV Infographic 的智能信息图生成插件。支持多种专业模板,自动图标匹配,并提供 SVG/PNG 下载功能。",
|
||||||
"downloads": 35,
|
"downloads": 35,
|
||||||
"views": 480,
|
"views": 486,
|
||||||
"upvotes": 3,
|
"upvotes": 3,
|
||||||
"saves": 0,
|
"saves": 0,
|
||||||
"comments": 0,
|
"comments": 0,
|
||||||
@@ -131,8 +131,8 @@
|
|||||||
"version": "0.4.3",
|
"version": "0.4.3",
|
||||||
"author": "Fu-Jie",
|
"author": "Fu-Jie",
|
||||||
"description": "将对话导出为 Word (.docx),支持 Mermaid 图表 (客户端渲染 SVG+PNG)、LaTeX 数学公式、真实超链接、增强表格格式、代码高亮和引用块。",
|
"description": "将对话导出为 Word (.docx),支持 Mermaid 图表 (客户端渲染 SVG+PNG)、LaTeX 数学公式、真实超链接、增强表格格式、代码高亮和引用块。",
|
||||||
"downloads": 31,
|
"downloads": 33,
|
||||||
"views": 929,
|
"views": 955,
|
||||||
"upvotes": 8,
|
"upvotes": 8,
|
||||||
"saves": 2,
|
"saves": 2,
|
||||||
"comments": 1,
|
"comments": 1,
|
||||||
@@ -147,8 +147,8 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"author": "Fu-Jie",
|
"author": "Fu-Jie",
|
||||||
"description": "A comprehensive thinking lens that dives deep into any content - from context to logic, insights, and action paths.",
|
"description": "A comprehensive thinking lens that dives deep into any content - from context to logic, insights, and action paths.",
|
||||||
"downloads": 22,
|
"downloads": 24,
|
||||||
"views": 259,
|
"views": 272,
|
||||||
"upvotes": 3,
|
"upvotes": 3,
|
||||||
"saves": 3,
|
"saves": 3,
|
||||||
"comments": 0,
|
"comments": 0,
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
"author": "Fu-Jie",
|
"author": "Fu-Jie",
|
||||||
"description": "智能分析文本内容,生成交互式思维导图,帮助用户结构化和可视化知识。",
|
"description": "智能分析文本内容,生成交互式思维导图,帮助用户结构化和可视化知识。",
|
||||||
"downloads": 17,
|
"downloads": 17,
|
||||||
"views": 304,
|
"views": 306,
|
||||||
"upvotes": 2,
|
"upvotes": 2,
|
||||||
"saves": 1,
|
"saves": 1,
|
||||||
"comments": 0,
|
"comments": 0,
|
||||||
@@ -180,7 +180,7 @@
|
|||||||
"author": "Fu-Jie",
|
"author": "Fu-Jie",
|
||||||
"description": "快速将文本提炼为精美的学习记忆卡片,支持核心要点提取与分类。",
|
"description": "快速将文本提炼为精美的学习记忆卡片,支持核心要点提取与分类。",
|
||||||
"downloads": 12,
|
"downloads": 12,
|
||||||
"views": 345,
|
"views": 349,
|
||||||
"upvotes": 4,
|
"upvotes": 4,
|
||||||
"saves": 1,
|
"saves": 1,
|
||||||
"comments": 0,
|
"comments": 0,
|
||||||
@@ -192,16 +192,16 @@
|
|||||||
"title": "异步上下文压缩",
|
"title": "异步上下文压缩",
|
||||||
"slug": "异步上下文压缩_5c0617cb",
|
"slug": "异步上下文压缩_5c0617cb",
|
||||||
"type": "filter",
|
"type": "filter",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"author": "Fu-Jie",
|
"author": "Fu-Jie",
|
||||||
"description": "通过智能摘要和消息压缩,降低长对话的 token 消耗,同时保持对话连贯性。",
|
"description": "通过智能摘要和消息压缩,降低长对话的 token 消耗,同时保持对话连贯性。",
|
||||||
"downloads": 6,
|
"downloads": 7,
|
||||||
"views": 153,
|
"views": 177,
|
||||||
"upvotes": 2,
|
"upvotes": 3,
|
||||||
"saves": 1,
|
"saves": 1,
|
||||||
"comments": 0,
|
"comments": 0,
|
||||||
"created_at": "2025-11-08",
|
"created_at": "2025-11-08",
|
||||||
"updated_at": "2026-01-07",
|
"updated_at": "2026-01-10",
|
||||||
"url": "https://openwebui.com/posts/异步上下文压缩_5c0617cb"
|
"url": "https://openwebui.com/posts/异步上下文压缩_5c0617cb"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -212,7 +212,7 @@
|
|||||||
"author": "Fu-Jie",
|
"author": "Fu-Jie",
|
||||||
"description": "全方位的思维透镜 —— 从背景全景到逻辑脉络,从深度洞察到行动路径。",
|
"description": "全方位的思维透镜 —— 从背景全景到逻辑脉络,从深度洞察到行动路径。",
|
||||||
"downloads": 1,
|
"downloads": 1,
|
||||||
"views": 86,
|
"views": 94,
|
||||||
"upvotes": 2,
|
"upvotes": 2,
|
||||||
"saves": 1,
|
"saves": 1,
|
||||||
"comments": 0,
|
"comments": 0,
|
||||||
@@ -228,10 +228,10 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"description": "",
|
"description": "",
|
||||||
"downloads": 0,
|
"downloads": 0,
|
||||||
"views": 19,
|
"views": 80,
|
||||||
"upvotes": 2,
|
"upvotes": 5,
|
||||||
"saves": 0,
|
"saves": 1,
|
||||||
"comments": 0,
|
"comments": 2,
|
||||||
"created_at": "2026-01-10",
|
"created_at": "2026-01-10",
|
||||||
"updated_at": "2026-01-10",
|
"updated_at": "2026-01-10",
|
||||||
"url": "https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960"
|
"url": "https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960"
|
||||||
@@ -242,11 +242,11 @@
|
|||||||
"name": "Fu-Jie",
|
"name": "Fu-Jie",
|
||||||
"profile_url": "https://openwebui.com/u/Fu-Jie",
|
"profile_url": "https://openwebui.com/u/Fu-Jie",
|
||||||
"profile_image": "https://community.s3.openwebui.com/uploads/users/b15d1348-4347-42b4-b815-e053342d6cb0/profile_d9510745-4bd4-4f8f-a997-4a21847d9300.webp",
|
"profile_image": "https://community.s3.openwebui.com/uploads/users/b15d1348-4347-42b4-b815-e053342d6cb0/profile_d9510745-4bd4-4f8f-a997-4a21847d9300.webp",
|
||||||
"followers": 71,
|
"followers": 75,
|
||||||
"following": 2,
|
"following": 2,
|
||||||
"total_points": 72,
|
"total_points": 77,
|
||||||
"post_points": 62,
|
"post_points": 66,
|
||||||
"comment_points": 10,
|
"comment_points": 11,
|
||||||
"contributions": 21
|
"contributions": 22
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,39 +1,39 @@
|
|||||||
# 📊 OpenWebUI Community Stats Report
|
# 📊 OpenWebUI Community Stats Report
|
||||||
|
|
||||||
> 📅 Updated: 2026-01-10 17:08
|
> 📅 Updated: 2026-01-11 02:11
|
||||||
|
|
||||||
## 📈 Overview
|
## 📈 Overview
|
||||||
|
|
||||||
| Metric | Value |
|
| Metric | Value |
|
||||||
|------|------|
|
|------|------|
|
||||||
| 📝 Total Posts | 14 |
|
| 📝 Total Posts | 14 |
|
||||||
| ⬇️ Total Downloads | 1066 |
|
| ⬇️ Total Downloads | 1087 |
|
||||||
| 👁️ Total Views | 11486 |
|
| 👁️ Total Views | 11853 |
|
||||||
| 👍 Total Upvotes | 64 |
|
| 👍 Total Upvotes | 68 |
|
||||||
| 💾 Total Saves | 66 |
|
| 💾 Total Saves | 67 |
|
||||||
| 💬 Total Comments | 15 |
|
| 💬 Total Comments | 17 |
|
||||||
|
|
||||||
## 📂 By Type
|
## 📂 By Type
|
||||||
|
|
||||||
|
- **filter**: 2
|
||||||
- **unknown**: 1
|
- **unknown**: 1
|
||||||
- **action**: 11
|
- **action**: 11
|
||||||
- **filter**: 2
|
|
||||||
|
|
||||||
## 📋 Posts List
|
## 📋 Posts List
|
||||||
|
|
||||||
| Rank | Title | Type | Version | Downloads | Views | Upvotes | Saves | Updated |
|
| Rank | Title | Type | Version | Downloads | Views | Upvotes | Saves | Updated |
|
||||||
|:---:|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
|:---:|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||||
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.1 | 341 | 3080 | 10 | 21 | 2026-01-07 |
|
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.1 | 348 | 3165 | 10 | 21 | 2026-01-07 |
|
||||||
| 2 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | 0.3.7 | 181 | 551 | 3 | 4 | 2026-01-07 |
|
| 2 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | 0.3.7 | 181 | 559 | 3 | 4 | 2026-01-07 |
|
||||||
| 3 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | filter | 1.1.0 | 125 | 1390 | 5 | 9 | 2026-01-07 |
|
| 3 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | filter | 1.1.1 | 128 | 1437 | 5 | 9 | 2026-01-10 |
|
||||||
| 4 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.4.1 | 116 | 1355 | 7 | 9 | 2026-01-07 |
|
| 4 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.4.1 | 120 | 1393 | 7 | 9 | 2026-01-07 |
|
||||||
| 5 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | 0.2.4 | 92 | 1735 | 8 | 6 | 2026-01-07 |
|
| 5 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | 0.2.4 | 94 | 1766 | 8 | 6 | 2026-01-07 |
|
||||||
| 6 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.3 | 87 | 800 | 5 | 8 | 2026-01-07 |
|
| 6 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.3 | 87 | 814 | 5 | 8 | 2026-01-07 |
|
||||||
| 7 | [📊 智能信息图 (AntV Infographic)](https://openwebui.com/posts/智能信息图_e04a48ff) | action | 1.4.1 | 35 | 480 | 3 | 0 | 2026-01-07 |
|
| 7 | [📊 智能信息图 (AntV Infographic)](https://openwebui.com/posts/智能信息图_e04a48ff) | action | 1.4.1 | 35 | 486 | 3 | 0 | 2026-01-07 |
|
||||||
| 8 | [导出为 Word (增强版)](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | 0.4.3 | 31 | 929 | 8 | 2 | 2026-01-07 |
|
| 8 | [导出为 Word (增强版)](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | 0.4.3 | 33 | 955 | 8 | 2 | 2026-01-07 |
|
||||||
| 9 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | 1.0.0 | 22 | 259 | 3 | 3 | 2026-01-08 |
|
| 9 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | 1.0.0 | 24 | 272 | 3 | 3 | 2026-01-08 |
|
||||||
| 10 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | 0.9.1 | 17 | 304 | 2 | 1 | 2026-01-07 |
|
| 10 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | 0.9.1 | 17 | 306 | 2 | 1 | 2026-01-07 |
|
||||||
| 11 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 12 | 345 | 4 | 1 | 2026-01-07 |
|
| 11 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 12 | 349 | 4 | 1 | 2026-01-07 |
|
||||||
| 12 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | filter | 1.1.0 | 6 | 153 | 2 | 1 | 2026-01-07 |
|
| 12 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | filter | 1.1.1 | 7 | 177 | 3 | 1 | 2026-01-10 |
|
||||||
| 13 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | 1.0.0 | 1 | 86 | 2 | 1 | 2026-01-08 |
|
| 13 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | 1.0.0 | 1 | 94 | 2 | 1 | 2026-01-08 |
|
||||||
| 14 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | unknown | | 0 | 19 | 2 | 0 | 2026-01-10 |
|
| 14 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | unknown | | 0 | 80 | 5 | 1 | 2026-01-10 |
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
# 📊 OpenWebUI 社区统计报告
|
# 📊 OpenWebUI 社区统计报告
|
||||||
|
|
||||||
> 📅 更新时间: 2026-01-10 17:08
|
> 📅 更新时间: 2026-01-11 02:11
|
||||||
|
|
||||||
## 📈 总览
|
## 📈 总览
|
||||||
|
|
||||||
| 指标 | 数值 |
|
| 指标 | 数值 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| 📝 发布数量 | 14 |
|
| 📝 发布数量 | 14 |
|
||||||
| ⬇️ 总下载量 | 1066 |
|
| ⬇️ 总下载量 | 1087 |
|
||||||
| 👁️ 总浏览量 | 11486 |
|
| 👁️ 总浏览量 | 11853 |
|
||||||
| 👍 总点赞数 | 64 |
|
| 👍 总点赞数 | 68 |
|
||||||
| 💾 总收藏数 | 66 |
|
| 💾 总收藏数 | 67 |
|
||||||
| 💬 总评论数 | 15 |
|
| 💬 总评论数 | 17 |
|
||||||
|
|
||||||
## 📂 按类型分类
|
## 📂 按类型分类
|
||||||
|
|
||||||
|
- **filter**: 2
|
||||||
- **unknown**: 1
|
- **unknown**: 1
|
||||||
- **action**: 11
|
- **action**: 11
|
||||||
- **filter**: 2
|
|
||||||
|
|
||||||
## 📋 发布列表
|
## 📋 发布列表
|
||||||
|
|
||||||
| 排名 | 标题 | 类型 | 版本 | 下载 | 浏览 | 点赞 | 收藏 | 更新日期 |
|
| 排名 | 标题 | 类型 | 版本 | 下载 | 浏览 | 点赞 | 收藏 | 更新日期 |
|
||||||
|:---:|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
|:---:|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||||
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.1 | 341 | 3080 | 10 | 21 | 2026-01-07 |
|
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.1 | 348 | 3165 | 10 | 21 | 2026-01-07 |
|
||||||
| 2 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | 0.3.7 | 181 | 551 | 3 | 4 | 2026-01-07 |
|
| 2 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | 0.3.7 | 181 | 559 | 3 | 4 | 2026-01-07 |
|
||||||
| 3 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | filter | 1.1.0 | 125 | 1390 | 5 | 9 | 2026-01-07 |
|
| 3 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | filter | 1.1.1 | 128 | 1437 | 5 | 9 | 2026-01-10 |
|
||||||
| 4 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.4.1 | 116 | 1355 | 7 | 9 | 2026-01-07 |
|
| 4 | [📊 Smart Infographic (AntV)](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.4.1 | 120 | 1393 | 7 | 9 | 2026-01-07 |
|
||||||
| 5 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | 0.2.4 | 92 | 1735 | 8 | 6 | 2026-01-07 |
|
| 5 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | 0.2.4 | 94 | 1766 | 8 | 6 | 2026-01-07 |
|
||||||
| 6 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.3 | 87 | 800 | 5 | 8 | 2026-01-07 |
|
| 6 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.3 | 87 | 814 | 5 | 8 | 2026-01-07 |
|
||||||
| 7 | [📊 智能信息图 (AntV Infographic)](https://openwebui.com/posts/智能信息图_e04a48ff) | action | 1.4.1 | 35 | 480 | 3 | 0 | 2026-01-07 |
|
| 7 | [📊 智能信息图 (AntV Infographic)](https://openwebui.com/posts/智能信息图_e04a48ff) | action | 1.4.1 | 35 | 486 | 3 | 0 | 2026-01-07 |
|
||||||
| 8 | [导出为 Word (增强版)](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | 0.4.3 | 31 | 929 | 8 | 2 | 2026-01-07 |
|
| 8 | [导出为 Word (增强版)](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | 0.4.3 | 33 | 955 | 8 | 2 | 2026-01-07 |
|
||||||
| 9 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | 1.0.0 | 22 | 259 | 3 | 3 | 2026-01-08 |
|
| 9 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | 1.0.0 | 24 | 272 | 3 | 3 | 2026-01-08 |
|
||||||
| 10 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | 0.9.1 | 17 | 304 | 2 | 1 | 2026-01-07 |
|
| 10 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | 0.9.1 | 17 | 306 | 2 | 1 | 2026-01-07 |
|
||||||
| 11 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 12 | 345 | 4 | 1 | 2026-01-07 |
|
| 11 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 12 | 349 | 4 | 1 | 2026-01-07 |
|
||||||
| 12 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | filter | 1.1.0 | 6 | 153 | 2 | 1 | 2026-01-07 |
|
| 12 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | filter | 1.1.1 | 7 | 177 | 3 | 1 | 2026-01-10 |
|
||||||
| 13 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | 1.0.0 | 1 | 86 | 2 | 1 | 2026-01-08 |
|
| 13 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | 1.0.0 | 1 | 94 | 2 | 1 | 2026-01-08 |
|
||||||
| 14 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | unknown | | 0 | 19 | 2 | 0 | 2026-01-10 |
|
| 14 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | unknown | | 0 | 80 | 5 | 1 | 2026-01-10 |
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Async Context Compression
|
# Async Context Compression
|
||||||
|
|
||||||
<span class="category-badge filter">Filter</span>
|
<span class="category-badge filter">Filter</span>
|
||||||
<span class="version-badge">v1.1.0</span>
|
<span class="version-badge">v1.1.2</span>
|
||||||
|
|
||||||
Reduces token consumption in long conversations through intelligent summarization while maintaining conversational coherence.
|
Reduces token consumption in long conversations through intelligent summarization while maintaining conversational coherence.
|
||||||
|
|
||||||
@@ -29,6 +29,9 @@ This is especially useful for:
|
|||||||
- :material-clock-fast: **Async Processing**: Non-blocking background compression
|
- :material-clock-fast: **Async Processing**: Non-blocking background compression
|
||||||
- :material-memory: **Context Preservation**: Keeps important information
|
- :material-memory: **Context Preservation**: Keeps important information
|
||||||
- :material-currency-usd-off: **Cost Reduction**: Minimize token usage
|
- :material-currency-usd-off: **Cost Reduction**: Minimize token usage
|
||||||
|
- :material-console: **Frontend Debugging**: Debug logs in browser console
|
||||||
|
- :material-alert-circle-check: **Enhanced Error Reporting**: Clear error status notifications
|
||||||
|
- :material-check-all: **Open WebUI v0.7.x Compatibility**: Dynamic DB session handling
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Async Context Compression(异步上下文压缩)
|
# Async Context Compression(异步上下文压缩)
|
||||||
|
|
||||||
<span class="category-badge filter">Filter</span>
|
<span class="category-badge filter">Filter</span>
|
||||||
<span class="version-badge">v1.1.0</span>
|
<span class="version-badge">v1.1.2</span>
|
||||||
|
|
||||||
通过智能摘要减少长对话的 token 消耗,同时保持对话连贯。
|
通过智能摘要减少长对话的 token 消耗,同时保持对话连贯。
|
||||||
|
|
||||||
@@ -29,6 +29,9 @@ Async Context Compression 过滤器通过以下方式帮助管理长对话的 to
|
|||||||
- :material-clock-fast: **异步处理**:后台非阻塞压缩
|
- :material-clock-fast: **异步处理**:后台非阻塞压缩
|
||||||
- :material-memory: **保留上下文**:尽量保留重要信息
|
- :material-memory: **保留上下文**:尽量保留重要信息
|
||||||
- :material-currency-usd-off: **降低成本**:减少 token 使用
|
- :material-currency-usd-off: **降低成本**:减少 token 使用
|
||||||
|
- :material-console: **前端调试**:支持浏览器控制台日志
|
||||||
|
- :material-alert-circle-check: **增强错误报告**:清晰的错误状态通知
|
||||||
|
- :material-check-all: **Open WebUI v0.7.x 兼容性**:动态数据库会话处理
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Filters act as middleware in the message pipeline:
|
|||||||
|
|
||||||
Reduces token consumption in long conversations through intelligent summarization while maintaining coherence.
|
Reduces token consumption in long conversations through intelligent summarization while maintaining coherence.
|
||||||
|
|
||||||
**Version:** 1.1.0
|
**Version:** 1.1.2
|
||||||
|
|
||||||
[:octicons-arrow-right-24: Documentation](async-context-compression.md)
|
[:octicons-arrow-right-24: Documentation](async-context-compression.md)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
# Async Context Compression Filter
|
# Async Context Compression Filter
|
||||||
|
|
||||||
**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** 1.1.0 | **License:** MIT
|
**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** 1.1.2 | **License:** MIT
|
||||||
|
|
||||||
This filter reduces token consumption in long conversations through intelligent summarization and message compression while keeping conversations coherent.
|
This filter reduces token consumption in long conversations through intelligent summarization and message compression while keeping conversations coherent.
|
||||||
|
|
||||||
|
## What's new in 1.1.2
|
||||||
|
|
||||||
|
- **Open WebUI v0.7.x Compatibility**: Resolved a critical database session binding error affecting Open WebUI v0.7.x users. The plugin now dynamically discovers the database engine and session context, ensuring compatibility across versions.
|
||||||
|
- **Enhanced Error Reporting**: Errors during background summary generation are now reported via both the status bar and browser console.
|
||||||
|
- **Robust Model Handling**: Improved handling of missing or invalid model IDs to prevent crashes.
|
||||||
|
|
||||||
|
## What's new in 1.1.1
|
||||||
|
|
||||||
|
- **Frontend Debugging**: Added `show_debug_log` option to print debug info to the browser console (F12).
|
||||||
|
- **Optimized Compression**: Improved token calculation logic to prevent aggressive truncation of history, ensuring more context is retained.
|
||||||
|
|
||||||
## What's new in 1.1.0
|
## What's new in 1.1.0
|
||||||
|
|
||||||
- Reuses Open WebUI's shared database connection by default (no custom engine or env vars required).
|
- Reuses Open WebUI's shared database connection by default (no custom engine or env vars required).
|
||||||
@@ -54,6 +65,7 @@ It is recommended to keep this filter early in the chain so it runs before filte
|
|||||||
| `summary_temperature` | `0.3` | Randomness for summary generation. Lower is more deterministic. |
|
| `summary_temperature` | `0.3` | Randomness for summary generation. Lower is more deterministic. |
|
||||||
| `model_thresholds` | `{}` | Per-model overrides for `compression_threshold_tokens` and `max_context_tokens` (useful for mixed models). |
|
| `model_thresholds` | `{}` | Per-model overrides for `compression_threshold_tokens` and `max_context_tokens` (useful for mixed models). |
|
||||||
| `debug_mode` | `true` | Log verbose debug info. Set to `false` in production. |
|
| `debug_mode` | `true` | Log verbose debug info. Set to `false` in production. |
|
||||||
|
| `show_debug_log` | `false` | Print debug logs to browser console (F12). Useful for frontend debugging. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,22 @@
|
|||||||
# 异步上下文压缩过滤器
|
# 异步上下文压缩过滤器
|
||||||
|
|
||||||
**作者:** [Fu-Jie](https://github.com/Fu-Jie) | **版本:** 1.2.0 | **许可证:** MIT
|
**作者:** [Fu-Jie](https://github.com/Fu-Jie) | **版本:** 1.1.2 | **许可证:** MIT
|
||||||
|
|
||||||
> **重要提示**:为了确保所有过滤器的可维护性和易用性,每个过滤器都应附带清晰、完整的文档,以确保其功能、配置和使用方法得到充分说明。
|
> **重要提示**:为了确保所有过滤器的可维护性和易用性,每个过滤器都应附带清晰、完整的文档,以确保其功能、配置和使用方法得到充分说明。
|
||||||
|
|
||||||
本过滤器通过智能摘要和消息压缩技术,在保持对话连贯性的同时,显著降低长对话的 Token 消耗。
|
本过滤器通过智能摘要和消息压缩技术,在保持对话连贯性的同时,显著降低长对话的 Token 消耗。
|
||||||
|
|
||||||
|
## 1.1.2 版本更新
|
||||||
|
|
||||||
|
- **Open WebUI v0.7.x 兼容性**: 修复了影响 Open WebUI v0.7.x 用户的严重数据库会话绑定错误。插件现在动态发现数据库引擎和会话上下文,确保跨版本兼容性。
|
||||||
|
- **增强错误报告**: 后台摘要生成过程中的错误现在会通过状态栏和浏览器控制台同时报告。
|
||||||
|
- **健壮的模型处理**: 改进了对缺失或无效模型 ID 的处理,防止程序崩溃。
|
||||||
|
|
||||||
|
## 1.1.1 版本更新
|
||||||
|
|
||||||
|
- **前端调试**: 新增 `show_debug_log` 选项,支持在浏览器控制台 (F12) 打印调试信息。
|
||||||
|
- **压缩优化**: 优化 Token 计算逻辑,防止历史记录被过度截断,保留更多上下文。
|
||||||
|
|
||||||
## 1.1.0 版本更新
|
## 1.1.0 版本更新
|
||||||
|
|
||||||
- 默认复用 OpenWebUI 内置数据库连接,无需自建引擎、无需配置 `DATABASE_URL`。
|
- 默认复用 OpenWebUI 内置数据库连接,无需自建引擎、无需配置 `DATABASE_URL`。
|
||||||
@@ -94,6 +105,11 @@
|
|||||||
- **默认值**: `true`
|
- **默认值**: `true`
|
||||||
- **描述**: 是否在 Open WebUI 的控制台日志中打印详细的调试信息(如 Token 计数、压缩进度、数据库操作等)。生产环境建议设为 `false`。
|
- **描述**: 是否在 Open WebUI 的控制台日志中打印详细的调试信息(如 Token 计数、压缩进度、数据库操作等)。生产环境建议设为 `false`。
|
||||||
|
|
||||||
|
#### `show_debug_log`
|
||||||
|
|
||||||
|
- **默认值**: `false`
|
||||||
|
- **描述**: 是否在浏览器控制台 (F12) 打印调试日志。便于前端调试。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 故障排除
|
## 故障排除
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ author: Fu-Jie
|
|||||||
author_url: https://github.com/Fu-Jie
|
author_url: https://github.com/Fu-Jie
|
||||||
funding_url: https://github.com/Fu-Jie/awesome-openwebui
|
funding_url: https://github.com/Fu-Jie/awesome-openwebui
|
||||||
description: Reduces token consumption in long conversations while maintaining coherence through intelligent summarization and message compression.
|
description: Reduces token consumption in long conversations while maintaining coherence through intelligent summarization and message compression.
|
||||||
version: 1.1.1
|
version: 1.1.2
|
||||||
openwebui_id: b1655bc8-6de9-4cad-8cb5-a6f7829a02ce
|
openwebui_id: b1655bc8-6de9-4cad-8cb5-a6f7829a02ce
|
||||||
license: MIT
|
license: MIT
|
||||||
|
|
||||||
@@ -249,6 +249,7 @@ import asyncio
|
|||||||
import json
|
import json
|
||||||
import hashlib
|
import hashlib
|
||||||
import time
|
import time
|
||||||
|
import contextlib
|
||||||
|
|
||||||
# Open WebUI built-in imports
|
# Open WebUI built-in imports
|
||||||
from open_webui.utils.chat import generate_chat_completion
|
from open_webui.utils.chat import generate_chat_completion
|
||||||
@@ -257,9 +258,10 @@ from fastapi.requests import Request
|
|||||||
from open_webui.main import app as webui_app
|
from open_webui.main import app as webui_app
|
||||||
|
|
||||||
# Open WebUI internal database (re-use shared connection)
|
# Open WebUI internal database (re-use shared connection)
|
||||||
from open_webui.internal.db import engine as owui_engine
|
try:
|
||||||
from open_webui.internal.db import Session as owui_Session
|
from open_webui.internal import db as owui_db
|
||||||
from open_webui.internal.db import Base as owui_Base
|
except ModuleNotFoundError: # pragma: no cover - filter runs inside Open WebUI
|
||||||
|
owui_db = None
|
||||||
|
|
||||||
# Try to import tiktoken
|
# Try to import tiktoken
|
||||||
try:
|
try:
|
||||||
@@ -269,14 +271,91 @@ except ImportError:
|
|||||||
|
|
||||||
# Database imports
|
# Database imports
|
||||||
from sqlalchemy import Column, String, Text, DateTime, Integer, inspect
|
from sqlalchemy import Column, String, Text, DateTime, Integer, inspect
|
||||||
|
from sqlalchemy.orm import declarative_base, sessionmaker
|
||||||
|
from sqlalchemy.engine import Engine
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
def _discover_owui_engine(db_module: Any) -> Optional[Engine]:
|
||||||
|
"""Discover the Open WebUI SQLAlchemy engine via provided db module helpers."""
|
||||||
|
if db_module is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
db_context = getattr(db_module, "get_db_context", None) or getattr(
|
||||||
|
db_module, "get_db", None
|
||||||
|
)
|
||||||
|
if callable(db_context):
|
||||||
|
try:
|
||||||
|
with db_context() as session:
|
||||||
|
try:
|
||||||
|
return session.get_bind()
|
||||||
|
except AttributeError:
|
||||||
|
return getattr(session, "bind", None) or getattr(
|
||||||
|
session, "engine", None
|
||||||
|
)
|
||||||
|
except Exception as exc:
|
||||||
|
print(f"[DB Discover] get_db_context failed: {exc}")
|
||||||
|
|
||||||
|
for attr in ("engine", "ENGINE", "bind", "BIND"):
|
||||||
|
candidate = getattr(db_module, attr, None)
|
||||||
|
if candidate is not None:
|
||||||
|
return candidate
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _discover_owui_schema(db_module: Any) -> Optional[str]:
|
||||||
|
"""Discover the Open WebUI database schema name if configured."""
|
||||||
|
if db_module is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
base = getattr(db_module, "Base", None)
|
||||||
|
metadata = getattr(base, "metadata", None) if base is not None else None
|
||||||
|
candidate = getattr(metadata, "schema", None) if metadata is not None else None
|
||||||
|
if isinstance(candidate, str) and candidate.strip():
|
||||||
|
return candidate.strip()
|
||||||
|
except Exception as exc:
|
||||||
|
print(f"[DB Discover] Base metadata schema lookup failed: {exc}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
metadata_obj = getattr(db_module, "metadata_obj", None)
|
||||||
|
candidate = (
|
||||||
|
getattr(metadata_obj, "schema", None) if metadata_obj is not None else None
|
||||||
|
)
|
||||||
|
if isinstance(candidate, str) and candidate.strip():
|
||||||
|
return candidate.strip()
|
||||||
|
except Exception as exc:
|
||||||
|
print(f"[DB Discover] metadata_obj schema lookup failed: {exc}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
from open_webui import env as owui_env
|
||||||
|
|
||||||
|
candidate = getattr(owui_env, "DATABASE_SCHEMA", None)
|
||||||
|
if isinstance(candidate, str) and candidate.strip():
|
||||||
|
return candidate.strip()
|
||||||
|
except Exception as exc:
|
||||||
|
print(f"[DB Discover] env schema lookup failed: {exc}")
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
owui_engine = _discover_owui_engine(owui_db)
|
||||||
|
owui_schema = _discover_owui_schema(owui_db)
|
||||||
|
owui_Base = getattr(owui_db, "Base", None) if owui_db is not None else None
|
||||||
|
if owui_Base is None:
|
||||||
|
owui_Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
class ChatSummary(owui_Base):
|
class ChatSummary(owui_Base):
|
||||||
"""Chat Summary Storage Table"""
|
"""Chat Summary Storage Table"""
|
||||||
|
|
||||||
__tablename__ = "chat_summary"
|
__tablename__ = "chat_summary"
|
||||||
__table_args__ = {"extend_existing": True}
|
__table_args__ = (
|
||||||
|
{"extend_existing": True, "schema": owui_schema}
|
||||||
|
if owui_schema
|
||||||
|
else {"extend_existing": True}
|
||||||
|
)
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||||
chat_id = Column(String(255), unique=True, nullable=False, index=True)
|
chat_id = Column(String(255), unique=True, nullable=False, index=True)
|
||||||
@@ -289,14 +368,66 @@ class ChatSummary(owui_Base):
|
|||||||
class Filter:
|
class Filter:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.valves = self.Valves()
|
self.valves = self.Valves()
|
||||||
|
self._owui_db = owui_db
|
||||||
self._db_engine = owui_engine
|
self._db_engine = owui_engine
|
||||||
self._SessionLocal = owui_Session
|
|
||||||
self.temp_state = {} # Used to pass temporary data between inlet and outlet
|
self.temp_state = {} # Used to pass temporary data between inlet and outlet
|
||||||
|
self._fallback_session_factory = (
|
||||||
|
sessionmaker(bind=self._db_engine) if self._db_engine else None
|
||||||
|
)
|
||||||
self._init_database()
|
self._init_database()
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def _db_session(self):
|
||||||
|
"""Yield a database session using Open WebUI helpers with graceful fallbacks."""
|
||||||
|
db_module = self._owui_db
|
||||||
|
db_context = None
|
||||||
|
if db_module is not None:
|
||||||
|
db_context = getattr(db_module, "get_db_context", None) or getattr(
|
||||||
|
db_module, "get_db", None
|
||||||
|
)
|
||||||
|
|
||||||
|
if callable(db_context):
|
||||||
|
with db_context() as session:
|
||||||
|
yield session
|
||||||
|
return
|
||||||
|
|
||||||
|
factory = None
|
||||||
|
if db_module is not None:
|
||||||
|
factory = getattr(db_module, "SessionLocal", None) or getattr(
|
||||||
|
db_module, "ScopedSession", None
|
||||||
|
)
|
||||||
|
if callable(factory):
|
||||||
|
session = factory()
|
||||||
|
try:
|
||||||
|
yield session
|
||||||
|
finally:
|
||||||
|
close = getattr(session, "close", None)
|
||||||
|
if callable(close):
|
||||||
|
close()
|
||||||
|
return
|
||||||
|
|
||||||
|
if self._fallback_session_factory is None:
|
||||||
|
raise RuntimeError(
|
||||||
|
"Open WebUI database session is unavailable. Ensure Open WebUI's database layer is initialized."
|
||||||
|
)
|
||||||
|
|
||||||
|
session = self._fallback_session_factory()
|
||||||
|
try:
|
||||||
|
yield session
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
session.close()
|
||||||
|
except Exception as exc: # pragma: no cover - best-effort cleanup
|
||||||
|
print(f"[Database] ⚠️ Failed to close fallback session: {exc}")
|
||||||
|
|
||||||
def _init_database(self):
|
def _init_database(self):
|
||||||
"""Initializes the database table using Open WebUI's shared connection."""
|
"""Initializes the database table using Open WebUI's shared connection."""
|
||||||
try:
|
try:
|
||||||
|
if self._db_engine is None:
|
||||||
|
raise RuntimeError(
|
||||||
|
"Open WebUI database engine is unavailable. Ensure Open WebUI is configured with a valid DATABASE_URL."
|
||||||
|
)
|
||||||
|
|
||||||
# Check if table exists using SQLAlchemy inspect
|
# Check if table exists using SQLAlchemy inspect
|
||||||
inspector = inspect(self._db_engine)
|
inspector = inspect(self._db_engine)
|
||||||
if not inspector.has_table("chat_summary"):
|
if not inspector.has_table("chat_summary"):
|
||||||
@@ -366,7 +497,7 @@ class Filter:
|
|||||||
def _save_summary(self, chat_id: str, summary: str, compressed_count: int):
|
def _save_summary(self, chat_id: str, summary: str, compressed_count: int):
|
||||||
"""Saves the summary to the database."""
|
"""Saves the summary to the database."""
|
||||||
try:
|
try:
|
||||||
with self._SessionLocal() as session:
|
with self._db_session() as session:
|
||||||
# Find existing record
|
# Find existing record
|
||||||
existing = session.query(ChatSummary).filter_by(chat_id=chat_id).first()
|
existing = session.query(ChatSummary).filter_by(chat_id=chat_id).first()
|
||||||
|
|
||||||
@@ -406,7 +537,7 @@ class Filter:
|
|||||||
def _load_summary_record(self, chat_id: str) -> Optional[ChatSummary]:
|
def _load_summary_record(self, chat_id: str) -> Optional[ChatSummary]:
|
||||||
"""Loads the summary record object from the database."""
|
"""Loads the summary record object from the database."""
|
||||||
try:
|
try:
|
||||||
with self._SessionLocal() as session:
|
with self._db_session() as session:
|
||||||
record = session.query(ChatSummary).filter_by(chat_id=chat_id).first()
|
record = session.query(ChatSummary).filter_by(chat_id=chat_id).first()
|
||||||
if record:
|
if record:
|
||||||
# Detach the object from the session so it can be used after session close
|
# Detach the object from the session so it can be used after session close
|
||||||
@@ -487,6 +618,26 @@ class Filter:
|
|||||||
"max_context_tokens": self.valves.max_context_tokens,
|
"max_context_tokens": self.valves.max_context_tokens,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _extract_chat_id(self, body: dict, metadata: Optional[dict]) -> str:
|
||||||
|
"""Extract chat_id from body or metadata."""
|
||||||
|
if isinstance(body, dict):
|
||||||
|
chat_id = body.get("chat_id")
|
||||||
|
if isinstance(chat_id, str) and chat_id.strip():
|
||||||
|
return chat_id.strip()
|
||||||
|
|
||||||
|
body_metadata = body.get("metadata", {})
|
||||||
|
if isinstance(body_metadata, dict):
|
||||||
|
chat_id = body_metadata.get("chat_id")
|
||||||
|
if isinstance(chat_id, str) and chat_id.strip():
|
||||||
|
return chat_id.strip()
|
||||||
|
|
||||||
|
if isinstance(metadata, dict):
|
||||||
|
chat_id = metadata.get("chat_id")
|
||||||
|
if isinstance(chat_id, str) and chat_id.strip():
|
||||||
|
return chat_id.strip()
|
||||||
|
|
||||||
|
return ""
|
||||||
|
|
||||||
def _inject_summary_to_first_message(self, message: dict, summary: str) -> dict:
|
def _inject_summary_to_first_message(self, message: dict, summary: str) -> dict:
|
||||||
"""Injects the summary into the first message (prepended to content)."""
|
"""Injects the summary into the first message (prepended to content)."""
|
||||||
content = message.get("content", "")
|
content = message.get("content", "")
|
||||||
@@ -632,7 +783,15 @@ class Filter:
|
|||||||
Compression Strategy: Only responsible for injecting existing summaries, no Token calculation.
|
Compression Strategy: Only responsible for injecting existing summaries, no Token calculation.
|
||||||
"""
|
"""
|
||||||
messages = body.get("messages", [])
|
messages = body.get("messages", [])
|
||||||
chat_id = __metadata__["chat_id"]
|
chat_id = self._extract_chat_id(body, __metadata__)
|
||||||
|
|
||||||
|
if not chat_id:
|
||||||
|
await self._log(
|
||||||
|
"[Inlet] ❌ Missing chat_id in metadata, skipping compression",
|
||||||
|
type="error",
|
||||||
|
event_call=__event_call__,
|
||||||
|
)
|
||||||
|
return body
|
||||||
|
|
||||||
if self.valves.debug_mode or self.valves.show_debug_log:
|
if self.valves.debug_mode or self.valves.show_debug_log:
|
||||||
await self._log(
|
await self._log(
|
||||||
@@ -747,7 +906,14 @@ class Filter:
|
|||||||
Executed after the LLM response is complete.
|
Executed after the LLM response is complete.
|
||||||
Calculates Token count in the background and triggers summary generation (does not block current response, does not affect content output).
|
Calculates Token count in the background and triggers summary generation (does not block current response, does not affect content output).
|
||||||
"""
|
"""
|
||||||
chat_id = __metadata__["chat_id"]
|
chat_id = self._extract_chat_id(body, __metadata__)
|
||||||
|
if not chat_id:
|
||||||
|
await self._log(
|
||||||
|
"[Outlet] ❌ Missing chat_id in metadata, skipping compression",
|
||||||
|
type="error",
|
||||||
|
event_call=__event_call__,
|
||||||
|
)
|
||||||
|
return body
|
||||||
model = body.get("model", "gpt-3.5-turbo")
|
model = body.get("model", "gpt-3.5-turbo")
|
||||||
|
|
||||||
if self.valves.debug_mode or self.valves.show_debug_log:
|
if self.valves.debug_mode or self.valves.show_debug_log:
|
||||||
@@ -836,6 +1002,13 @@ class Filter:
|
|||||||
event_call=__event_call__,
|
event_call=__event_call__,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _clean_model_id(self, model_id: Optional[str]) -> Optional[str]:
|
||||||
|
"""Cleans the model ID by removing whitespace and quotes."""
|
||||||
|
if not model_id:
|
||||||
|
return None
|
||||||
|
cleaned = model_id.strip().strip('"').strip("'")
|
||||||
|
return cleaned if cleaned else None
|
||||||
|
|
||||||
async def _generate_summary_async(
|
async def _generate_summary_async(
|
||||||
self,
|
self,
|
||||||
messages: list,
|
messages: list,
|
||||||
@@ -892,9 +1065,17 @@ class Filter:
|
|||||||
# 3. Check Token limit and truncate (Max Context Truncation)
|
# 3. Check Token limit and truncate (Max Context Truncation)
|
||||||
# [Optimization] Use the summary model's (if any) threshold to decide how many middle messages can be processed
|
# [Optimization] Use the summary model's (if any) threshold to decide how many middle messages can be processed
|
||||||
# This allows using a long-window model (like gemini-flash) to compress history exceeding the current model's window
|
# This allows using a long-window model (like gemini-flash) to compress history exceeding the current model's window
|
||||||
summary_model_id = self.valves.summary_model or body.get(
|
summary_model_id = self._clean_model_id(
|
||||||
"model", "gpt-3.5-turbo"
|
self.valves.summary_model
|
||||||
|
) or self._clean_model_id(body.get("model"))
|
||||||
|
|
||||||
|
if not summary_model_id:
|
||||||
|
await self._log(
|
||||||
|
"[🤖 Async Summary Task] ⚠️ Summary model does not exist, skipping compression",
|
||||||
|
type="warning",
|
||||||
|
event_call=__event_call__,
|
||||||
)
|
)
|
||||||
|
return
|
||||||
|
|
||||||
thresholds = self._get_model_thresholds(summary_model_id)
|
thresholds = self._get_model_thresholds(summary_model_id)
|
||||||
# Note: Using the summary model's max context limit here
|
# Note: Using the summary model's max context limit here
|
||||||
@@ -966,9 +1147,21 @@ class Filter:
|
|||||||
)
|
)
|
||||||
|
|
||||||
new_summary = await self._call_summary_llm(
|
new_summary = await self._call_summary_llm(
|
||||||
None, conversation_text, body, user_data, __event_call__
|
None,
|
||||||
|
conversation_text,
|
||||||
|
{**body, "model": summary_model_id},
|
||||||
|
user_data,
|
||||||
|
__event_call__,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not new_summary:
|
||||||
|
await self._log(
|
||||||
|
"[🤖 Async Summary Task] ⚠️ Summary generation returned empty result, skipping save",
|
||||||
|
type="warning",
|
||||||
|
event_call=__event_call__,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
# 6. Save new summary
|
# 6. Save new summary
|
||||||
await self._log(
|
await self._log(
|
||||||
"[Optimization] Saving summary in a background thread to avoid blocking the event loop.",
|
"[Optimization] Saving summary in a background thread to avoid blocking the event loop.",
|
||||||
@@ -1007,6 +1200,18 @@ class Filter:
|
|||||||
type="error",
|
type="error",
|
||||||
event_call=__event_call__,
|
event_call=__event_call__,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if __event_emitter__:
|
||||||
|
await __event_emitter__(
|
||||||
|
{
|
||||||
|
"type": "status",
|
||||||
|
"data": {
|
||||||
|
"description": f"Summary Error: {str(e)[:100]}...",
|
||||||
|
"done": True,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
@@ -1088,7 +1293,17 @@ This conversation may contain previous summaries (as system messages or text) an
|
|||||||
Based on the content above, generate the summary:
|
Based on the content above, generate the summary:
|
||||||
"""
|
"""
|
||||||
# Determine the model to use
|
# Determine the model to use
|
||||||
model = self.valves.summary_model or body.get("model", "")
|
model = self._clean_model_id(self.valves.summary_model) or self._clean_model_id(
|
||||||
|
body.get("model")
|
||||||
|
)
|
||||||
|
|
||||||
|
if not model:
|
||||||
|
await self._log(
|
||||||
|
"[🤖 LLM Call] ⚠️ Summary model does not exist, skipping summary generation",
|
||||||
|
type="warning",
|
||||||
|
event_call=__event_call__,
|
||||||
|
)
|
||||||
|
return ""
|
||||||
|
|
||||||
await self._log(f"[🤖 LLM Call] Model: {model}", event_call=__event_call__)
|
await self._log(f"[🤖 LLM Call] Model: {model}", event_call=__event_call__)
|
||||||
|
|
||||||
@@ -1142,7 +1357,12 @@ Based on the content above, generate the summary:
|
|||||||
return summary
|
return summary
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_message = f"Error occurred while calling LLM ({model}) to generate summary: {str(e)}"
|
error_msg = str(e)
|
||||||
|
# Handle specific error messages
|
||||||
|
if "Model not found" in error_msg:
|
||||||
|
error_message = f"Summary model '{model}' not found."
|
||||||
|
else:
|
||||||
|
error_message = f"Summary LLM Error ({model}): {error_msg}"
|
||||||
if not self.valves.summary_model:
|
if not self.valves.summary_model:
|
||||||
error_message += (
|
error_message += (
|
||||||
"\n[Hint] You did not specify a summary_model, so the filter attempted to use the current conversation's model. "
|
"\n[Hint] You did not specify a summary_model, so the filter attempted to use the current conversation's model. "
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ author: Fu-Jie
|
|||||||
author_url: https://github.com/Fu-Jie
|
author_url: https://github.com/Fu-Jie
|
||||||
funding_url: https://github.com/Fu-Jie/awesome-openwebui
|
funding_url: https://github.com/Fu-Jie/awesome-openwebui
|
||||||
description: 通过智能摘要和消息压缩,降低长对话的 token 消耗,同时保持对话连贯性。
|
description: 通过智能摘要和消息压缩,降低长对话的 token 消耗,同时保持对话连贯性。
|
||||||
version: 1.1.1
|
version: 1.1.2
|
||||||
openwebui_id: 5c0617cb-a9e4-4bd6-a440-d276534ebd18
|
openwebui_id: 5c0617cb-a9e4-4bd6-a440-d276534ebd18
|
||||||
license: MIT
|
license: MIT
|
||||||
|
|
||||||
@@ -820,6 +820,13 @@ class Filter:
|
|||||||
event_call=__event_call__,
|
event_call=__event_call__,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _clean_model_id(self, model_id: Optional[str]) -> Optional[str]:
|
||||||
|
"""Cleans the model ID by removing whitespace and quotes."""
|
||||||
|
if not model_id:
|
||||||
|
return None
|
||||||
|
cleaned = model_id.strip().strip('"').strip("'")
|
||||||
|
return cleaned if cleaned else None
|
||||||
|
|
||||||
async def _generate_summary_async(
|
async def _generate_summary_async(
|
||||||
self,
|
self,
|
||||||
messages: list,
|
messages: list,
|
||||||
@@ -874,7 +881,17 @@ class Filter:
|
|||||||
# 3. 检查 Token 上限并截断 (Max Context Truncation)
|
# 3. 检查 Token 上限并截断 (Max Context Truncation)
|
||||||
# [优化] 使用摘要模型(如果有)的阈值来决定能处理多少中间消息
|
# [优化] 使用摘要模型(如果有)的阈值来决定能处理多少中间消息
|
||||||
# 这样可以用长窗口模型(如 gemini-flash)来压缩超过当前模型窗口的历史记录
|
# 这样可以用长窗口模型(如 gemini-flash)来压缩超过当前模型窗口的历史记录
|
||||||
summary_model_id = self.valves.summary_model or body.get("model")
|
summary_model_id = self._clean_model_id(
|
||||||
|
self.valves.summary_model
|
||||||
|
) or self._clean_model_id(body.get("model"))
|
||||||
|
|
||||||
|
if not summary_model_id:
|
||||||
|
await self._log(
|
||||||
|
"[🤖 异步摘要任务] ⚠️ 摘要模型不存在,跳过压缩",
|
||||||
|
type="warning",
|
||||||
|
event_call=__event_call__,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
thresholds = self._get_model_thresholds(summary_model_id)
|
thresholds = self._get_model_thresholds(summary_model_id)
|
||||||
# 注意:这里使用的是摘要模型的最大上下文限制
|
# 注意:这里使用的是摘要模型的最大上下文限制
|
||||||
@@ -946,9 +963,21 @@ class Filter:
|
|||||||
)
|
)
|
||||||
|
|
||||||
new_summary = await self._call_summary_llm(
|
new_summary = await self._call_summary_llm(
|
||||||
None, conversation_text, body, user_data, __event_call__
|
None,
|
||||||
|
conversation_text,
|
||||||
|
{**body, "model": summary_model_id},
|
||||||
|
user_data,
|
||||||
|
__event_call__,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not new_summary:
|
||||||
|
await self._log(
|
||||||
|
"[🤖 异步摘要任务] ⚠️ 摘要生成返回空结果,跳过保存",
|
||||||
|
type="warning",
|
||||||
|
event_call=__event_call__,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
# 6. 保存新摘要
|
# 6. 保存新摘要
|
||||||
await self._log(
|
await self._log(
|
||||||
"[优化] 在后台线程中保存摘要以避免阻塞事件循环。",
|
"[优化] 在后台线程中保存摘要以避免阻塞事件循环。",
|
||||||
@@ -987,6 +1016,18 @@ class Filter:
|
|||||||
type="error",
|
type="error",
|
||||||
event_call=__event_call__,
|
event_call=__event_call__,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if __event_emitter__:
|
||||||
|
await __event_emitter__(
|
||||||
|
{
|
||||||
|
"type": "status",
|
||||||
|
"data": {
|
||||||
|
"description": f"摘要生成错误: {str(e)[:100]}...",
|
||||||
|
"done": True,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
@@ -1068,7 +1109,17 @@ class Filter:
|
|||||||
请根据上述内容,生成摘要:
|
请根据上述内容,生成摘要:
|
||||||
"""
|
"""
|
||||||
# 确定使用的模型
|
# 确定使用的模型
|
||||||
model = self.valves.summary_model or body.get("model", "")
|
model = self._clean_model_id(self.valves.summary_model) or self._clean_model_id(
|
||||||
|
body.get("model")
|
||||||
|
)
|
||||||
|
|
||||||
|
if not model:
|
||||||
|
await self._log(
|
||||||
|
"[🤖 LLM 调用] ⚠️ 摘要模型不存在,跳过摘要生成",
|
||||||
|
type="warning",
|
||||||
|
event_call=__event_call__,
|
||||||
|
)
|
||||||
|
return ""
|
||||||
|
|
||||||
await self._log(f"[🤖 LLM 调用] 模型: {model}", event_call=__event_call__)
|
await self._log(f"[🤖 LLM 调用] 模型: {model}", event_call=__event_call__)
|
||||||
|
|
||||||
@@ -1122,7 +1173,12 @@ class Filter:
|
|||||||
return summary
|
return summary
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_message = f"调用 LLM ({model}) 生成摘要时发生错误: {str(e)}"
|
error_msg = str(e)
|
||||||
|
# Handle specific error messages
|
||||||
|
if "Model not found" in error_msg:
|
||||||
|
error_message = f"摘要模型 '{model}' 不存在。"
|
||||||
|
else:
|
||||||
|
error_message = f"摘要 LLM 错误 ({model}): {error_msg}"
|
||||||
if not self.valves.summary_model:
|
if not self.valves.summary_model:
|
||||||
error_message += (
|
error_message += (
|
||||||
"\n[提示] 您未指定 summary_model,因此过滤器尝试使用当前对话的模型。"
|
"\n[提示] 您未指定 summary_model,因此过滤器尝试使用当前对话的模型。"
|
||||||
|
|||||||
@@ -469,10 +469,42 @@ class OpenWebUICommunityClient:
|
|||||||
return True, f"Created new post (ID: {new_post_id})"
|
return True, f"Created new post (ID: {new_post_id})"
|
||||||
return False, "Failed to create new post"
|
return False, "Failed to create new post"
|
||||||
|
|
||||||
|
# 获取远程帖子信息(只需获取一次)
|
||||||
|
remote_post = None
|
||||||
|
if post_id:
|
||||||
|
remote_post = self.get_post(post_id)
|
||||||
|
|
||||||
# 版本检查(仅对更新有效)
|
# 版本检查(仅对更新有效)
|
||||||
if not force and local_version:
|
if not force and local_version and remote_post:
|
||||||
if not self.version_needs_update(post_id, local_version):
|
remote_version = (
|
||||||
return True, f"Skipped: version {local_version} matches remote"
|
remote_post.get("data", {})
|
||||||
|
.get("function", {})
|
||||||
|
.get("meta", {})
|
||||||
|
.get("manifest", {})
|
||||||
|
.get("version")
|
||||||
|
)
|
||||||
|
|
||||||
|
version_changed = local_version != remote_version
|
||||||
|
|
||||||
|
# 检查 README 是否变化
|
||||||
|
readme_changed = False
|
||||||
|
remote_content = remote_post.get("content", "")
|
||||||
|
local_content = readme_content or metadata.get("description", "")
|
||||||
|
|
||||||
|
# 简单的内容比较 (去除首尾空白)
|
||||||
|
if (local_content or "").strip() != (remote_content or "").strip():
|
||||||
|
readme_changed = True
|
||||||
|
|
||||||
|
if not version_changed and not readme_changed:
|
||||||
|
return (
|
||||||
|
True,
|
||||||
|
f"Skipped: version {local_version} matches remote and no README changes",
|
||||||
|
)
|
||||||
|
|
||||||
|
if readme_changed and not version_changed:
|
||||||
|
print(
|
||||||
|
f" ℹ️ Version match ({local_version}) but README changed. Updating..."
|
||||||
|
)
|
||||||
|
|
||||||
# 更新
|
# 更新
|
||||||
success = self.update_plugin(
|
success = self.update_plugin(
|
||||||
@@ -484,7 +516,9 @@ class OpenWebUICommunityClient:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
|
if local_version:
|
||||||
return True, f"Updated to version {local_version}"
|
return True, f"Updated to version {local_version}"
|
||||||
|
return True, "Updated plugin"
|
||||||
return False, "Update failed"
|
return False, "Update failed"
|
||||||
|
|
||||||
def _parse_frontmatter(self, content: str) -> Dict[str, str]:
|
def _parse_frontmatter(self, content: str) -> Dict[str, str]:
|
||||||
|
|||||||
Reference in New Issue
Block a user