Documentation
¶
Overview ¶
Package skills provides skill loading, matching, and lifecycle management. Skills are activatable behaviors that combine prompt injection, tool preferences, trigger conditions, and optional persistence across turns.
Index ¶
- func ComputeSkillBudget(maxContextTokens, budgetPercent int) int
- func EstimateTokens(s string) int
- func FormatSkillHeader() string
- func FormatSkillsForInjection(skills []*ActiveSkill, maxTokens int) (string, []string)
- func SkillToYAML(s *Skill) ([]byte, error)
- type ActiveSkill
- type HotReloadConfig
- type HotReloader
- type Library
- func (l *Library) FindByKeywords(msg string) []*ScoredSkill
- func (l *Library) FindBySlashCommand(cmd string) (*Skill, bool)
- func (l *Library) InvalidateCache()
- func (l *Library) List() []*Skill
- func (l *Library) ListAll() []SkillSummary
- func (l *Library) ListByDomain(domain string) []*Skill
- func (l *Library) Load(name string) (*Skill, error)
- func (l *Library) Register(skill *Skill)
- func (l *Library) RemoveFromCache(name string)
- func (l *Library) Search(query string) []*ScoredSkill
- func (l *Library) WriteSkill(skill *Skill) error
- type LibraryOption
- type MatchResult
- type Orchestrator
- func (o *Orchestrator) ActivateSkill(sessionID string, skill *Skill, triggerType, triggerValue string, ...) *ActiveSkill
- func (o *Orchestrator) CleanupSession(sessionID string)
- func (o *Orchestrator) DeactivateSkill(sessionID, skillName string)
- func (o *Orchestrator) FormatActiveSkillsForLLM(sessionID string, maxTokens int) string
- func (o *Orchestrator) GetActiveSkills(sessionID string) []*ActiveSkill
- func (o *Orchestrator) GetLibrary() *Library
- func (o *Orchestrator) MatchSkills(sessionID, userMsg string, config *SkillsConfig) ([]*MatchResult, error)
- type OrchestratorOption
- type ScoredSkill
- type Skill
- type SkillActivationMode
- type SkillExample
- type SkillExampleYAML
- type SkillLibraryMetadataYAML
- type SkillLibraryYAML
- type SkillMetadataYAML
- type SkillPrompt
- type SkillPromptYAML
- type SkillSummary
- type SkillToolConfig
- type SkillToolsYAML
- type SkillTrigger
- type SkillTriggerYAML
- type SkillUpdateCallback
- type SkillYAML
- type SkillsConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ComputeSkillBudget ¶
ComputeSkillBudget calculates the token budget for skills given the model's max context tokens and the configured budget percentage. Returns the total budget for skills+patterns combined.
func EstimateTokens ¶
EstimateTokens estimates the token count for a string. Uses the approximation: 1 token ~ 4 characters.
func FormatSkillHeader ¶
func FormatSkillHeader() string
FormatSkillHeader returns the header for the skills injection block.
func FormatSkillsForInjection ¶
func FormatSkillsForInjection(skills []*ActiveSkill, maxTokens int) (string, []string)
FormatSkillsForInjection formats multiple skills for LLM system message injection. It respects the token budget, including skills in priority order. Returns the formatted string and the list of skill names that were included.
func SkillToYAML ¶
SkillToYAML converts a Skill Go struct to YAML bytes. This is used by the MCP create_skill tool to serialize skills.
Types ¶
type ActiveSkill ¶
type ActiveSkill struct {
Skill *Skill `json:"skill"`
TriggerType string `json:"trigger_type"`
TriggerValue string `json:"trigger_value"`
Confidence float64 `json:"confidence"`
ActivatedAt time.Time `json:"activated_at"`
SessionID string `json:"session_id"`
AgentID string `json:"agent_id"`
}
ActiveSkill tracks an activated skill within a session.
type HotReloadConfig ¶
type HotReloadConfig struct {
Enabled bool // Enable hot-reload watching
DebounceMs int // Debounce delay in milliseconds (default: 500ms)
Logger *zap.Logger // Logger for reload events
OnUpdate SkillUpdateCallback // Callback for skill updates (optional)
}
HotReloadConfig configures hot-reload behavior for the skill library.
type HotReloader ¶
type HotReloader struct {
// contains filtered or unexported fields
}
HotReloader watches skill YAML files for changes and updates the library cache.
func NewHotReloader ¶
func NewHotReloader(library *Library, config HotReloadConfig, tracer observability.Tracer) (*HotReloader, error)
NewHotReloader creates a new hot-reloader for the skill library. Returns an error if the library has no filesystem search paths configured.
func (*HotReloader) Start ¶
func (hr *HotReloader) Start(ctx context.Context) error
Start begins watching skill directories for file changes. It watches all configured search paths on the library.
func (*HotReloader) Stop ¶
func (hr *HotReloader) Stop() error
Stop stops the hot-reload watcher. It is safe to call multiple times.
type Library ¶
type Library struct {
// contains filtered or unexported fields
}
Library manages skill discovery, loading, caching, and search. It supports three tiers of skill sources in order of precedence:
- Configured search paths (from agent config skills_dir)
- $LOOM_SKILLS_DIR env var (default $HOME/.loom/skills/)
- Embedded examples (lowest precedence, read-only)
Thread safety: All public methods are safe for concurrent use.
func NewLibrary ¶
func NewLibrary(opts ...LibraryOption) *Library
NewLibrary creates a skill library with the given options. If no search paths are provided, it defaults to $LOOM_SKILLS_DIR (falling back to $HOME/.loom/skills/).
func (*Library) FindByKeywords ¶
func (l *Library) FindByKeywords(msg string) []*ScoredSkill
FindByKeywords matches a user message against each skill's trigger keywords. Returns scored results sorted by descending relevance.
func (*Library) FindBySlashCommand ¶
FindBySlashCommand searches for a skill matching the given slash command. Returns the matching skill and true if found, nil and false otherwise.
func (*Library) InvalidateCache ¶
func (l *Library) InvalidateCache()
InvalidateCache clears the skill cache and index. The next call to Load or ListAll will re-read from disk/embedded sources.
func (*Library) List ¶
recordLoadMetric records a tracing span attribute and metric for a Load call. List returns all skills in the library cache. If the cache is empty, it triggers indexing first.
func (*Library) ListAll ¶
func (l *Library) ListAll() []SkillSummary
ListAll returns summaries for all available skills. The result is cached; call InvalidateCache to force re-indexing. Skills from filesystem paths take precedence over embedded skills with the same name.
func (*Library) ListByDomain ¶
ListByDomain returns all skills matching the given domain.
func (*Library) Load ¶
Load reads a skill by name. It checks three tiers in order: cache, filesystem search paths, embedded FS. Returns an error if the skill is not found in any source.
func (*Library) Register ¶
Register adds a skill directly to the in-memory cache. This is useful for programmatically created skills that don't come from YAML files.
func (*Library) RemoveFromCache ¶
RemoveFromCache removes a single skill from the cache by name.
func (*Library) Search ¶
func (l *Library) Search(query string) []*ScoredSkill
Search performs free-text keyword matching across skill name, title, and description. Returns scored results sorted by descending relevance.
func (*Library) WriteSkill ¶
WriteSkill writes a skill as YAML to the primary (first writable) search path. Uses SkillToYAML from loader.go for serialization.
type LibraryOption ¶
type LibraryOption func(*Library)
LibraryOption configures a Library during construction.
func WithEmbeddedFS ¶
func WithEmbeddedFS(efs *embed.FS) LibraryOption
WithEmbeddedFS sets an embedded filesystem as the lowest-precedence skill source.
func WithSearchPaths ¶
func WithSearchPaths(paths ...string) LibraryOption
WithSearchPaths adds filesystem directories to search for skill YAML files. Paths are searched in the order provided, with earlier paths taking precedence.
func WithTracer ¶
func WithTracer(t observability.Tracer) LibraryOption
WithTracer sets the observability tracer for the library.
type MatchResult ¶
type MatchResult struct {
Skill *Skill `json:"skill"`
Confidence float64 `json:"confidence"`
TriggerType string `json:"trigger_type"`
TriggerValue string `json:"trigger_value"`
}
MatchResult represents the result of matching a skill against user input.
type Orchestrator ¶
type Orchestrator struct {
// contains filtered or unexported fields
}
Orchestrator is the activation engine for skills. It evaluates user messages, matches them to skills via slash commands, keywords, or always-on rules, and manages active skill lifecycles within sessions.
func NewOrchestrator ¶
func NewOrchestrator(library *Library, opts ...OrchestratorOption) *Orchestrator
NewOrchestrator creates a new skill orchestrator backed by the given library.
func (*Orchestrator) ActivateSkill ¶
func (o *Orchestrator) ActivateSkill(sessionID string, skill *Skill, triggerType, triggerValue string, confidence float64) *ActiveSkill
ActivateSkill activates a skill for a session. If the session already has MaxConcurrentSkills active, the lowest-confidence skill is evicted.
func (*Orchestrator) CleanupSession ¶
func (o *Orchestrator) CleanupSession(sessionID string)
CleanupSession removes all state for a session.
func (*Orchestrator) DeactivateSkill ¶
func (o *Orchestrator) DeactivateSkill(sessionID, skillName string)
DeactivateSkill removes a skill from a session.
func (*Orchestrator) FormatActiveSkillsForLLM ¶
func (o *Orchestrator) FormatActiveSkillsForLLM(sessionID string, maxTokens int) string
FormatActiveSkillsForLLM combines all active skill prompts within the given token budget. Skills are included in FIFO order (activation time). If a skill's formatted prompt exceeds the remaining budget it is skipped. Token estimation: 1 token ~ 4 characters.
func (*Orchestrator) GetActiveSkills ¶
func (o *Orchestrator) GetActiveSkills(sessionID string) []*ActiveSkill
GetActiveSkills returns all active skills for a session.
func (*Orchestrator) GetLibrary ¶
func (o *Orchestrator) GetLibrary() *Library
GetLibrary returns the underlying skill library.
func (*Orchestrator) MatchSkills ¶
func (o *Orchestrator) MatchSkills(sessionID, userMsg string, config *SkillsConfig) ([]*MatchResult, error)
MatchSkills evaluates the user message and returns matching skills. It checks slash commands first, then auto-detection for HYBRID/AUTO skills, and finally ALWAYS skills. Results are filtered by config and sorted by confidence.
type OrchestratorOption ¶
type OrchestratorOption func(*Orchestrator)
OrchestratorOption configures an Orchestrator during construction.
func WithOrchestratorTracer ¶
func WithOrchestratorTracer(t observability.Tracer) OrchestratorOption
WithOrchestratorTracer sets the observability tracer for the orchestrator.
type ScoredSkill ¶
ScoredSkill represents a skill with a relevance score for search/ranking.
type Skill ¶
type Skill struct {
// Metadata
Name string `json:"name"`
Title string `json:"title"`
Description string `json:"description"`
Version string `json:"version"`
Domain string `json:"domain"`
Labels map[string]string `json:"labels,omitempty"`
Author string `json:"author,omitempty"`
// Trigger configuration
Trigger SkillTrigger `json:"trigger"`
// Prompt instructions
Prompt SkillPrompt `json:"prompt"`
// Tool requirements and preferences
Tools SkillToolConfig `json:"tools"`
// Co-inject these patterns when skill is active
PatternRefs []string `json:"pattern_refs,omitempty"`
// Compose with sub-skills (max depth: 2)
SkillRefs []string `json:"skill_refs,omitempty"`
// Token budget for this skill's prompt (0 = use default 1500)
MaxPromptTokens int32 `json:"max_prompt_tokens,omitempty"`
// Persist across turns once activated
Sticky bool `json:"sticky,omitempty"`
// Target backend (empty = agnostic)
Backend string `json:"backend,omitempty"`
}
Skill represents an activatable behavior that combines prompt injection, tool preferences, trigger conditions, and optional persistence across turns.
func LoadSkillLibrary ¶
LoadSkillLibrary loads a skill library YAML file containing multiple skills.
func (*Skill) FormatForLLM ¶
FormatForLLM formats the skill for LLM injection. Returns a concise, actionable representation optimized for token efficiency. Target: <2000 tokens per skill.
func (*Skill) Summary ¶
func (s *Skill) Summary() SkillSummary
Summary returns a lightweight SkillSummary from this Skill.
type SkillActivationMode ¶
type SkillActivationMode string
SkillActivationMode controls how a skill can be triggered.
const ( // ActivationManual requires explicit slash command or API call. ActivationManual SkillActivationMode = "MANUAL" // ActivationAuto enables auto-detection from user message content. ActivationAuto SkillActivationMode = "AUTO" // ActivationHybrid supports both manual and auto-detection. ActivationHybrid SkillActivationMode = "HYBRID" // ActivationAlways keeps the skill active whenever configured. ActivationAlways SkillActivationMode = "ALWAYS" )
type SkillExample ¶
type SkillExample struct {
UserInput string `json:"user_input"`
ExpectedOutput string `json:"expected_output"`
Explanation string `json:"explanation,omitempty"`
}
SkillExample provides a few-shot example for the skill.
type SkillExampleYAML ¶
type SkillExampleYAML struct {
UserInput string `yaml:"user_input"`
ExpectedOutput string `yaml:"expected_output"`
Explanation string `yaml:"explanation"`
}
SkillExampleYAML holds a single example from YAML.
type SkillLibraryMetadataYAML ¶
type SkillLibraryMetadataYAML struct {
Name string `yaml:"name"`
Version string `yaml:"version"`
Description string `yaml:"description"`
Labels map[string]string `yaml:"labels"`
}
SkillLibraryMetadataYAML holds library-level metadata from YAML.
type SkillLibraryYAML ¶
type SkillLibraryYAML struct {
APIVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
Metadata SkillLibraryMetadataYAML `yaml:"metadata"`
Skills []SkillYAML `yaml:"skills"`
}
SkillLibraryYAML represents the YAML structure for a skill library file.
type SkillMetadataYAML ¶
type SkillMetadataYAML struct {
Name string `yaml:"name"`
Title string `yaml:"title"`
Description string `yaml:"description"`
Version string `yaml:"version"`
Domain string `yaml:"domain"`
Author string `yaml:"author"`
Labels map[string]string `yaml:"labels"`
}
SkillMetadataYAML holds skill metadata from YAML.
type SkillPrompt ¶
type SkillPrompt struct {
// Main prompt instructions (supports {{.var}} interpolation)
Instructions string `json:"instructions"`
// Rules and constraints to enforce
Constraints []string `json:"constraints,omitempty"`
// Expected output structure description
OutputFormat string `json:"output_format,omitempty"`
// Few-shot examples
Examples []SkillExample `json:"examples,omitempty"`
}
SkillPrompt defines the instructions injected when a skill is active.
type SkillPromptYAML ¶
type SkillPromptYAML struct {
Instructions string `yaml:"instructions"`
Constraints []string `yaml:"constraints"`
OutputFormat string `yaml:"output_format"`
Examples []SkillExampleYAML `yaml:"examples"`
}
SkillPromptYAML holds prompt configuration from YAML.
type SkillSummary ¶
type SkillSummary struct {
Name string `json:"name"`
Title string `json:"title"`
Description string `json:"description"`
Domain string `json:"domain"`
Version string `json:"version"`
Labels map[string]string `json:"labels,omitempty"`
Commands []string `json:"commands,omitempty"`
}
SkillSummary provides lightweight metadata for catalog listing.
type SkillToolConfig ¶
type SkillToolConfig struct {
// Ensure these tools are registered when skill is active
RequiredTools []string `json:"required_tools,omitempty"`
// Suggested tool execution ordering
PreferredOrder []string `json:"preferred_order,omitempty"`
// Tools to hide when skill is active
ExcludedTools []string `json:"excluded_tools,omitempty"`
// MCP servers to enable when skill is active
MCPServers []string `json:"mcp_servers,omitempty"`
}
SkillToolConfig defines tool requirements and preferences for a skill.
type SkillToolsYAML ¶
type SkillToolsYAML struct {
RequiredTools []string `yaml:"required_tools"`
PreferredOrder []string `yaml:"preferred_order"`
ExcludedTools []string `yaml:"excluded_tools"`
MCPServers []string `yaml:"mcp_servers"`
}
SkillToolsYAML holds tool configuration from YAML.
type SkillTrigger ¶
type SkillTrigger struct {
// Slash commands that activate this skill: ["/review", "/code-review"]
SlashCommands []string `json:"slash_commands,omitempty"`
// Keywords for auto-detection from user messages
Keywords []string `json:"keywords,omitempty"`
// Maps to patterns.IntentCategory for intent-based activation
IntentCategories []string `json:"intent_categories,omitempty"`
// How this skill can be activated
Mode SkillActivationMode `json:"mode,omitempty"`
// Minimum confidence for AUTO/HYBRID activation (default: 0.7)
MinConfidence float64 `json:"min_confidence,omitempty"`
}
SkillTrigger defines how a skill gets activated.
type SkillTriggerYAML ¶
type SkillTriggerYAML struct {
SlashCommands []string `yaml:"slash_commands"`
Keywords []string `yaml:"keywords"`
IntentCategories []string `yaml:"intent_categories"`
Mode string `yaml:"mode"`
MinConfidence float64 `yaml:"min_confidence"`
}
SkillTriggerYAML holds trigger configuration from YAML.
type SkillUpdateCallback ¶
SkillUpdateCallback is called when a skill file is created, modified, or deleted. Parameters: eventType (create/modify/delete/validation_failed), skillName, error (if validation failed).
type SkillYAML ¶
type SkillYAML struct {
APIVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
Metadata SkillMetadataYAML `yaml:"metadata"`
Trigger SkillTriggerYAML `yaml:"trigger"`
Prompt SkillPromptYAML `yaml:"prompt"`
Tools SkillToolsYAML `yaml:"tools"`
PatternRefs []string `yaml:"pattern_refs"`
SkillRefs []string `yaml:"skill_refs"`
MaxPromptTokens int32 `yaml:"max_prompt_tokens"`
Sticky bool `yaml:"sticky"`
Backend string `yaml:"backend"`
}
SkillYAML represents the YAML structure for a single skill file.
type SkillsConfig ¶
type SkillsConfig struct {
Enabled bool
EnabledSkills []string
DisabledSkills []string
MinAutoConfidence float64
MaxConcurrentSkills int
SkillsDir string
ContextBudgetPercent int
}
SkillsConfig controls skill matching behavior for a session.
func DefaultSkillsConfig ¶
func DefaultSkillsConfig() *SkillsConfig
DefaultSkillsConfig returns a SkillsConfig with sensible defaults.