feat(project): sync engineering standards and finalize markdown-normalizer v1.2.7

- Update .github/copilot-instructions.md with latest i18n and naming standards
- Add docs/development/issue-reply-guide.md for professional community engagement
- Sync all documentation (MKDocs, READMEs, Docs) to v1.2.7
- Include CI/CD and Agent instruction templates for better automation
This commit is contained in:
fujie
2026-02-24 15:13:52 +08:00
parent 2da934dd92
commit 377534e6c9
20 changed files with 1675 additions and 337 deletions

View File

@@ -4,15 +4,16 @@
## 📚 目录
1. [插件开发快速入门](#1-quick-start)
2. [核心概念与 SDK 详解](#2-core-concepts-sdk-details)
3. [插件类型深度解析](#3-plugin-types)
* [Action (动作)](#31-action)
* [Filter (过滤器)](#32-filter)
* [Pipe (管道)](#33-pipe)
4. [高级开发模式](#4-advanced-patterns)
5. [最佳实践与设计原则](#5-best-practices)
6. [故障排查](#6-troubleshooting)
1. [插件开发快速入门](#1-quick-start)
2. [核心概念与 SDK 详解](#2-core-concepts-sdk-details)
3. [插件类型深度解析](#3-plugin-types)
* [Action (动作)](#31-action)
* [Filter (过滤器)](#32-filter)
* [Pipe (管道)](#33-pipe)
4. [高级开发模式](#4-advanced-patterns)
5. [最佳实践与设计原则](#5-best-practices)
6. [仓库规范openwebui-extensions](#6-repo-standards)
7. [故障排查](#7-troubleshooting)
---
@@ -21,9 +22,10 @@
### 1.1 什么是 OpenWebUI 插件?
OpenWebUI 插件(官方称为 "Functions")是扩展平台功能的主要方式。它们运行在后端 Python 环境中,允许你:
* 🔌 **集成新模型**:通过 Pipe 接入 Claude、Gemini 或自定义 RAG。
* 🎨 **增强交互**:通过 Action 在消息旁添加按钮(如"导出"、"生成图表"
* 🔧 **干预流程**:通过 Filter 在请求前后修改数据(如注入上下文、敏感词过滤)。
* 🔌 **集成新模型**:通过 Pipe 接入 Claude、Gemini 或自定义 RAG
* 🎨 **增强交互**:通过 Action 在消息旁添加按钮(如"导出"、"生成图表")。
* 🔧 **干预流程**:通过 Filter 在请求前后修改数据(如注入上下文、敏感词过滤)。
### 1.2 你的第一个插件 (Hello World)
@@ -69,9 +71,10 @@ class Action:
### 2.1 ⚠️ 重要:同步与异步
OpenWebUI 插件运行在 `asyncio` 事件循环中。
* **原则**:所有 I/O 操作(数据库、文件、网络)必须非阻塞。
* **陷阱**:直接调用同步方法(如 `time.sleep`, `requests.get`)会卡死整个服务器
* **解决**:使用 `await asyncio.to_thread(sync_func, ...)` 包装同步调用
* **原则**:所有 I/O 操作(数据库、文件、网络)必须非阻塞
* **陷阱**:直接调用同步方法(如 `time.sleep`, `requests.get`)会卡死整个服务器
* **解决**:使用 `await asyncio.to_thread(sync_func, ...)` 包装同步调用。
### 2.2 核心参数详解
@@ -88,8 +91,8 @@ OpenWebUI 插件运行在 `asyncio` 事件循环中。
### 2.3 配置系统 (Valves)
* **`Valves`**: 管理员全局配置。
* **`UserValves`**: 用户级配置(优先级更高,可覆盖全局)。
* **`Valves`**: 管理员全局配置。
* **`UserValves`**: 用户级配置(优先级更高,可覆盖全局)。
```python
class Filter:
@@ -113,7 +116,7 @@ class Filter:
**定位**:在消息下方添加按钮,用户点击触发。
**高级用法:前端执行 JavaScript (文件下载示例)**
#### 高级用法:前端执行 JavaScript (文件下载示例)
```python
import base64
@@ -138,11 +141,11 @@ async def action(self, body, __event_call__):
**定位**:中间件,拦截并修改请求/响应。
* **`inlet`**: 请求前。用于注入上下文、修改模型参数。
* **`outlet`**: 响应后。用于格式化输出、保存日志。
* **`stream`**: 流式处理中。用于实时敏感词过滤。
* **`inlet`**: 请求前。用于注入上下文、修改模型参数。
* **`outlet`**: 响应后。用于格式化输出、保存日志。
* **`stream`**: 流式处理中。用于实时敏感词过滤。
**示例:注入环境变量**
#### 示例:注入环境变量
```python
async def inlet(self, body, __metadata__):
@@ -159,7 +162,7 @@ async def inlet(self, body, __metadata__):
**定位**:自定义模型/代理。
**示例:简单的 OpenAI 代理**
#### 示例:简单的 OpenAI 代理
```python
import requests
@@ -180,11 +183,14 @@ class Pipe:
## 4. 高级开发模式 {: #4-advanced-patterns }
### 4.1 Pipe 与 Filter 协同
利用 `__request__.app.state` 在不同插件间共享数据。
* **Pipe**: `__request__.app.state.search_results = [...]`
* **Filter (Outlet)**: 读取 `search_results` 并将其格式化为引用链接附加到回复末尾。
* **Pipe**: `__request__.app.state.search_results = [...]`
* **Filter (Outlet)**: 读取 `search_results` 并将其格式化为引用链接附加到回复末尾。
### 4.2 异步后台任务
不阻塞用户响应,在后台执行耗时操作(如生成总结、存库)。
```python
@@ -205,7 +211,7 @@ async def background_job(self, chat_id):
#### 工作流程
```
```text
┌──────────────────────────────────────────────────────────────┐
│ 1. Python Action │
│ ├── 分析消息内容 │
@@ -297,10 +303,10 @@ async def action(self, body, __event_call__, __metadata__, ...):
#### 优势
- **纯 Markdown 输出**:结果是标准的 Markdown 图片语法,无需 HTML 代码块
- **自包含**:图片以 Base64 Data URL 嵌入,无外部依赖
- **持久化**:通过 API 回写,消息重新加载后图片仍然存在
- **跨平台**:任何支持 Markdown 图片的客户端都能显示
* **纯 Markdown 输出**:结果是标准的 Markdown 图片语法,无需 HTML 代码块
* **自包含**:图片以 Base64 Data URL 嵌入,无外部依赖
* **持久化**:通过 API 回写,消息重新加载后图片仍然存在
* **跨平台**:任何支持 Markdown 图片的客户端都能显示
#### HTML 注入 vs JS 渲染嵌入 Markdown
@@ -315,20 +321,23 @@ async def action(self, body, __event_call__, __metadata__, ...):
#### 参考实现
- `plugins/actions/infographic/infographic.py` - 基于 AntV + Data URL 的生产级实现
* `plugins/actions/infographic/infographic.py` - 基于 AntV + Data URL 的生产级实现
## 5. 最佳实践与设计原则 {: #5-best-practices }
### 5.1 命名与定位
* **简短有力**:如 "闪记卡", "精读"。避免 "文本分析助手" 这种泛词。
* **功能互补**:不要重复造轮子,明确你的插件解决了什么特定问题
* **简短有力**:如 "闪记卡", "精读"。避免 "文本分析助手" 这种泛词
* **功能互补**:不要重复造轮子,明确你的插件解决了什么特定问题。
### 5.2 用户体验 (UX)
* **反馈及时**:耗时操作前先发送 `notification` ("正在生成...")。
* **视觉美观**Action 输出 HTML 时,使用现代化的 CSS圆角、阴影、渐变
* **智能引导**:检测到文本过短时,提示用户"建议输入更多内容以获得更好结果"
* **反馈及时**:耗时操作前先发送 `notification` ("正在生成...")
* **视觉美观**Action 输出 HTML 时,使用现代化的 CSS圆角、阴影、渐变
* **智能引导**:检测到文本过短时,提示用户"建议输入更多内容以获得更好结果"。
### 5.3 错误处理
永远不要让插件静默失败。捕获异常并通过 `__event_emitter__` 告知用户。
```python
@@ -343,8 +352,76 @@ except Exception as e:
---
## 6. 故障排查 {: #6-troubleshooting }
## 6. 仓库规范openwebui-extensions {: #6-repo-standards }
* **HTML 不显示?** 确保包裹在 ` ```html ... ``` ` 代码块中。
* **数据库报错?** 检查是否在 `async` 函数中直接调用了同步的 DB 方法,请使用 `asyncio.to_thread`
* **参数未生效?** 检查 `Valves` 定义是否正确,以及是否被 `UserValves` 覆盖。
### 6.1 单文件 i18n 规范
本仓库要求每个插件采用**单文件源码 + 内置多语言**方案,禁止按语言拆分多个 `.py` 文件。
* 代码路径规范:`plugins/{type}/{name}/{name}.py`
* 文档规范:必须同时提供 `README.md``README_CN.md`
### 6.2 上下文访问规范(必选)
优先通过 `_get_user_context``_get_chat_context` 提取上下文,避免直接硬编码读取 `__user__``body` 字段。
### 6.3 事件与日志规范
* 用状态/通知事件给用户反馈进度。
* 前端调试优先使用 `execute` 注入的控制台日志。
* 后端统一使用 Python `logging`,生产代码避免 `print()`
### 6.4 前端语言探测防卡死
通过 `__event_call__` 获取前端语言时,必须同时满足:
* JS 端 `try...catch` 并保证返回值
* 后端 `asyncio.wait_for(..., timeout=2.0)`
这样可以避免前端异常导致后端永久等待。
### 6.5 Copilot SDK 工具参数定义
开发 Copilot SDK 工具时,应使用 `pydantic.BaseModel` 显式声明参数,并在 `define_tool(...)` 中通过 `params_type` 传入。
### 6.6 Copilot SDK 流式输出格式
* 思考过程使用原生 `<think>...</think>`
* 正文或工具卡片输出前,必须先闭合 `</think>`
* 工具卡片使用 `<details type="tool_calls" ...>` 原生结构。
* `arguments``result` 属性中的双引号必须转义为 `&quot;`
### 6.7 从 `plugins/` 全量提炼的关键开发知识
* **输入与上下文**:统一做多模态文本抽取;优先 `_get_user_context` / `_get_chat_context`;前端语言探测必须 `wait_for` 超时保护。
* **长任务反馈**:执行前立即发送 `status/notification`,过程分阶段汇报,失败时用户提示简洁、后台日志完整。
* **HTML/渲染输出**:使用固定包装器与插入点,支持覆盖与合并两种模式;主题跟随父页面与系统主题。
* **前端导出闭环**:离屏渲染 SVG/PNG -> 上传 `/api/v1/files/` -> 事件更新 + 持久化更新,避免刷新丢失。
* **DOCX 生产模式**`TITLE_SOURCE` 多级回退;导出前剔除 reasoningLaTeX 转 OMML支持引用锚点与参考文献。
* **文件访问回退链**DB 内联 -> S3 -> 本地路径变体 -> 公网 URL -> 内部 API -> 原始字段,并在每层限制字节上限。
* **Filter 单例安全**:禁止在 `self` 保存请求态;上下文压缩采用 inlet/outlet 双阶段 + 异步后台任务。
* **工具与工作区安全**:工具参数用 `params_type` 显式建模;路径解析后必须二次校验在 workspace 根目录内。
* **文件交付标准**:本地生成 -> 发布工具 -> 返回 `/api/v1/files/{id}/content`,并带 `skip_rag=true` 元数据。
* **MoE 聚合优化**:识别聚合提示词后重写为结构化综合分析任务,并可在聚合阶段切换模型。
### 6.8 Copilot 工程化配置GitHub Copilot + Gemini CLI + 反重力开发)
统一工程化配置请参考:
* `docs/development/copilot-engineering-plan.md`
* `docs/development/copilot-engineering-plan.zh.md`
该设计文档规定了:
* 工具参数建模与路由规则
* 文件创建与发布协议
* 可回滚的高迭代交付模式
* 流式输出与工具卡片兼容要求
---
## 7. 故障排查 {: #7-troubleshooting }
* **HTML 不显示?** 确保包裹在 ` ```html ... ``` ` 代码块中。
* **数据库报错?** 检查是否在 `async` 函数中直接调用了同步的 DB 方法,请使用 `asyncio.to_thread`
* **参数未生效?** 检查 `Valves` 定义是否正确,以及是否被 `UserValves` 覆盖。