Class: Riffer::Skills::Context
- Inherits:
-
Object
- Object
- Riffer::Skills::Context
- Defined in:
- lib/riffer/skills/context.rb
Overview
Skills context for an agent generation cycle — coordinates discovery, activation, and prompt rendering, caching skill bodies to avoid redundant backend reads. Exposed to tools via context.skills.
Instance Attribute Summary collapse
-
#adapter ⇒ Object
readonly
The skill adapter used for this context.
-
#on_activate ⇒ Object
Optional callback invoked when a skill is first activated.
-
#skills ⇒ Object
readonly
Skill catalog indexed by name.
Instance Method Summary collapse
-
#activatable? ⇒ Boolean
Returns whether any skill is available for the model to activate.
-
#activate(name) ⇒ Object
Activates a skill by name.
-
#activated?(name) ⇒ Boolean
Returns whether a skill has been activated.
-
#activation_prompt(name) ⇒ Object
Activates a skill and returns its body wrapped for injection as a user message.
-
#deactivate(name) ⇒ Object
Clears a skill’s activation so the next activation is treated as the first.
-
#initialize(backend:, skills:, adapter:) ⇒ Context
constructor
– : (backend: Riffer::Skills::Backend, skills: Hash[String, Riffer::Skills::Frontmatter], adapter: Riffer::Skills::Adapter) -> void.
-
#model_invocable?(name) ⇒ Boolean
Returns whether a skill exists and may be activated by the model.
-
#preactivate(name) ⇒ Object
Activates a skill whose body renders in the system prompt rather than the conversation.
-
#read(name) ⇒ Object
Returns a skill’s body without recording an activation.
-
#system_prompt ⇒ Object
Returns the complete skills section for the system prompt — the catalog plus any pre-activated skill bodies.
Constructor Details
#initialize(backend:, skills:, adapter:) ⇒ Context
– : (backend: Riffer::Skills::Backend, skills: Hash[String, Riffer::Skills::Frontmatter], adapter: Riffer::Skills::Adapter) -> void
24 25 26 27 28 29 30 31 |
# File 'lib/riffer/skills/context.rb', line 24 def initialize(backend:, skills:, adapter:) @backend = backend @skills = skills @adapter = adapter @bodies = {} #: Hash[String, String] @activated = [] #: Array[String] @preactivated = [] #: Array[String] end |
Instance Attribute Details
#adapter ⇒ Object (readonly)
The skill adapter used for this context.
17 18 19 |
# File 'lib/riffer/skills/context.rb', line 17 def adapter @adapter end |
#on_activate ⇒ Object
Optional callback invoked when a skill is first activated.
20 21 22 |
# File 'lib/riffer/skills/context.rb', line 20 def on_activate @on_activate end |
#skills ⇒ Object (readonly)
Skill catalog indexed by name.
14 15 16 |
# File 'lib/riffer/skills/context.rb', line 14 def skills @skills end |
Instance Method Details
#activatable? ⇒ Boolean
Returns whether any skill is available for the model to activate. – : () -> bool
114 115 116 |
# File 'lib/riffer/skills/context.rb', line 114 def activatable? available_skills.any? end |
#activate(name) ⇒ Object
Activates a skill by name. Returns the cached body on re-activation.
Raises Riffer::ArgumentError if the skill is not in the catalog.
– : (String) -> String
50 51 52 53 54 55 56 57 |
# File 'lib/riffer/skills/context.rb', line 50 def activate(name) body = read(name) unless @activated.include?(name) @activated << name @on_activate&.call(name) end body end |
#activated?(name) ⇒ Boolean
Returns whether a skill has been activated.
– : (String) -> bool
99 100 101 |
# File 'lib/riffer/skills/context.rb', line 99 def activated?(name) @activated.include?(name) end |
#activation_prompt(name) ⇒ Object
Activates a skill and returns its body wrapped for injection as a user message.
Raises Riffer::ArgumentError if the skill is not in the catalog.
– : (String) -> String
66 67 68 69 |
# File 'lib/riffer/skills/context.rb', line 66 def activation_prompt(name) body = activate(name) @adapter.render_activation(skills.fetch(name), body) end |
#deactivate(name) ⇒ Object
Clears a skill’s activation so the next activation is treated as the first.
Raises Riffer::ArgumentError if the skill is not in the catalog.
– : (String) -> void
89 90 91 92 93 |
# File 'lib/riffer/skills/context.rb', line 89 def deactivate(name) raise Riffer::ArgumentError, "Unknown skill: '#{name}'" unless skills.key?(name) @activated.delete(name) nil end |
#model_invocable?(name) ⇒ Boolean
Returns whether a skill exists and may be activated by the model. – : (String) -> bool
106 107 108 109 |
# File 'lib/riffer/skills/context.rb', line 106 def model_invocable?(name) skill = skills[name] !skill.nil? && !skill.disable_model_invocation end |
#preactivate(name) ⇒ Object
Activates a skill whose body renders in the system prompt rather than the conversation.
Raises Riffer::ArgumentError if the skill is not in the catalog.
– : (String) -> void
78 79 80 81 |
# File 'lib/riffer/skills/context.rb', line 78 def preactivate(name) activate(name) @preactivated << name unless @preactivated.include?(name) end |
#read(name) ⇒ Object
Returns a skill’s body without recording an activation.
Raises Riffer::ArgumentError if the skill is not in the catalog.
– : (String) -> String
39 40 41 42 |
# File 'lib/riffer/skills/context.rb', line 39 def read(name) raise Riffer::ArgumentError, "Unknown skill: '#{name}'" unless skills.key?(name) @bodies[name] ||= @backend.read_skill(name) end |
#system_prompt ⇒ Object
Returns the complete skills section for the system prompt — the catalog plus any pre-activated skill bodies. – : () -> String
122 123 124 125 126 127 128 |
# File 'lib/riffer/skills/context.rb', line 122 def system_prompt available = available_skills parts = [] #: Array[String] parts << @adapter.render_catalog(available) unless available.empty? @preactivated.each { |name| parts << @adapter.render_activation(skills.fetch(name), @bodies.fetch(name)) } parts.join("\n\n") end |