Files
Fu-Jie_openwebui-extensions/plugins/pipes/github-copilot-sdk/SKILLS_BEST_PRACTICES.md
Fu-Jie 0c7201902c feat(github-copilot-sdk): add workspace skills support (v0.9.0) (#51)
* feat(github-copilot-sdk): add workspace skills support

- Introduce ENABLE_WORKSPACE_SKILLS valve to enable/disable workspace custom tools discovery
- Modify _build_session_config() to auto-load tools from .copilot-skills/ directory
- Add workspace_skills_example.py template with 3 working example tools
- Update README.md and README_CN.md with Workspace Skills guide and usage examples
- Create v0.9.0.md and v0.9.0_CN.md release notes
- Sync version to all docs files (index.md, index.zh.md, and main docs)
- Bump version from 0.8.0 to 0.9.0 across all 7+ locations

* docs: establish temp files handling policy (project-based, not /tmp)

- Add TEMP_FILES_POLICY.md guideline for all skills and workflows
- Update pr-submitter skill to use .temp/ directory instead of /tmp
- Update release-prep skill documentation with temp file convention
- Add .temp/ and .build/ entries to .gitignore
- Create internal policy memo in /memories/repo/

This policy ensures:
- All temporary files stay within project workspace (not system /tmp)
- Alignment with OpenWebUI workspace isolation principles
- Multi-user safety and cleanup traceability
- Consistent handling across all skills and development workflows

* fix(terminology): rename 'workspace skills' to 'workspace custom tools' for accuracy

The term 'Skills' in Anthropic context refers to instruction-based frameworks
(SKILL.md files with YAML frontmatter + markdown), not custom tool functions.

Our implementation uses @define_tool decorator to define custom tools that the
SDK auto-discovers from .copilot-skills/ directory. These are Tools, not Skills.

Changes:
- Rename ENABLE_WORKSPACE_SKILLS valve -> ENABLE_WORKSPACE_TOOLS
- Update all documentation (README, README_CN, docs, release notes)
- Fix section headings and descriptions throughout
- Ensure consistent terminology across all files

This is a terminology-only change; functionality remains identical.

* feat(pipes): release v0.9.0 of GitHub Copilot SDK Pipe

- Integrated OpenWebUI Skills Bridge and manage_skills tool
- Reinforced status bar stability with session_finalized logic
- Added persistent SDK config directory support

* docs(pipes): add comprehensive guides and v0.9.0 notes for Copilot SDK

- Added skill manager and best practices guides
- Added publishing tool documentation
- Included v0.9.0 release notes and deployment script
- Updated usage guides
2026-02-28 03:50:56 +08:00

210 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Skills Best Practices
A concise guide to writing, organizing, and maintaining Copilot SDK skills effectively.
---
## Understanding How Skills Work
Skills are **not command-line tools**. They are context-injected instruction sets:
1. The Copilot SDK daemon reads every `SKILL.md` file from your `skill_directories`
2. It extracts the YAML `description` field from each skill
3. When the user sends a message, the SDK compares intent against all descriptions
4. If a match is found, the SDK fires `skill.invoked` and **injects the full SKILL.md body** into the conversation as instructions
5. The agent reads those instructions and executes them using `bash`, `create_file`, `view_file`, etc.
**Key implication**: never run a skill's name as a bash command (e.g., `finance-reporting`). The skill IS the instructions, not an executable.
---
## Writing a Good `description` Field
The `description` in `SKILL.md` frontmatter is the **primary trigger mechanism**. The SDK uses it like a semantic router.
### Do ✅
- Start with a verb: "Manage…", "Generate…", "Analyze…"
- Include explicit "Use when:" scenarios — this is the most reliable trigger signal
- Cover all the intent variations a user might express
```yaml
description: Generate a PowerPoint presentation from an outline or topic.
Use when: creating slides, building a deck, making a presentation, exporting to PPTX.
```
### Don't ❌
- Vague descriptions: "A useful skill for various things"
- Overlapping descriptions with other skills (causes misfires)
- Omitting "Use when:" examples (reduces trigger reliability significantly)
### Rule of Thumb
If two people would phrase the same request differently (e.g., "make slides" vs. "create a deck"), both phrasings should appear somewhere in the description.
---
## Structure: What Goes Where
```
skill-name/
├── SKILL.md ← Required. Frontmatter + core instructions
├── .owui_id ← Auto-generated. DO NOT edit or delete
├── references/ ← Optional. Supplementary docs, loaded on demand
│ └── advanced.md
├── scripts/ ← Optional. Helper shell/Python scripts
└── assets/ ← Optional. Templates, sample files, static data
```
### When to Use `references/`
Put content in `references/` when it is:
- Only needed for edge cases or advanced usage
- Too long to read every time (> ~100 lines)
- Reference material (API specs, format docs, examples)
Use progressive disclosure: the agent reads `SKILL.md` first, then loads a specific reference file only when the task requires it.
```markdown
## Advanced Export Options
See [references/export-options.md](references/export-options.md) for the full list.
```
### When to Inline in `SKILL.md`
Keep content in `SKILL.md` when it is:
- Needed for every run of the skill
- Short enough not to slow down context injection (< ~150 lines total)
- Core to the skill's main workflow
---
## Naming Conventions
| Item | Convention | Example |
|---|---|---|
| Skill directory name | `kebab-case` | `export-to-pptx` |
| `name` field in frontmatter | `kebab-case`, matches dir name | `export-to-pptx` |
| Script filenames | `snake_case.py` or `snake_case.sh` | `build_slide.py` |
| Reference filenames | `kebab-case.md` | `advanced-options.md` |
Avoid spaces and uppercase in skill directory names — the SDK uses the directory name as the skill identifier.
---
## Writing Effective SKILL.md Instructions
### Open With a Role Statement
Tell the agent who it is in this skill context:
```markdown
# Export to PowerPoint
You are a presentation builder. Your job is to convert the user's content into a well-structured PPTX file using the scripts in this skill directory.
```
### Use Imperative Steps
Write instructions as numbered steps, not prose:
```markdown
1. Ask the user for the outline if not provided.
2. Run `python3 {scripts_dir}/build_slide.py --title "..." --output "{cwd}/output.pptx"`
3. Confirm success by checking the file exists.
4. Provide the user with the download path.
```
### Handle Errors Explicitly
Tell the agent what to do when things go wrong:
```markdown
If the script exits with a non-zero code, show the user the stderr output and ask how to proceed.
```
### End With a Closing Instruction
```markdown
After completing the task, summarize what was created and remind the user where to find the file.
```
---
## Skill Scope
Each skill should do **one thing well**. Signs a skill is too broad:
- The description has more than 45 "Use when:" entries covering unrelated domains
- The SKILL.md is > 300 lines
- You've added more than 3 reference files
When a skill grows too large, split it: one parent skill for routing + separate child skills per major function.
---
## Managing the `shared/` Directory
The `shared/` directory is **bidirectionally synced** with the OpenWebUI database:
- Skills created via the OpenWebUI UI are automatically imported into `shared/`
- Skills created by the agent in `shared/` are exported back to OpenWebUI at session start
### Safe operations
| Operation | Method |
|---|---|
| Install from URL | `python3 {scripts_dir}/install_skill.py --url <url> --dest {shared_dir}` |
| Create new skill | `mkdir -p {shared_dir}/<name>/ && create SKILL.md` |
| Edit skill | Read → modify → write `SKILL.md` |
| Delete skill | `rm -rf {shared_dir}/<name>/` (does NOT delete from OpenWebUI UI — do that separately) |
| List skills | `python3 {scripts_dir}/list_skills.py --path {shared_dir}` |
### The `.owui_id` file
Every skill synced with OpenWebUI has a `.owui_id` file containing the database UUID. **Never edit or delete this file** — it is the link between the filesystem and OpenWebUI DB. If deleted, the skill will be treated as new on next sync and may create a duplicate.
---
## Session Lifecycle Awareness
Skills are loaded **once at session start**. Changes made during a session take effect in the **next session**.
| When | What happens |
|---|---|
| Session starts | SDK daemon reads all `SKILL.md` files; `_sync_openwebui_skills` runs bidirectional DB↔file sync |
| During a session | New/edited/deleted skill files exist on disk but are NOT yet loaded by the daemon |
| After user starts new session | New skills become available; edited descriptions take effect |
**Always tell the user** after any create/edit/delete: "This change will take effect when you start a new session."
---
## Anti-Patterns to Avoid
| Anti-pattern | Why it's bad | Fix |
|---|---|---|
| Running `<skill-name>` as a bash command | Skills are not executables | Read the SKILL.md instructions and act with standard tools |
| Editing `.owui_id` | Breaks DB sync | Never touch it |
| Storing per-session state in `SKILL.md` | SKILL.md is static instructions, not a state file | Use separate workspace files for session state |
| Ultra-broad skill descriptions | Causes false positives on every message | Narrow to specific intent with "Use when:" |
| Putting all logic in one 500-line SKILL.md | Slow context injection, hard to maintain | Split into SKILL.md + `references/*.md` |
| Creating skills in `/tmp` | Not persisted, not found by SDK | Always create in `{shared_dir}/` |
---
## Quick Checklist for a New Skill
- [ ] Directory name is `kebab-case` and matches the `name` field
- [ ] `description` starts with a verb and has "Use when:" examples
- [ ] SKILL.md opens with a role statement for the agent
- [ ] Instructions use imperative numbered steps
- [ ] Long reference content moved to `references/`
- [ ] Scripts placed in `scripts/`
- [ ] Confirmed: skill does NOT overlap in description with other loaded skills
- [ ] User informed: "new skill takes effect next session"