- Enable default overwrite installation policy for overlapping skills - Support deep recursive GitHub trees discovery mechanism to resolve #58 - Refactor internal architecture to fully decouple stateless helper logic - READMEs and docs synced (v0.3.0)
7.7 KiB
7.7 KiB
自动发现与去重指南
功能概述
OpenWebUI Skills 管理工具现在能够自动发现并安装 GitHub 仓库中的所有 skill,并内置重复处理机制。
新增功能
1. 自动仓库根目录检测 🎯
当你提供一个 GitHub 仓库根 URL(不含 /tree/ 路径)时,系统会自动将其转换为发现模式。
示例
输入:https://github.com/nicobailon/visual-explainer
↓
自动转换为:https://github.com/nicobailon/visual-explainer/tree/main
↓
发现所有 skill 子目录
2. 自动发现 Skill 🔍
一旦检测到 tree URL,工具会自动:
- 调用 GitHub API 列出所有子目录
- 为每个子目录创建 skill 安装 URL
- 尝试从每个子目录获取
SKILL.md或README.md - 将所有发现的 skill 以批量模式安装
支持的 URL 格式
✓ https://github.com/owner/repo → 自动检测为仓库根
✓ https://github.com/owner/repo/ → 带末尾斜杠
✓ https://github.com/owner/repo/tree/main → 现有 tree 格式
✓ https://github.com/owner/repo/tree/main/skills → 嵌套 skill 目录
3. 重复 URL 移除 🔄
安装多个 skill 时,系统会自动:
- 检测重复的 URL
- 移除重复项(保持顺序不变)
- 通知用户移除了多少个重复项
- 跳过重复 URL 的处理
示例
输入 URL(共 5 个):
- https://github.com/user/repo/tree/main/skill1
- https://github.com/user/repo/tree/main/skill1 ← 重复
- https://github.com/user/repo/tree/main/skill2
- https://github.com/user/repo/tree/main/skill2 ← 重复
- https://github.com/user/repo/tree/main/skill3
处理结果:
- 唯一 URL:3 个
- 移除重复:2 个
- 状态提示:「已从批量队列中移除 2 个重复 URL」
4. 重复 Skill 名称检测 ⚠️
如果多个 URL 在批量安装时导致相同的 skill 名称:
- 系统检测到重复安装
- 记录详细的警告日志
- 通知用户发生了冲突
- 显示采取了什么行动(已安装/已更新)
示例场景
Skill A: skill1.zip → 创建 skill 「报告生成器」
Skill B: skill2.zip → 创建 skill 「报告生成器」 ← 同名!
警告:「技能名称 '报告生成器' 重复 - 多次安装。」
注意:最后一次安装可能已覆盖了之前的版本
(取决于 ALLOW_OVERWRITE_ON_CREATE 设置)
使用示例
示例 1:简单仓库根目录
用户输入:
「从 https://github.com/nicobailon/visual-explainer 安装 skill」
系统响应:
「检测到 GitHub repo 根目录:https://github.com/nicobailon/visual-explainer。
自动转换为发现模式...」
「正在从 https://github.com/nicobailon/visual-explainer/tree/main 发现 skill...」
「正在安装 5 个技能...」
示例 2:带嵌套 Skill 目录
用户输入:
「从 https://github.com/anthropics/skills 安装所有 skill」
系统响应:
「检测到 GitHub repo 根目录:https://github.com/anthropics/skills。
自动转换为发现模式...」
「正在从 https://github.com/anthropics/skills/tree/main 发现 skill...」
「正在安装 12 个技能...」
示例 3:重复处理
用户输入(批量):
[
"https://github.com/user/repo/tree/main/skill-a",
"https://github.com/user/repo/tree/main/skill-a", ← 重复
"https://github.com/user/repo/tree/main/skill-b"
]
系统响应:
「已从批量队列中移除 1 个重复 URL。」
「正在安装 2 个技能...」
结果:
- 批量安装完成:成功 2 个,失败 0 个
实现细节
检测逻辑
仓库根目录检测使用正则表达式:
^https://github\.com/([^/]+)/([^/]+)/?$
# 匹配:
# https://github.com/owner/repo ✓
# https://github.com/owner/repo/ ✓
# 不匹配:
# https://github.com/owner/repo/tree/main ✗
# https://github.com/owner/repo/blob/main/file.md ✗
规范化
检测到的仓库根 URL 会被转换为:
https://github.com/{owner}/{repo} → https://github.com/{owner}/{repo}/tree/main
首先尝试 main 分支;如果不存在,GitHub API 会自动回退到 master。
发现流程
- 用正则表达式解析 tree URL,提取 owner、repo、branch 和 path
- 调用 GitHub API:
/repos/{owner}/{repo}/contents{path}?ref={branch} - 筛选目录(跳过以
.开头的隐藏目录) - 对于每个子目录,创建指向它的 tree URL
- 返回发现的 tree URL 列表以供批量安装
去重策略
seen_urls = set()
unique_urls = []
duplicates_removed = 0
for url in input_urls:
if url not in seen_urls:
unique_urls.append(url)
seen_urls.add(url)
else:
duplicates_removed += 1
- 保持 URL 顺序
- 时间复杂度 O(n)
- 低内存开销
重复名称跟踪
在批量安装期间:
installed_names = {} # {小写名称: url}
for skill in results:
if success:
name_lower = skill["name"].lower()
if name_lower in installed_names:
# 检测到重复
warn_user(name_lower, installed_names[name_lower])
else:
installed_names[name_lower] = current_url
配置
无需新增 Valve 参数。现有设置继续有效:
| 参数 | 影响 |
|---|---|
ALLOW_OVERWRITE_ON_CREATE |
控制重复 skill 名称时是否更新或出错 |
TRUSTED_DOMAINS |
对所有发现的 URL 继续强制执行 |
INSTALL_FETCH_TIMEOUT |
适用于每个 GitHub API 发现调用 |
SHOW_STATUS |
显示所有发现和去重消息 |
API 变化
install_skill() 方法
新增行为:
- 自动将仓库根 URL 转换为 tree 格式
- 自动发现 tree URL 中的所有 skill 子目录
- 批量处理前对 URL 列表去重
- 安装期间跟踪重复的 skill 名称
参数:(无变化)
url:现在可以接受仓库根目录(如https://github.com/owner/repo)name:在批量/自动发现模式下被忽略overwrite:控制 skill 名称冲突时的行为- 其他参数保持不变
返回值:(无变化)
- 单个 skill:返回安装元数据
- 批量安装:返回包含成功/失败数的批处理摘要
错误处理
发现失败
- 如果仓库根规范化失败 → 视为普通 URL 处理
- 如果 tree 发现 API 失败 → 记录警告,继续尝试单文件安装
- 如果未找到 SKILL.md 或 README.md → 该 URL 的特定错误
批量失败
- 重复 URL 移除 → 通知用户但继续处理
- 单个 skill 失败 → 记录错误,继续处理下一个 skill
- 最终摘要显示成功/失败数
遥测和日志
所有操作都会发出状态更新:
- ✓ 「检测到 GitHub repo 根目录:...」
- ✓ 「已从批量队列中移除 {count} 个重复 URL」
- ⚠️ 「警告:技能名称 '{name}' 重复」
- ✗ 「{url} 安装失败:{reason}」
查看 OpenWebUI 日志了解详细的错误追踪。
测试
运行包含的测试套件:
python3 docs/test_auto_discovery.py
测试覆盖范围:
- ✓ 仓库根 URL 检测(6 个用例)
- ✓ 发现模式的 URL 规范化(4 个用例)
- ✓ 去重逻辑(3 个场景)
- ✓ 总计:13/13 个测试用例通过
向后兼容性
✅ 完全向后兼容。
- 现有 tree URL 工作方式不变
- 现有 blob/raw URL 功能不变
- 现有批量安装不受影响
- 新功能是自动的(无需用户操作)
- 无 API 破坏性变更
未来增强
可能的未来改进:
- 支持 GitLab、Gitea 和其他 Git 平台
- 智能分支检测(master → main 回退)
- 自动发现期间按名称模式筛选 skill
- 带冲突解决策略的批量安装
- 缓存发现结果以减少 API 调用