AI Agent Skills
Skills are reusable instruction packs for AI chat: metadata in the database and files on disk. This matches the behavior described in the framework usages guide for operators and extension authors.
What skills doβ
- Optional
domainsandskill_idson chat requests select which skills apply. - The backend injects a metadata table (id, name, description, domain) and registers the
skill_loadertoolset so the model can callget_skill_content(exposed asskill_loader_get_skill_content) instead of loading every file into the first prompt. - Domain
coreis always included when any skills are loaded; other domains must be registered in code (see below).
Storage and modelβ
- Table
t_skill(pkg/model/skill.go): name, description, category, domain, status (enabled/disabled), preset flags,preset_key, resource id, etc. - Files live under
skills_pathin config (ServerConfiginpkg/config/config.go), orfile_upload_path + "/skills"when unset. Each skill uses a directory named by the skill resource id. - Allowed file extensions:
.mdand.txtonly, with path validation (no..).
Main document: SKILL.md or SKILLS.md (both accepted on upload and create).
Example layout:
<skills_root>/
βββ <skill-resource-id>/
βββ SKILL.md
βββ REFERENCE.md
YAML frontmatterβ
Upload and create paths parse frontmatter for default name/description, for example:
---
name: My Skill
description: Instructions for the agent in this scenario.
---
# Markdown body
Implementation reference: pkg/service/skill_service.go (parseSkillFrontmatter, defaultSkillMDContent).
Console and permissionsβ
Under System Settings β Skills (see SkillSettings.tsx in the main repo):
- List, search, filter by domain; enable/disable for AI chat (
PUT /api/system/skills/:id/status) when permitted. - Preset skills from
pkg/presetcannot have metadata or files edited in UI; Preview and Clone still work. - File tree editor for user skills; Markdown preview.
| Permission | Purpose |
|---|---|
system:skills:view | List, get, preview, domains |
system:skills:create | Create, upload |
system:skills:update | Metadata and status |
system:skills:delete | Delete |
system:skills:edit_files | File tree CRUD |
HTTP APIsβ
Base path /api/system/skills (Swag: pkg/api/system/skill_controller.go). Regenerate clients with make clean-openapi clean-openapi2ts openapi2ts as in API best practices.
Notable routes:
- CRUD, upload, preview, file tree
/files/*, move path,/ai-tool-bindings(org-scoped; requiresX-Scope-OrgIDwhen linking tools).
AI integration and tool bindingβ
When system_enable_skill_tool_binding is enabled and a non-empty skill loader is used:
- Until
get_skill_contentsucceeds for at least one in-scope skill in the session, organization toolsets may be hidden so the model must load skills first (exact matrix in code:SkillChatBindingModeinpkg/service/toolset_service.go). skillLoader.OnContentLoadedinStreamChatpersists activated skill ids on the session; tool definitions can refresh between LLM iterations.- After auto-summarization, activated skills are cleared and
get_skill_contentresults are redacted in summarizer input so large bodies are not folded verbatim.
Preset skills and default bindings are synced on startup (Service.SyncPresetResources); see AI model integration for preset toolsets overview.
Registering domainsβ
Default domain list is core. Register more in init():
import "github.com/sven-victor/ez-console/pkg/service"
func init() {
service.RegisterSkillsDomain("document")
}
Registration is idempotent. Skills with domain = "document" are then eligible when the client sends that domain in the chat request.
Related topicsβ
- AI model integration β Models, toolsets, streaming, client tools
- System settings β Operator-facing configuration
- API best practices
Need help? Ask in GitHub Discussions.