310 lines
13 KiB
Markdown
310 lines
13 KiB
Markdown
# 🧰 OpenWebUI Skills Manager Tool
|
|
|
|
| By [Fu-Jie](https://github.com/Fu-Jie) · v0.3.0 | [⭐ Star this repo](https://github.com/Fu-Jie/openwebui-extensions) |
|
|
| :--- | ---: |
|
|
|
|
|  |  |  |  |  |  |  |
|
|
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
|
|
|
|
A standalone OpenWebUI Tool plugin to manage native **Workspace > Skills** for any model.
|
|
|
|
## Install with Batch Install Plugins
|
|
|
|
If you already use [Batch Install Plugins from GitHub](https://openwebui.com/posts/batch_install_plugins_install_popular_plugins_in_s_c9fd6e80), you can install or update this plugin with:
|
|
|
|
```text
|
|
Install plugin from Fu-Jie/openwebui-extensions
|
|
```
|
|
|
|
When the selection dialog opens, search for this plugin, check it, and continue.
|
|
|
|
> [!IMPORTANT]
|
|
> If the official OpenWebUI Community version is already installed, remove it first. After that, Batch Install Plugins can keep this plugin updated in future runs.
|
|
|
|
## What's New
|
|
|
|
- **🤖 Automatic Repo Root Discovery**: Install any GitHub repo by providing just the root URL (e.g., `https://github.com/owner/repo`). System auto-converts to discovery mode and installs all skills.
|
|
- **🔄 Batch Deduplication**: Automatically removes duplicate URLs from batch installations and detects duplicate skill names.
|
|
- Added GitHub skills-directory auto-discovery for `install_skill` (e.g., `.../tree/main/skills`) to install all child skills in one request.
|
|
- Fixed language detection with robust frontend-first fallback (`__event_call__` + timeout), request header fallback, and profile fallback.
|
|
|
|
> [!TIP]
|
|
> **💡 Looking to batch install global plugins (Actions, Filters, Pipes, Tools)?**
|
|
> This plugin specializes in managing Workspace Skills for your assistants. If you need to install and manage global function-based plugins, use our companion tool [Batch Install Plugins from GitHub](https://openwebui.com/posts/batch_install_plugins_install_popular_plugins_in_s_c9fd6e80) for an optimized installation workflow.
|
|
|
|
## Key Features
|
|
|
|
- **🌐 Model-agnostic**: Can be enabled for any model that supports OpenWebUI Tools.
|
|
- **🛠️ Simple Skill Management**: Directly manage OpenWebUI skill records.
|
|
- **🔐 User-scoped Safety**: Operates on current user's accessible skills.
|
|
- **📡 Friendly Status Feedback**: Emits status bubbles for each operation.
|
|
- **🔍 Auto-Discovery**: Automatically discovers and installs all skills from GitHub repository trees.
|
|
- **⚙️ Smart Deduplication**: Removes duplicate URLs and detects conflicting skill names during batch installation.
|
|
|
|
## How to Use
|
|
|
|
1. Open OpenWebUI and go to **Workspace > Tools**.
|
|
2. Install **OpenWebUI Skills Manager Tool** from the official marketplace.
|
|
3. Enable this tool for your model/chat.
|
|
4. Ask the model to call tool operations, for example:
|
|
- "List my skills"
|
|
- "Show skill named docs-writer"
|
|
- "Create a skill named meeting-notes with content ..."
|
|
- "Update skill ..."
|
|
- "Delete skill ..."
|
|
|
|
### Manual Installation (Alternative)
|
|
|
|
- Create a new Tool and paste `openwebui_skills_manager.py`.
|
|
|
|
## Example: Install Skills
|
|
|
|
This tool can fetch and install skills directly from URLs (supporting GitHub repo roots, tree/blob, raw markdown, and .zip/.tar archives).
|
|
|
|
### Auto-discover all skills from a GitHub repo
|
|
|
|
- "Install skills from <https://github.com/nicobailon/visual-explainer>" ← Auto-discovers all subdirectories
|
|
- "Install all skills from <https://github.com/anthropics/skills>" ← Installs entire skills directory
|
|
|
|
### Install a single skill from GitHub
|
|
|
|
- "Install skill from <https://github.com/anthropics/skills/tree/main/skills/xlsx>"
|
|
- "Install skill from <https://github.com/Fu-Jie/openwebui-extensions/blob/main/.agent/skills/test-copilot-pipe/SKILL.md>"
|
|
|
|
### Batch install multiple skills
|
|
|
|
- "Install these skills: ['https://github.com/anthropics/skills/tree/main/skills/xlsx', 'https://github.com/anthropics/skills/tree/main/skills/docx']"
|
|
|
|
> **Tip**: For GitHub, the tool automatically resolves directory (tree) URLs by looking for `SKILL.md`.
|
|
|
|
## Installation Logic
|
|
|
|
### URL Type Recognition & Processing
|
|
|
|
The `install_skill` method automatically detects and handles different URL formats with the following logic:
|
|
|
|
#### **1. GitHub Repository Root** (Auto-Discovery)
|
|
|
|
**Format:** `https://github.com/owner/repo` or `https://github.com/owner/repo/`
|
|
|
|
**Processing:**
|
|
|
|
1. Detected via regex: `^https://github\.com/([^/]+)/([^/]+)/?$`
|
|
2. Automatically converted to: `https://github.com/owner/repo/tree/main`
|
|
3. API queries all subdirectories at `/repos/{owner}/{repo}/contents?ref=main`
|
|
4. For each subdirectory, creates skill URLs
|
|
5. Attempts to fetch `SKILL.md` from each directory
|
|
6. All discovered skills installed in **batch mode**
|
|
|
|
**Example Flow:**
|
|
|
|
```
|
|
Input: https://github.com/nicobailon/visual-explainer
|
|
↓ [Detect: repo root]
|
|
↓ [Convert: add /tree/main]
|
|
↓ [Query: GitHub API for subdirs]
|
|
Discover: skill1, skill2, skill3, ...
|
|
↓ [Batch mode]
|
|
Install: All skills found
|
|
```
|
|
|
|
#### **2. GitHub Tree (Directory) URL** (Auto-Discovery)
|
|
|
|
**Format:** `https://github.com/owner/repo/tree/branch/path/to/directory`
|
|
|
|
**Processing:**
|
|
|
|
1. Detected via regex: `/tree/` in URL
|
|
2. API queries directory contents: `/repos/{owner}/{repo}/contents/path?ref=branch`
|
|
3. Filters for subdirectories (skips `.hidden` dirs)
|
|
4. For each subdirectory, attempts to fetch `SKILL.md`
|
|
5. All discovered skills installed in **batch mode**
|
|
|
|
**Example:**
|
|
|
|
```
|
|
Input: https://github.com/anthropics/skills/tree/main/skills
|
|
↓ [Query: /repos/anthropics/skills/contents/skills?ref=main]
|
|
Discover: xlsx, docx, pptx, markdown, ...
|
|
Install: All 12 skills in batch mode
|
|
```
|
|
|
|
#### **3. GitHub Blob (File) URL** (Single Install)
|
|
|
|
**Format:** `https://github.com/owner/repo/blob/branch/path/to/SKILL.md`
|
|
|
|
**Processing:**
|
|
|
|
1. Detected via pattern: `/blob/` in URL
|
|
2. Converted to raw URL: `https://raw.githubusercontent.com/owner/repo/branch/path/to/SKILL.md`
|
|
3. Content fetched and parsed as single skill
|
|
4. Installed in **single mode**
|
|
|
|
**Example:**
|
|
|
|
```
|
|
Input: https://github.com/user/repo/blob/main/SKILL.md
|
|
↓ [Convert: /blob/ → raw.githubusercontent.com]
|
|
↓ [Fetch: raw markdown content]
|
|
Parse: Skill name, description, content
|
|
Install: Single skill
|
|
```
|
|
|
|
#### **4. Raw GitHub URL** (Single Install)
|
|
|
|
**Format:** `https://raw.githubusercontent.com/owner/repo/branch/path/to/SKILL.md`
|
|
|
|
**Processing:**
|
|
|
|
1. Direct download from raw content endpoint
|
|
2. Content parsed as markdown with frontmatter
|
|
3. Skill metadata extracted (name, description from frontmatter)
|
|
4. Installed in **single mode**
|
|
|
|
**Example:**
|
|
|
|
```
|
|
Input: https://raw.githubusercontent.com/Fu-Jie/openwebui-extensions/main/SKILL.md
|
|
↓ [Fetch: raw content directly]
|
|
Parse: Extract metadata
|
|
Install: Single skill
|
|
```
|
|
|
|
#### **5. Archive Files** (Single Install)
|
|
|
|
**Format:** `https://example.com/skill.zip` or `.tar`, `.tar.gz`, `.tgz`
|
|
|
|
**Processing:**
|
|
|
|
1. Detected via file extension: `.zip`, `.tar`, `.tar.gz`, `.tgz`
|
|
2. Downloaded and extracted safely:
|
|
- Validates member paths (prevents path traversal attacks)
|
|
- Extracts to temporary directory
|
|
3. Searches for `SKILL.md` in archive root
|
|
4. Content parsed and installed in **single mode**
|
|
|
|
**Example:**
|
|
|
|
```
|
|
Input: https://github.com/user/repo/releases/download/v1.0/my-skill.zip
|
|
↓ [Download: zip archive]
|
|
↓ [Extract safely: validate paths]
|
|
↓ [Search: SKILL.md]
|
|
Parse: Extract metadata
|
|
Install: Single skill
|
|
```
|
|
|
|
### Batch Mode vs Single Mode
|
|
|
|
| Mode | Triggered By | Behavior | Result |
|
|
|------|--------------|----------|--------|
|
|
| **Batch** | Repo root or tree URL | All subdirectories auto-discovered | List of { succeeded, failed, results } |
|
|
| **Single** | Blob, raw, or archive URL | Direct content fetch and parse | { success, id, name, ... } |
|
|
| **Batch** | List of URLs | Each URL processed individually | List of results |
|
|
|
|
### Deduplication During Batch Install
|
|
|
|
When multiple URLs are provided in batch mode:
|
|
|
|
1. **URL Deduplication**: Removes duplicate URLs (preserves order)
|
|
2. **Name Collision Detection**: Tracks installed skill names
|
|
- If same name appears multiple times → warning notification
|
|
- Action depends on `ALLOW_OVERWRITE_ON_CREATE` valve
|
|
|
|
**Example:**
|
|
|
|
```
|
|
Input URLs: [url1, url1, url2, url2, url3]
|
|
↓ [Deduplicate]
|
|
Unique: [url1, url2, url3]
|
|
Process: 3 URLs
|
|
Output: "Removed 2 duplicate URL(s)"
|
|
```
|
|
|
|
### Skill Name Resolution
|
|
|
|
During parsing, skill names are resolved in this order:
|
|
|
|
1. **User-provided name** (if specified in `name` parameter)
|
|
2. **Frontmatter metadata** (from `---` block at file start)
|
|
3. **Markdown h1 heading** (first `# Title` found)
|
|
4. **Extracted directory/file name** (from URL path)
|
|
5. **Fallback name:** `"installed-skill"` (last resort)
|
|
|
|
**Example:**
|
|
|
|
```
|
|
Markdown document structure:
|
|
───────────────────────────
|
|
---
|
|
title: "My Custom Skill"
|
|
description: "Does something useful"
|
|
---
|
|
|
|
# Alternative Title
|
|
|
|
Content here...
|
|
───────────────────────────
|
|
|
|
Resolution order:
|
|
1. Check frontmatter: title = "My Custom Skill" ✓ Use this
|
|
2. (Skip other options)
|
|
|
|
Result: Skill created as "My Custom Skill"
|
|
```
|
|
|
|
### Safety & Security
|
|
|
|
All installations enforce:
|
|
|
|
- ✅ **Domain Whitelist** (TRUSTED_DOMAINS): Only github.com, huggingface.co, githubusercontent.com allowed
|
|
- ✅ **Scheme Validation**: Only http/https URLs accepted
|
|
- ✅ **Path Traversal Prevention**: Archives validated before extraction
|
|
- ✅ **User Scope**: Operations isolated per user_id
|
|
- ✅ **Timeout Protection**: Configurable timeout (default 12s)
|
|
|
|
### Error Handling
|
|
|
|
| Error Case | Handling |
|
|
|-----------|----------|
|
|
| Unsupported scheme (ftp://, file://) | Blocked at validation |
|
|
| Untrusted domain | Rejected (domain not in whitelist) |
|
|
| URL fetch timeout | Timeout error with retry suggestion |
|
|
| Invalid archive | Error on extraction attempt |
|
|
| No SKILL.md found | Error per subdirectory (batch continues) |
|
|
| Duplicate skill name | Warning notification (depends on valve) |
|
|
| Missing skill name | Error (name is required) |
|
|
|
|
## Configuration (Valves)
|
|
|
|
| Parameter | Default | Description |
|
|
| --- | --- | --- |
|
|
| `SHOW_STATUS` | `True` | Show operation status updates in OpenWebUI status bar. |
|
|
| `ALLOW_OVERWRITE_ON_CREATE` | `False` | Allow `create_skill`/`install_skill` to overwrite same-name skill by default. |
|
|
| `INSTALL_FETCH_TIMEOUT` | `12.0` | URL fetch timeout in seconds for skill installation. |
|
|
| `TRUSTED_DOMAINS` | `github.com,huggingface.co,githubusercontent.com` | Comma-separated list of primary trusted domains for downloads (always enforced). Subdomains automatically allowed (e.g., `github.com` allows `api.github.com`). See [Domain Whitelist Guide](https://github.com/Fu-Jie/openwebui-extensions/blob/main/plugins/tools/openwebui-skills-manager/docs/DOMAIN_WHITELIST.md). |
|
|
|
|
## Supported Tool Methods
|
|
|
|
| Method | Purpose |
|
|
| --- | --- |
|
|
| `list_skills` | List current user's skills. |
|
|
| `show_skill` | Show one skill by `skill_id` or `name`. |
|
|
| `install_skill` | Install skill from URL into OpenWebUI native skills. |
|
|
| `create_skill` | Create a new skill (or overwrite when allowed). |
|
|
| `update_skill` | Modify an existing skill by id or name. Update any combination of: `new_name` (rename), `description`, `content`, or `is_active` (enable/disable). Validates name uniqueness. |
|
|
| `delete_skill` | Delete a skill by `skill_id` or `name`. |
|
|
|
|
## Support
|
|
|
|
If this plugin has been useful, a star on [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) is a big motivation for me. Thank you for the support.
|
|
|
|
## Others
|
|
|
|
- This tool manages OpenWebUI native skill records and supports direct URL installation.
|
|
- For advanced orchestration, combine with other Pipe/Tool workflows.
|
|
|
|
## Changelog
|
|
|
|
See full history in the GitHub repository releases and commits.
|