Class: Insika::SkillCatalog
- Inherits:
-
Object
- Object
- Insika::SkillCatalog
- Defined in:
- lib/insika/skill_catalog.rb
Overview
OpenClaw / AgentSkills convention: each skill is a directory with a SKILL.md (YAML frontmatter + markdown body). Progressive disclosure: level 1 = name+description in the system prompt; level 2 = body loaded on demand by the load_skill tool.
Consumed by the Executor (skill_catalog:) and by stage 3 (effective/format_for_prompt).
Defined Under Namespace
Classes: Skill
Instance Method Summary collapse
- #all ⇒ Object
-
#effective(skills_policy) ⇒ Object
Per-agent allowlist: nil -> all | [] -> none | [names] -> subset.
- #find(name) ⇒ Object
-
#format_for_prompt(skills = all) ⇒ Object
Level 1: compact list injected into the system prompt.
-
#initialize(roots, store: nil) ⇒ SkillCatalog
constructor
roots ordered by PRECEDENCE (highest first): workspace, managed, bundled.
-
#reload ⇒ Object
Reloads from disk + Store and SWAPS the index atomically: an authored/edited skill takes effect without a restart.
Constructor Details
#initialize(roots, store: nil) ⇒ SkillCatalog
roots ordered by PRECEDENCE (highest first): workspace, managed, bundled. Same name in more than one root: the first wins.
store (optional): a SkillStore with the skills AUTHORED in the Studio. They overlay the on-disk ones (seed) — the Store wins, it is the source of truth. Nil = disk-only behavior, zero regression.
22 23 24 25 26 |
# File 'lib/insika/skill_catalog.rb', line 22 def initialize(roots, store: nil) @roots = Array(roots) @store = store @skills = load_all end |
Instance Method Details
#all ⇒ Object
28 29 30 |
# File 'lib/insika/skill_catalog.rb', line 28 def all @skills.values end |
#effective(skills_policy) ⇒ Object
Per-agent allowlist: nil -> all | [] -> none | [names] -> subset.
45 46 47 |
# File 'lib/insika/skill_catalog.rb', line 45 def effective(skills_policy) Allowlist.filter(all, skills_policy) { |s| s.name } end |
#find(name) ⇒ Object
32 33 34 |
# File 'lib/insika/skill_catalog.rb', line 32 def find(name) @skills[name.to_s] end |
#format_for_prompt(skills = all) ⇒ Object
Level 1: compact list injected into the system prompt. Metadata only. Receives the set already filtered by the agent.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/insika/skill_catalog.rb', line 51 def format_for_prompt(skills = all) return "" if skills.empty? entries = skills.map do |s| %( <skill name="#{s.name}">#{s.description}</skill>) end.join("\n") <<~PROMPT.strip <available_skills> #{entries} </available_skills> Before acting on a task that matches a skill above, call the `load_skill` tool with its name to load the complete instructions. PROMPT end |
#reload ⇒ Object
Reloads from disk + Store and SWAPS the index atomically: an authored/edited skill takes effect without a restart. A turn in progress captured @skills at dispatch, so it does not see the swap mid-flight.
39 40 41 42 |
# File 'lib/insika/skill_catalog.rb', line 39 def reload @skills = load_all self end |