Class: Riffer::Skills::Context

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

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

#adapterObject (readonly)

The skill adapter used for this context.



17
18
19
# File 'lib/riffer/skills/context.rb', line 17

def adapter
  @adapter
end

#on_activateObject

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

#skillsObject (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

Returns:

  • (Boolean)


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

Returns:

  • (Boolean)


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

Returns:

  • (Boolean)


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_promptObject

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