Compare commits

..

12 Commits

Author SHA1 Message Date
fujie
f5e5e5caa4 feat: 添加版本一致性检查脚本以确保插件和文档版本同步 2026-01-03 12:25:04 +08:00
fujie
0c893ce61f docs: 新增插件开发工作流程文档并更新了多个插件的版本信息 2026-01-03 12:22:14 +08:00
fujie
8f4ce8f084 docs: 更新异步上下文压缩的图标。 2026-01-03 12:00:18 +08:00
fujie
ac2cf00807 feat: 更新了异步上下文压缩插件版本,并优化了发布工作流以直接上传插件文件,同时排除了新的插件模板文件。 2026-01-03 11:54:17 +08:00
fujie
b9d8100cdb docs: add consistency maintenance section to copilot instructions 2026-01-03 11:18:39 +08:00
fujie
bb1cc0d966 docs: update copilot instructions for consistency and sync READMEs 2026-01-03 11:17:54 +08:00
fujie
2e238c5b5d 移除多模型上下文合并器插件的描述。 2026-01-03 11:17:48 +08:00
fujie
b56e7cb41e docs: update documentation versions, fix rendering issues, and update READMEs 2026-01-03 11:16:24 +08:00
fujie
236ae43c0c fix: 提取插件版本时跳过 gemini_manifold.pygemini_manifold_companion.py 文件 2026-01-03 11:00:14 +08:00
fujie
a4e8cc52f9 docs: 更新 Copilot 指令。 2026-01-03 10:57:21 +08:00
fujie
c8e8434bc6 feat: 引入选项以在发布说明中忽略已移除的插件。 2026-01-03 10:55:05 +08:00
fujie
3ee00bb083 docs(copilot-instructions): add release workflow guidelines
- Add release workflow section with automatic release process
- Document version numbering rules (semver)
- Add three release methods: direct push, PR, manual trigger
- Include commit message convention (Conventional Commits)
- Add release checklist
2026-01-01 04:23:22 +08:00
25 changed files with 648 additions and 73 deletions

View File

