Skip to main content

AI Agent Skills

DEVELOPER Advanced

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 domains and skill_ids on chat requests select which skills apply.
  • The backend injects a metadata table (id, name, description, domain) and registers the skill_loader toolset so the model can call get_skill_content (exposed as skill_loader_get_skill_content) instead of loading every file into the first prompt.
  • Domain core is 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_path in config (ServerConfig in pkg/config/config.go), or file_upload_path + "/skills" when unset. Each skill uses a directory named by the skill resource id.
  • Allowed file extensions: .md and .txt only, 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/preset cannot have metadata or files edited in UI; Preview and Clone still work.
  • File tree editor for user skills; Markdown preview.
PermissionPurpose
system:skills:viewList, get, preview, domains
system:skills:createCreate, upload
system:skills:updateMetadata and status
system:skills:deleteDelete
system:skills:edit_filesFile 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; requires X-Scope-OrgID when 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_content succeeds 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: SkillChatBindingMode in pkg/service/toolset_service.go).
  • skillLoader.OnContentLoaded in StreamChat persists activated skill ids on the session; tool definitions can refresh between LLM iterations.
  • After auto-summarization, activated skills are cleared and get_skill_content results 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.


Need help? Ask in GitHub Discussions.