@@ -0,0 +1,93 @@
---
description: OpenWebUI Plugin Development & Release Workflow
---
# OpenWebUI Plugin Development Workflow
This workflow outlines the standard process for developing, documenting, and releasing plugins for OpenWebUI, ensuring compliance with project standards and CI/CD requirements.
## 1. Development Standards
Reference: `.github/copilot-instructions.md`
### Bilingual Requirement
Every plugin **MUST** have bilingual versions for both code and documentation:
- **Code**:
- English: `plugins/{type}/{name}/{name}.py`
- Chinese: `plugins/{type}/{name}/{name_cn}.py` (or `中文名.py`)
- **README**:
- English: `plugins/{type}/{name}/README.md`
- Chinese: `plugins/{type}/{name}/README_CN.md`
### Code Structure
- **Docstring**: Must include `title`, `author`, `version`, `description`, etc.
- **Valves**: Use `pydantic` for configuration.
- **Database**: Re-use `open_webui.internal.db` shared connection.
- **User Context**: Use `_get_user_context` helper method.
### Commit Messages
- **Language**: **English ONLY**. Do not use Chinese in commit messages.
- **Format**: Conventional Commits (e.g., `feat:`, `fix:`, `docs:`).
## 2. Documentation Updates
When adding or updating a plugin, you **MUST** update the following documentation files to maintain consistency:
### Plugin Directory
- `README.md`: Update version, description, and usage.
- `README_CN.md`: Update version, description, and usage.
### Global Documentation (`docs/`)
- **Index Pages**:
- `docs/plugins/{type}/index.md`: Add/Update list item with **correct version**.
- `docs/plugins/{type}/index.zh.md`: Add/Update list item with **correct version**.
- **Detail Pages**:
- `docs/plugins/{type}/{name}.md`: Ensure content matches README.
- `docs/plugins/{type}/{name}.zh.md`: Ensure content matches README_CN.
### Root README
- `README.md`: Add to "Featured Plugins" if applicable.
- `README_CN.md`: Add to "Featured Plugins" if applicable.
## 3. Version Control & Release
Reference: `.github/workflows/release.yml`
### Version Bumping
- **Rule**: Any change to plugin logic **MUST** be accompanied by a version bump in the docstring.
- **Format**: Semantic Versioning (e.g., `1.0.0` -> `1.0.1`).
- **Consistency**: 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`)
### Automated Release Process
1. **Trigger**: Push to `main` branch with changes in `plugins/**/*.py`.
2. **Detection**: `scripts/extract_plugin_versions.py` detects changed plugins and compares versions.
3. **Release**:
- Generates release notes based on changes.
- Creates a GitHub Release tag (e.g., `v2024.01.01-1`).
- Uploads individual `.py` files of **changed plugins only** as assets.
### Pull Request Check
- Workflow: `.github/workflows/plugin-version-check.yml`
- Checks if plugin files are modified.
- **Fails** if version number is not updated.
- **Fails** if PR description is too short (< 20 chars).
## 4. Verification Checklist
Before committing:
- [ ] Code is bilingual and functional?
- [ ] Docstrings have updated version?
- [ ] READMEs are updated and bilingual?
- [ ] `docs/` index and detail pages are updated?
- [ ] Root `README.md` is updated?
- [ ] All version numbers match exactly?

View File

@@ -795,10 +795,147 @@ For iframe plugins to access parent document theme information, users need to co
- [ ] 实现 Valves 配置 - [ ] 实现 Valves 配置
- [ ] 使用 logging 而非 print - [ ] 使用 logging 而非 print
- [ ] 测试双语界面 - [ ] 测试双语界面
- [ ] **一致性检查 (Consistency Check)**:
- [ ] 更新 `README.md` 插件列表
- [ ] 更新 `README_CN.md` 插件列表
- [ ] 更新/创建 `docs/` 下的对应文档
- [ ] 确保文档版本号与代码一致
--- ---
## 📚 参考资源 (Reference Resources) ## 🔄 一致性维护 (Consistency Maintenance)
任何插件的**新增、修改或移除**,必须同时更新以下三个位置,保持完全一致:
1. **插件代码 (Plugin Code)**: 更新 `version` 和功能实现。
2. **项目文档 (Docs)**: 更新 `docs/` 下对应的文档文件(版本号、功能描述)。
3. **自述文件 (README)**: 更新根目录下的 `README.md``README_CN.md` 中的插件列表。
> [!IMPORTANT]
> 提交 PR 前,请务必检查这三处是否同步。例如:如果删除了一个插件,必须同时从 README 列表中移除,并删除对应的 docs 文档。
---
## <20> 发布工作流 (Release Workflow)
### 自动发布 (Automatic Release)
当插件更新推送到 `main` 分支时,会**自动触发**发布流程:
1. 🔍 检测版本变化(与上次 release 对比)
2. 📝 生成发布说明(包含更新内容和提交记录)
3. 📦 创建 GitHub Release包含可下载的插件文件
4. 🏷️ 自动生成版本号(格式:`vYYYY.MM.DD-运行号`
**注意**:仅**移除插件**(删除文件)**不会触发**自动发布。只有新增或修改插件(且更新了版本号)才会触发发布。移除的插件将不会出现在发布日志中。
### 发布前必须完成 (Pre-release Requirements)
1.**更新版本号** - 修改插件文档字符串中的 `version` 字段
2.**中英文版本同步** - 确保两个版本的版本号一致
```python
"""
title: My Plugin
version: 0.2.0 # <- 必须更新这里!
...
"""
```
### 版本编号规则 (Versioning)
遵循[语义化版本](https://semver.org/lang/zh-CN/)
| 变更类型 | 版本变化 | 示例 |
|---------|---------|------|
| Bug 修复 | PATCH +1 | 0.1.0 → 0.1.1 |
| 新功能 | MINOR +1 | 0.1.1 → 0.2.0 |
| 不兼容变更 | MAJOR +1 | 0.2.0 → 1.0.0 |
### 发布方式 (Release Methods)
**方式 A直接推送到 main推荐**
```bash
# 1. 暂存更改
git add plugins/actions/my-plugin/
# 2. 提交(使用规范的 commit message
git commit -m "feat(my-plugin): add new feature X
- Add feature X for better user experience
- Fix bug Y
- Update version to 0.2.0"
# 3. 推送到 main
git push origin main
# GitHub Actions 会自动创建 Release
```
**方式 B创建 PR团队协作**
```bash
# 1. 创建功能分支
git checkout -b feature/my-plugin-v0.2.0
# 2. 提交更改
git commit -m "feat(my-plugin): add new feature X"
# 3. 推送并创建 PR
git push origin feature/my-plugin-v0.2.0
# 4. PR 合并后自动触发发布
```
**方式 C手动触发发布**
1. 前往 GitHub Actions → "Plugin Release / 插件发布"
2. 点击 "Run workflow"
3. 填写版本号和发布说明
### Commit Message 规范 (Commit Convention)
使用 [Conventional Commits](https://www.conventionalcommits.org/) 格式:
```
<type>(<scope>): <description>
[optional body]
[optional footer]
```
常用类型:
- `feat`: 新功能
- `fix`: Bug 修复
- `docs`: 文档更新
- `refactor`: 代码重构
- `style`: 代码格式调整
- `perf`: 性能优化
示例:
```
feat(flash-card): add _get_user_context for safer user info retrieval
- Add _get_user_context method to handle various __user__ types
- Prevent AttributeError when __user__ is not a dict
- Update version to 0.2.2 for both English and Chinese versions
```
### 发布检查清单 (Release Checklist)
发布前确保完成以下检查:
- [ ] 更新插件版本号(英文版 + 中文版)
- [ ] 测试插件功能正常
- [ ] 确保代码通过格式检查
- [ ] 编写清晰的 commit message
- [ ] 推送到 main 分支或合并 PR
---
## <20>📚 参考资源 (Reference Resources)
- [Action 插件模板 (英文)](plugins/actions/ACTION_PLUGIN_TEMPLATE.py) - [Action 插件模板 (英文)](plugins/actions/ACTION_PLUGIN_TEMPLATE.py)
- [Action 插件模板 (中文)](plugins/actions/ACTION_PLUGIN_TEMPLATE_CN.py) - [Action 插件模板 (中文)](plugins/actions/ACTION_PLUGIN_TEMPLATE_CN.py)
@@ -816,3 +953,32 @@ GitHub: [Fu-Jie/awesome-openwebui](https://github.com/Fu-Jie/awesome-openwebui)
## License ## License
MIT License MIT License
---
## 📝 Commit Message Guidelines
**Commit messages MUST be in English.** Do not use Chinese.
### Format
Follow the [Conventional Commits](https://www.conventionalcommits.org/) specification:
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation only changes
- `style`: Changes that do not affect the meaning of the code (white-space, formatting, etc)
- `refactor`: A code change that neither fixes a bug nor adds a feature
- `perf`: A code change that improves performance
- `test`: Adding missing tests or correcting existing tests
- `chore`: Changes to the build process or auxiliary tools and libraries such as documentation generation
### Examples
**Good:**
- `feat: add new export to pdf plugin`
- `fix: resolve icon rendering issue in documentation`
- `docs: update README with installation steps`
**Bad:**
- `新增导出PDF插件` (Chinese is not allowed)
- `update code` (Too vague)

View File

@@ -101,7 +101,7 @@ jobs:
fi fi
# Compare versions and generate release notes # Compare versions and generate release notes
python scripts/extract_plugin_versions.py --compare old_versions.json --output changes.md python scripts/extract_plugin_versions.py --compare old_versions.json --ignore-removed --output changes.md
python scripts/extract_plugin_versions.py --compare old_versions.json --json --output changes.json python scripts/extract_plugin_versions.py --compare old_versions.json --json --output changes.json
echo "=== Version Changes ===" echo "=== Version Changes ==="
@@ -175,10 +175,7 @@ jobs:
id: plugins id: plugins
run: | run: |
python scripts/extract_plugin_versions.py --json --output plugin_versions.json python scripts/extract_plugin_versions.py --json --output plugin_versions.json
python scripts/extract_plugin_versions.py --markdown --output plugin_table.md python scripts/extract_plugin_versions.py --json --output plugin_versions.json
echo "=== Plugin Versions ==="
cat plugin_table.md
- name: Collect plugin files for release - name: Collect plugin files for release
id: collect_files id: collect_files
@@ -198,28 +195,12 @@ jobs:
fi fi
done done
else else
echo "Collecting all plugin files..." echo "No changed plugins detected. Skipping file collection."
find plugins -name "*.py" -type f ! -name "__*" | while read -r file; do
dir=$(dirname "$file")
mkdir -p "release_plugins/$dir"
cp "$file" "release_plugins/$file"
done
fi fi
# Create a zip file with error handling # Create a zip file with error handling
cd release_plugins # cd release_plugins
if [ -n "$(ls -A . 2>/dev/null)" ]; then # Zip step removed as per user request
if zip -r ../plugins_release.zip .; then
echo "Successfully created plugins_release.zip"
else
echo "Warning: Failed to create zip file, creating empty placeholder"
touch ../plugins_release.zip
fi
else
echo "No plugin files to zip, creating empty placeholder"
touch ../plugins_release.zip
fi
cd ..
echo "=== Collected Files ===" echo "=== Collected Files ==="
find release_plugins -name "*.py" -type f | head -20 find release_plugins -name "*.py" -type f | head -20
@@ -280,16 +261,13 @@ jobs:
echo "" >> release_notes.md echo "" >> release_notes.md
fi fi
echo "## All Plugin Versions / 所有插件版本" >> release_notes.md
echo "" >> release_notes.md
cat plugin_table.md >> release_notes.md
echo "" >> release_notes.md
cat >> release_notes.md << 'EOF' cat >> release_notes.md << 'EOF'
## Download / 下载 ## Download / 下载
📦 **plugins_release.zip** - 包含本次更新的所有插件文件 / Contains all updated plugin files 📦 **Download the updated plugin files below** / 请在下方下载更新的插件文件
### Installation / 安装 ### Installation / 安装
@@ -323,7 +301,7 @@ jobs:
prerelease: ${{ github.event.inputs.prerelease || false }} prerelease: ${{ github.event.inputs.prerelease || false }}
files: | files: |
plugin_versions.json plugin_versions.json
plugins_release.zip release_plugins/**/*.py
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -336,5 +314,4 @@ jobs:
echo "### Updated Plugins" >> $GITHUB_STEP_SUMMARY echo "### Updated Plugins" >> $GITHUB_STEP_SUMMARY
echo "${{ needs.check-changes.outputs.release_notes }}" >> $GITHUB_STEP_SUMMARY echo "${{ needs.check-changes.outputs.release_notes }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY
echo "### All Plugin Versions" >> $GITHUB_STEP_SUMMARY
cat plugin_table.md >> $GITHUB_STEP_SUMMARY

View File

@@ -14,15 +14,17 @@ Located in the `plugins/` directory, containing Python-based enhancements:
#### Actions #### Actions
- **Smart Mind Map** (`smart-mind-map`): Generates interactive mind maps from text. - **Smart Mind Map** (`smart-mind-map`): Generates interactive mind maps from text.
- **Smart Infographic** (`infographic`): Transforms text into professional infographics using AntV.
- **Knowledge Card** (`knowledge-card`): Creates beautiful flashcards for learning. - **Knowledge Card** (`knowledge-card`): Creates beautiful flashcards for learning.
- **Export to Excel** (`export_to_excel`): Exports chat history to Excel files. - **Export to Excel** (`export_to_excel`): Exports chat history to Excel files.
- **Export to Word** (`export_to_docx`): Exports chat history to Word documents.
- **Summary** (`summary`): Text summarization tool. - **Summary** (`summary`): Text summarization tool.
#### Filters #### Filters
- **Async Context Compression** (`async-context-compression`): Optimizes token usage via context compression. - **Async Context Compression** (`async-context-compression`): Optimizes token usage via context compression.
- **Context Enhancement** (`context_enhancement_filter`): Enhances chat context. - **Context Enhancement** (`context_enhancement_filter`): Enhances chat context.
- **Gemini Manifold Companion** (`gemini_manifold_companion`): Companion filter for Gemini Manifold. - **Gemini Manifold Companion** (`gemini_manifold_companion`): Companion filter for Gemini Manifold.
- **Multi-Model Context Merger** (`multi_model_context_merger`): Merges context from multiple models.
#### Pipes #### Pipes
- **Gemini Manifold** (`gemini_mainfold`): Pipeline for Gemini model integration. - **Gemini Manifold** (`gemini_mainfold`): Pipeline for Gemini model integration.

View File

@@ -8,15 +8,17 @@ OpenWebUI 增强功能集合。包含个人开发与收集的### 🧩 插件 (Pl
#### Actions (交互增强) #### Actions (交互增强)
- **Smart Mind Map** (`smart-mind-map`): 智能分析文本并生成交互式思维导图。 - **Smart Mind Map** (`smart-mind-map`): 智能分析文本并生成交互式思维导图。
- **Smart Infographic** (`infographic`): 基于 AntV 的智能信息图生成工具。
- **Knowledge Card** (`knowledge-card`): 快速生成精美的学习记忆卡片。 - **Knowledge Card** (`knowledge-card`): 快速生成精美的学习记忆卡片。
- **Export to Excel** (`export_to_excel`): 将对话内容导出为 Excel 文件。 - **Export to Excel** (`export_to_excel`): 将对话内容导出为 Excel 文件。
- **Export to Word** (`export_to_docx`): 将对话内容导出为 Word 文档。
- **Summary** (`summary`): 文本摘要生成工具。 - **Summary** (`summary`): 文本摘要生成工具。
#### Filters (消息处理) #### Filters (消息处理)
- **Async Context Compression** (`async-context-compression`): 异步上下文压缩,优化 Token 使用。 - **Async Context Compression** (`async-context-compression`): 异步上下文压缩,优化 Token 使用。
- **Context Enhancement** (`context_enhancement_filter`): 上下文增强过滤器。 - **Context Enhancement** (`context_enhancement_filter`): 上下文增强过滤器。
- **Gemini Manifold Companion** (`gemini_manifold_companion`): Gemini Manifold 配套增强。 - **Gemini Manifold Companion** (`gemini_manifold_companion`): Gemini Manifold 配套增强。
- **Multi-Model Context Merger** (`multi_model_context_merger`): 多模型上下文合并。
#### Pipes (模型管道) #### Pipes (模型管道)
- **Gemini Manifold** (`gemini_mainfold`): 集成 Gemini 模型的管道。 - **Gemini Manifold** (`gemini_mainfold`): 集成 Gemini 模型的管道。

View File

@@ -1,7 +1,7 @@
# Export to Excel # Export to Excel
<span class="category-badge action">Action</span> <span class="category-badge action">Action</span>
<span class="version-badge">v1.0.0</span> <span class="version-badge">v0.3.3</span>
Export chat conversations to Excel spreadsheet format for analysis, archiving, and sharing. Export chat conversations to Excel spreadsheet format for analysis, archiving, and sharing.

View File

@@ -33,7 +33,7 @@ Actions are interactive plugins that:
Transform text into professional infographics using AntV visualization engine with various templates. Transform text into professional infographics using AntV visualization engine with various templates.
**Version:** 1.0.0 **Version:** 1.3.0
[:octicons-arrow-right-24: Documentation](smart-infographic.md) [:octicons-arrow-right-24: Documentation](smart-infographic.md)
@@ -43,7 +43,7 @@ Actions are interactive plugins that:
Quickly generates beautiful learning memory cards, perfect for studying and memorization. Quickly generates beautiful learning memory cards, perfect for studying and memorization.
**Version:** 0.2.0 **Version:** 0.2.2
[:octicons-arrow-right-24: Documentation](knowledge-card.md) [:octicons-arrow-right-24: Documentation](knowledge-card.md)
@@ -53,7 +53,7 @@ Actions are interactive plugins that:
Export chat conversations to Excel spreadsheet format for analysis and archiving. Export chat conversations to Excel spreadsheet format for analysis and archiving.
**Version:** 1.0.0 **Version:** 0.3.3
[:octicons-arrow-right-24: Documentation](export-to-excel.md) [:octicons-arrow-right-24: Documentation](export-to-excel.md)
@@ -73,7 +73,7 @@ Actions are interactive plugins that:
Generate concise summaries of long text content with key points extraction. Generate concise summaries of long text content with key points extraction.
**Version:** 1.0.0 **Version:** 0.1.0
[:octicons-arrow-right-24: Documentation](summary.md) [:octicons-arrow-right-24: Documentation](summary.md)

View File

@@ -33,7 +33,7 @@ Actions 是交互式插件,能够:
使用 AntV 可视化引擎,将文本转成专业的信息图。 使用 AntV 可视化引擎,将文本转成专业的信息图。
**版本:** 1.0.0 **版本:** 1.3.0
[:octicons-arrow-right-24: 查看文档](smart-infographic.md) [:octicons-arrow-right-24: 查看文档](smart-infographic.md)
@@ -43,7 +43,7 @@ Actions 是交互式插件,能够:
快速生成精美的学习记忆卡片,适合学习与记忆。 快速生成精美的学习记忆卡片,适合学习与记忆。
**版本:** 0.2.0 **版本:** 0.2.2
[:octicons-arrow-right-24: 查看文档](knowledge-card.md) [:octicons-arrow-right-24: 查看文档](knowledge-card.md)
@@ -53,7 +53,7 @@ Actions 是交互式插件,能够:
将聊天记录导出为 Excel 电子表格,方便分析或归档。 将聊天记录导出为 Excel 电子表格,方便分析或归档。
**版本:** 1.0.0 **版本:** 0.3.3
[:octicons-arrow-right-24: 查看文档](export-to-excel.md) [:octicons-arrow-right-24: 查看文档](export-to-excel.md)
@@ -73,7 +73,7 @@ Actions 是交互式插件,能够:
对长文本进行精简总结,提取要点。 对长文本进行精简总结,提取要点。
**版本:** 1.0.0 **版本:** 0.1.0
[:octicons-arrow-right-24: 查看文档](summary.md) [:octicons-arrow-right-24: 查看文档](summary.md)

View File

@@ -1,7 +1,7 @@
# Knowledge Card # Knowledge Card
<span class="category-badge action">Action</span> <span class="category-badge action">Action</span>
<span class="version-badge">v0.2.0</span> <span class="version-badge">v0.2.2</span>
Quickly generates beautiful learning memory cards, perfect for studying and quick memorization. Quickly generates beautiful learning memory cards, perfect for studying and quick memorization.

View File

@@ -1,7 +1,7 @@
# Smart Infographic # Smart Infographic
<span class="category-badge action">Action</span> <span class="category-badge action">Action</span>
<span class="version-badge">v1.0.0</span> <span class="version-badge">v1.3.0</span>
An AntV Infographic engine powered plugin that transforms long text into professional, beautiful infographics with a single click. An AntV Infographic engine powered plugin that transforms long text into professional, beautiful infographics with a single click.

View File

@@ -1,7 +1,7 @@
# Summary # Summary
<span class="category-badge action">Action</span> <span class="category-badge action">Action</span>
<span class="version-badge">v1.0.0</span> <span class="version-badge">v0.1.0</span>
Generate concise summaries of long text content with key points extraction. Generate concise summaries of long text content with key points extraction.

View File

@@ -1,7 +1,7 @@
# Summary摘要 # Summary摘要
<span class="category-badge action">Action</span> <span class="category-badge action">Action</span>
<span class="version-badge">v1.0.0</span> <span class="version-badge">v0.1.0</span>
为长文本生成简洁摘要,并提取关键要点。 为长文本生成简洁摘要,并提取关键要点。

View File

@@ -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.0.0</span> <span class="version-badge">v1.1.0</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.

View File

@@ -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.0.0</span> <span class="version-badge">v1.1.0</span>
通过智能摘要减少长对话的 token 消耗,同时保持对话连贯。 通过智能摘要减少长对话的 token 消耗,同时保持对话连贯。

View File

@@ -1,7 +1,7 @@
# Context Enhancement # Context Enhancement
<span class="category-badge filter">Filter</span> <span class="category-badge filter">Filter</span>
<span class="version-badge">v1.0.0</span> <span class="version-badge">v0.2</span>
Enhances chat context with additional information for improved LLM responses. Enhances chat context with additional information for improved LLM responses.

View File

@@ -1,7 +1,7 @@
# Context Enhancement上下文增强 # Context Enhancement上下文增强
<span class="category-badge filter">Filter</span> <span class="category-badge filter">Filter</span>
<span class="version-badge">v1.0.0</span> <span class="version-badge">v0.2</span>
为聊天自动补充上下文信息,让 LLM 回复更相关、更准确。 为聊天自动补充上下文信息,让 LLM 回复更相关、更准确。

View File

@@ -1,7 +1,7 @@
# Gemini Manifold Companion # Gemini Manifold Companion
<span class="category-badge filter">Filter</span> <span class="category-badge filter">Filter</span>
<span class="version-badge">v1.0.0</span> <span class="version-badge">v0.3.2</span>
Companion filter for the Gemini Manifold pipe plugin, providing enhanced functionality. Companion filter for the Gemini Manifold pipe plugin, providing enhanced functionality.

View File

@@ -1,7 +1,7 @@
# Gemini Manifold Companion # Gemini Manifold Companion
<span class="category-badge filter">Filter</span> <span class="category-badge filter">Filter</span>
<span class="version-badge">v1.0.0</span> <span class="version-badge">v0.3.2</span>
Gemini Manifold Pipe 的伴随过滤器,用于增强 Gemini 集成的处理效果。 Gemini Manifold Pipe 的伴随过滤器,用于增强 Gemini 集成的处理效果。

View File

@@ -16,13 +16,13 @@ Filters act as middleware in the message pipeline:
<div class="grid cards" markdown> <div class="grid cards" markdown>
- :material-compress:{ .lg .middle } **Async Context Compression** - :material-arrow-collapse-vertical:{ .lg .middle } **Async Context Compression**
--- ---
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.0.0 **Version:** 1.1.0
[:octicons-arrow-right-24: Documentation](async-context-compression.md) [:octicons-arrow-right-24: Documentation](async-context-compression.md)
@@ -32,7 +32,7 @@ Filters act as middleware in the message pipeline:
Enhances chat context with additional information for better responses. Enhances chat context with additional information for better responses.
**Version:** 1.0.0 **Version:** 0.2
[:octicons-arrow-right-24: Documentation](context-enhancement.md) [:octicons-arrow-right-24: Documentation](context-enhancement.md)
@@ -42,7 +42,7 @@ Filters act as middleware in the message pipeline:
Companion filter for the Gemini Manifold pipe plugin. Companion filter for the Gemini Manifold pipe plugin.
**Version:** 1.0.0 **Version:** 1.7.0
[:octicons-arrow-right-24: Documentation](gemini-manifold-companion.md) [:octicons-arrow-right-24: Documentation](gemini-manifold-companion.md)

View File

@@ -16,13 +16,13 @@ Filter 充当消息管线中的中间件:
<div class="grid cards" markdown> <div class="grid cards" markdown>
- :material-compress:{ .lg .middle } **Async Context Compression** - :material-arrow-collapse-vertical:{ .lg .middle } **Async Context Compression**
--- ---
通过智能总结减少长对话的 token 消耗,同时保持连贯性。 通过智能总结减少长对话的 token 消耗,同时保持连贯性。
**版本:** 1.0.0 **版本:** 1.1.0
[:octicons-arrow-right-24: 查看文档](async-context-compression.md) [:octicons-arrow-right-24: 查看文档](async-context-compression.md)
@@ -32,7 +32,7 @@ Filter 充当消息管线中的中间件:
为聊天增加额外信息,提升回复质量。 为聊天增加额外信息,提升回复质量。
**版本:** 1.0.0 **版本:** 0.2
[:octicons-arrow-right-24: 查看文档](context-enhancement.md) [:octicons-arrow-right-24: 查看文档](context-enhancement.md)
@@ -42,7 +42,7 @@ Filter 充当消息管线中的中间件:
Gemini Manifold Pipe 插件的伴随过滤器。 Gemini Manifold Pipe 插件的伴随过滤器。
**版本:** 1.0.0 **版本:** 1.7.0
[:octicons-arrow-right-24: 查看文档](gemini-manifold-companion.md) [:octicons-arrow-right-24: 查看文档](gemini-manifold-companion.md)

View File

@@ -1,7 +1,7 @@
""" """
title: 精读 (Deep Reading) title: 精读 (Deep Reading)
icon_url: data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImciIHgxPSIwIiB5MT0iMCIgeDI9IjEiIHkyPSIxIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjNDI4NWY0Ii8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjMWU4OGU1Ii8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHBhdGggZD0iTTYgMmg4bDYgNnYxMmEyIDIgMCAwIDEtMiAySDZhMiAyIDAgMCAxLTItMlY0YTIgMiAwIDAgMSAyLTJ6IiBmaWxsPSJ1cmwoI2cpIi8+PHBhdGggZD0iTTE0IDJsNiA2aC02eiIgZmlsbD0iIzFlODhlNSIgb3BhY2l0eT0iMC42Ii8+PGxpbmUgeDE9IjgiIHkxPSIxMyIgeDI9IjE2IiB5Mj0iMTMiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48bGluZSB4MT0iOCIgeTE9IjE3IiB4Mj0iMTQiIHkyPSIxNyIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEuNSIvPjxjaXJjbGUgY3g9IjE2IiBjeT0iMTgiIHI9IjMiIGZpbGw9IiNmZmQ3MDAiLz48cGF0aCBkPSJNMTYgMTZsMS41IDEuNSIgc3Ryb2tlPSIjNDI4NWY0IiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvc3ZnPg== icon_url: data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImciIHgxPSIwIiB5MT0iMCIgeDI9IjEiIHkyPSIxIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjNDI4NWY0Ii8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjMWU4OGU1Ii8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHBhdGggZD0iTTYgMmg4bDYgNnYxMmEyIDIgMCAwIDEtMiAySDZhMiAyIDAgMCAxLTItMlY0YTIgMiAwIDAgMSAyLTJ6IiBmaWxsPSJ1cmwoI2cpIi8+PHBhdGggZD0iTTE0IDJsNiA2aC02eiIgZmlsbD0iIzFlODhlNSIgb3BhY2l0eT0iMC42Ii8+PGxpbmUgeDE9IjgiIHkxPSIxMyIgeDI9IjE2IiB5Mj0iMTMiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48bGluZSB4MT0iOCIgeTE9IjE3IiB4Mj0iMTQiIHkyPSIxNyIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEuNSIvPjxjaXJjbGUgY3g9IjE2IiBjeT0iMTgiIHI9IjMiIGZpbGw9IiNmZmQ3MDAiLz48cGF0aCBkPSJNMTYgMTZsMS41IDEuNSIgc3Ryb2tlPSIjNDI4NWY0IiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvc3ZnPg==
version: 2.0.0 version: 0.1.0
description: 深度分析长篇文本,提炼详细摘要、关键信息点和可执行的行动建议,适合工作和学习场景。 description: 深度分析长篇文本,提炼详细摘要、关键信息点和可执行的行动建议,适合工作和学习场景。
requirements: jinja2, markdown requirements: jinja2, markdown
""" """

View File

@@ -1,6 +1,6 @@
# Async Context Compression Filter # Async Context Compression Filter
**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** 1.2.0 | **License:** MIT **Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** 1.1.0 | **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.

View File

@@ -1,6 +1,6 @@
# Example Pipe Plugin # Example Pipe Plugin
**Author:** OpenWebUI Community | **Version:** 1.0.0 | **License:** MIT **Author:** OpenWebUI Community | **Version:** 1.26.0 | **License:** MIT
This is a template/example for creating Pipe plugins in OpenWebUI. This is a template/example for creating Pipe plugins in OpenWebUI.

View File

@@ -0,0 +1,315 @@
#!/usr/bin/env python3
"""
Script to check and enforce version consistency across OpenWebUI plugins and documentation.
用于检查并强制 OpenWebUI 插件和文档之间版本一致性的脚本。
Usage:
python scripts/check_version_consistency.py # Check only
python scripts/check_version_consistency.py --fix # Check and fix
"""
import argparse
import os
import re
import sys
from pathlib import Path
from typing import Optional, List, Dict, Tuple
# ANSI colors
GREEN = "\033[92m"
RED = "\033[91m"
YELLOW = "\033[93m"
BLUE = "\033[94m"
RESET = "\033[0m"
def log_info(msg):
print(f"{BLUE}[INFO]{RESET} {msg}")
def log_success(msg):
print(f"{GREEN}[OK]{RESET} {msg}")
def log_warning(msg):
print(f"{YELLOW}[WARN]{RESET} {msg}")
def log_error(msg):
print(f"{RED}[ERR]{RESET} {msg}")
class VersionChecker:
def __init__(self, root_dir: str, fix: bool = False):
self.root_dir = Path(root_dir)
self.plugins_dir = self.root_dir / "plugins"
self.docs_dir = self.root_dir / "docs" / "plugins"
self.fix = fix
self.issues_found = 0
self.fixed_count = 0
def extract_version_from_py(self, file_path: Path) -> Optional[str]:
"""Extract version from Python docstring."""
try:
content = file_path.read_text(encoding="utf-8")
match = re.search(r"version:\s*([\d\.]+)", content)
if match:
return match.group(1)
except Exception as e:
log_error(f"Failed to read {file_path}: {e}")
return None
def update_file_content(
self, file_path: Path, pattern: str, replacement: str, version: str
) -> bool:
"""Update file content with new version."""
try:
content = file_path.read_text(encoding="utf-8")
new_content = re.sub(pattern, replacement, content)
if content != new_content:
if self.fix:
file_path.write_text(new_content, encoding="utf-8")
log_success(
f"Fixed {file_path.relative_to(self.root_dir)}: -> {version}"
)
self.fixed_count += 1
return True
else:
log_error(
f"Mismatch in {file_path.relative_to(self.root_dir)}: Expected {version}"
)
self.issues_found += 1
return False
return True
except Exception as e:
log_error(f"Failed to update {file_path}: {e}")
return False
def check_plugin(self, plugin_type: str, plugin_dir: Path):
"""Check consistency for a single plugin."""
plugin_name = plugin_dir.name
# 1. Identify Source of Truth (English .py file)
py_file = plugin_dir / f"{plugin_name}.py"
if not py_file.exists():
# Try finding any .py file that matches the directory name pattern or is the main file
py_files = list(plugin_dir.glob("*.py"))
# Filter out _cn.py, templates, etc.
candidates = [
f
for f in py_files
if not f.name.endswith("_cn.py") and "TEMPLATE" not in f.name
]
if candidates:
py_file = candidates[0]
else:
return # Not a valid plugin dir
true_version = self.extract_version_from_py(py_file)
if not true_version:
log_warning(f"Skipping {plugin_name}: No version found in {py_file.name}")
return
log_info(f"Checking {plugin_name} (v{true_version})...")
# 2. Check Chinese .py file
cn_py_files = list(plugin_dir.glob("*_cn.py")) + list(
plugin_dir.glob("*中文*.py")
)
# Also check for files that are not the main file but might be the CN version
for f in plugin_dir.glob("*.py"):
if f != py_file and "TEMPLATE" not in f.name and f not in cn_py_files:
# Heuristic: if it has Chinese characters or ends in _cn
if re.search(r"[\u4e00-\u9fff]", f.name) or f.name.endswith("_cn.py"):
cn_py_files.append(f)
for cn_py in set(cn_py_files):
self.update_file_content(
cn_py, r"(version:\s*)([\d\.]+)", rf"\g<1>{true_version}", true_version
)
# 3. Check README.md (English)
readme = plugin_dir / "README.md"
if readme.exists():
# Pattern 1: **Version:** 1.0.0
self.update_file_content(
readme,
r"(\*\*Version:?\*\*\s*)([\d\.]+)",
rf"\g<1>{true_version}",
true_version,
)
# Pattern 2: | **Version:** 1.0.0 |
self.update_file_content(
readme,
r"(\|\s*\*\*Version:\*\*\s*)([\d\.]+)",
rf"\g<1>{true_version}",
true_version,
)
# 4. Check README_CN.md (Chinese)
readme_cn = plugin_dir / "README_CN.md"
if readme_cn.exists():
# Pattern: **版本:** 1.0.0
self.update_file_content(
readme_cn,
r"(\*\*版本:?\*\*\s*)([\d\.]+)",
rf"\g<1>{true_version}",
true_version,
)
# 5. Check Global Docs Index (docs/plugins/{type}/index.md)
index_md = self.docs_dir / plugin_type / "index.md"
if index_md.exists():
# Need to find the specific block for this plugin.
# This is harder with regex on the whole file.
# We assume the format: **Version:** X.Y.Z
# But we need to make sure we are updating the RIGHT plugin's version.
# Strategy: Look for the plugin title or link, then the version nearby.
# Extract title from py file to help search
title = self.extract_title(py_file)
if title:
self.update_version_in_index(index_md, title, true_version)
# 6. Check Global Docs Index CN (docs/plugins/{type}/index.zh.md)
index_zh = self.docs_dir / plugin_type / "index.zh.md"
if index_zh.exists():
# Try to find Chinese title? Or just use English title if listed?
# Often Chinese index uses English title or Chinese title.
# Let's try to extract Chinese title from cn_py if available
cn_title = None
if cn_py_files:
cn_title = self.extract_title(cn_py_files[0])
target_title = cn_title if cn_title else title
if target_title:
self.update_version_in_index(
index_zh, target_title, true_version, is_zh=True
)
# 7. Check Global Detail Page (docs/plugins/{type}/{name}.md)
# The doc filename usually matches the plugin directory name
detail_md = self.docs_dir / plugin_type / f"{plugin_name}.md"
if detail_md.exists():
self.update_file_content(
detail_md,
r'(<span class="version-badge">v)([\d\.]+)(</span>)',
rf"\g<1>{true_version}\g<3>",
true_version,
)
# 8. Check Global Detail Page CN (docs/plugins/{type}/{name}.zh.md)
detail_zh = self.docs_dir / plugin_type / f"{plugin_name}.zh.md"
if detail_zh.exists():
self.update_file_content(
detail_zh,
r'(<span class="version-badge">v)([\d\.]+)(</span>)',
rf"\g<1>{true_version}\g<3>",
true_version,
)
def extract_title(self, file_path: Path) -> Optional[str]:
try:
content = file_path.read_text(encoding="utf-8")
match = re.search(r"title:\s*(.+)", content)
if match:
return match.group(1).strip()
except:
pass
return None
def update_version_in_index(
self, file_path: Path, title: str, version: str, is_zh: bool = False
):
"""
Update version in index file.
Look for:
- ... **Title** ...
- ...
- **Version:** X.Y.Z
"""
try:
content = file_path.read_text(encoding="utf-8")
# Escape title for regex
safe_title = re.escape(title)
# Regex to find the plugin block and its version
# We look for the title, then non-greedy match until we find Version line
if is_zh:
ver_label = r"\*\*版本:\*\*"
else:
ver_label = r"\*\*Version:\*\*"
# Pattern: (Title ...)(Version: )(\d+\.\d+\.\d+)
# We allow some lines between title and version
pattern = rf"(\*\*{safe_title}\*\*[\s\S]*?{ver_label}\s*)([\d\.]+)"
match = re.search(pattern, content)
if match:
current_ver = match.group(2)
if current_ver != version:
if self.fix:
new_content = content.replace(
match.group(0), f"{match.group(1)}{version}"
)
file_path.write_text(new_content, encoding="utf-8")
log_success(
f"Fixed index for {title}: {current_ver} -> {version}"
)
self.fixed_count += 1
else:
log_error(
f"Mismatch in index for {title}: Found {current_ver}, Expected {version}"
)
self.issues_found += 1
else:
# log_warning(f"Could not find entry for '{title}' in {file_path.name}")
pass
except Exception as e:
log_error(f"Failed to check index {file_path}: {e}")
def run(self):
if not self.plugins_dir.exists():
log_error(f"Plugins directory not found: {self.plugins_dir}")
return
# Scan actions, filters, pipes
for type_dir in self.plugins_dir.iterdir():
if type_dir.is_dir() and type_dir.name in ["actions", "filters", "pipes"]:
for plugin_dir in type_dir.iterdir():
if plugin_dir.is_dir():
self.check_plugin(type_dir.name, plugin_dir)
print("-" * 40)
if self.issues_found > 0:
if self.fix:
print(f"Fixed {self.fixed_count} issues.")
else:
print(f"Found {self.issues_found} version inconsistencies.")
print(f"Run with --fix to automatically resolve them.")
sys.exit(1)
else:
print("All versions are consistent! ✨")
def main():
parser = argparse.ArgumentParser(description="Check version consistency.")
parser.add_argument("--fix", action="store_true", help="Fix inconsistencies")
args = parser.parse_args()
# Assume script is run from root or scripts dir
root = Path.cwd()
if (root / "scripts").exists():
pass
elif root.name == "scripts":
root = root.parent
checker = VersionChecker(str(root), fix=args.fix)
checker.run()
if __name__ == "__main__":
main()

View File

@@ -96,6 +96,15 @@ def scan_plugins_directory(plugins_dir: str) -> list[dict[str, Any]]:
for root, _dirs, files in os.walk(plugins_path): for root, _dirs, files in os.walk(plugins_path):
for file in files: for file in files:
if file.endswith(".py") and not file.startswith("__"): if file.endswith(".py") and not file.startswith("__"):
# Skip specific files that should not trigger release
if file in [
"gemini_manifold.py",
"gemini_manifold_companion.py",
"ACTION_PLUGIN_TEMPLATE.py",
"ACTION_PLUGIN_TEMPLATE_CN.py",
]:
continue
file_path = os.path.join(root, file) file_path = os.path.join(root, file)
metadata = extract_plugin_metadata(file_path) metadata = extract_plugin_metadata(file_path)
if metadata: if metadata:
@@ -109,9 +118,7 @@ def scan_plugins_directory(plugins_dir: str) -> list[dict[str, Any]]:
return plugins return plugins
def compare_versions( def compare_versions(current: list[dict], previous_file: str) -> dict[str, list[dict]]:
current: list[dict], previous_file: str
) -> dict[str, list[dict]]:
""" """
Compare current plugin versions with a previous version file. Compare current plugin versions with a previous version file.
比较当前插件版本与之前的版本文件。 比较当前插件版本与之前的版本文件。
@@ -168,7 +175,9 @@ def format_markdown_table(plugins: list[dict]) -> str:
"|---------------|----------------|-------------|---------------------|", "|---------------|----------------|-------------|---------------------|",
] ]
for plugin in sorted(plugins, key=lambda x: (x.get("type", ""), x.get("title", ""))): for plugin in sorted(
plugins, key=lambda x: (x.get("type", ""), x.get("title", ""))
):
title = plugin.get("title", "Unknown") title = plugin.get("title", "Unknown")
version = plugin.get("version", "Unknown") version = plugin.get("version", "Unknown")
plugin_type = plugin.get("type", "Unknown").capitalize() plugin_type = plugin.get("type", "Unknown").capitalize()
@@ -181,7 +190,9 @@ def format_markdown_table(plugins: list[dict]) -> str:
return "\n".join(lines) return "\n".join(lines)
def format_release_notes(comparison: dict[str, list]) -> str: def format_release_notes(
comparison: dict[str, list], ignore_removed: bool = False
) -> str:
""" """
Format version comparison as release notes. Format version comparison as release notes.
将版本比较格式化为发布说明。 将版本比较格式化为发布说明。
@@ -206,7 +217,7 @@ def format_release_notes(comparison: dict[str, list]) -> str:
) )
lines.append("") lines.append("")
if comparison["removed"]: if comparison["removed"] and not ignore_removed:
lines.append("### 移除插件 / Removed Plugins") lines.append("### 移除插件 / Removed Plugins")
for plugin in comparison["removed"]: for plugin in comparison["removed"]:
lines.append(f"- **{plugin['title']}** v{plugin['version']}") lines.append(f"- **{plugin['title']}** v{plugin['version']}")
@@ -239,6 +250,11 @@ def main():
metavar="FILE", metavar="FILE",
help="Compare with previous version JSON file", help="Compare with previous version JSON file",
) )
parser.add_argument(
"--ignore-removed",
action="store_true",
help="Ignore removed plugins in output",
)
parser.add_argument( parser.add_argument(
"--output", "--output",
"-o", "-o",
@@ -257,7 +273,9 @@ def main():
if args.json: if args.json:
output = json.dumps(comparison, indent=2, ensure_ascii=False) output = json.dumps(comparison, indent=2, ensure_ascii=False)
else: else:
output = format_release_notes(comparison) output = format_release_notes(
comparison, ignore_removed=args.ignore_removed
)
if not output.strip(): if not output.strip():
output = "No changes detected. / 未检测到更改。" output = "No changes detected. / 未检测到更改。"
elif args.json: elif args.json:
@@ -268,7 +286,9 @@ def main():
# Default: simple list # Default: simple list
lines = [] lines = []
for plugin in sorted(plugins, key=lambda x: x.get("title", "")): for plugin in sorted(plugins, key=lambda x: x.get("title", "")):
lines.append(f"{plugin.get('title', 'Unknown')}: v{plugin.get('version', '?')}") lines.append(
f"{plugin.get('title', 'Unknown')}: v{plugin.get('version', '?')}"
)
output = "\n".join(lines) output = "\n".join(lines)
# Write output # Write output