riffer 0.24.2 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.agents/architecture.md +1 -1
- data/.bundle/config +4 -0
- data/.release-please-config.json +3 -1
- data/.release-please-manifest.json +1 -1
- data/.ruby-version +1 -1
- data/AGENTS.md +1 -1
- data/CHANGELOG.md +19 -0
- data/README.md +1 -1
- data/docs/10_CONFIGURATION.md +28 -0
- data/docs/13_SKILLS.md +32 -8
- data/lib/riffer/agent.rb +52 -22
- data/lib/riffer/config.rb +56 -0
- data/lib/riffer/providers/amazon_bedrock.rb +18 -0
- data/lib/riffer/providers/anthropic.rb +2 -2
- data/lib/riffer/providers/base.rb +7 -3
- data/lib/riffer/providers/mock.rb +15 -0
- data/lib/riffer/skills/adapter.rb +20 -15
- data/lib/riffer/skills/config.rb +18 -0
- data/lib/riffer/skills/context.rb +2 -1
- data/lib/riffer/skills/markdown_adapter.rb +1 -1
- data/lib/riffer/skills/xml_adapter.rb +1 -1
- data/lib/riffer/version.rb +1 -1
- data/sig/generated/riffer/agent.rbs +25 -0
- data/sig/generated/riffer/config.rbs +45 -0
- data/sig/generated/riffer/providers/amazon_bedrock.rbs +15 -0
- data/sig/generated/riffer/providers/anthropic.rbs +2 -2
- data/sig/generated/riffer/providers/base.rbs +7 -3
- data/sig/generated/riffer/providers/mock.rbs +12 -0
- data/sig/generated/riffer/skills/adapter.rbs +18 -13
- data/sig/generated/riffer/skills/config.rbs +13 -0
- data/sig/generated/riffer/skills/context.rbs +2 -1
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4097cc002e3ac3c06c0e354fddd33de5c5fb7b51ed53c6080478de972125b8b7
|
|
4
|
+
data.tar.gz: eed8cf5ed60830b206e00ef62640aa691aa9b32140c2ec5852b69d39fb775e5f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f6d511f5de22e4a04521ac1c12e26aa7f508a6b0c2649e124447995c64a4b3d66a9a6cace08869db7f66c129bb38aa1f169fde5c42e3a6b8612be07b81e320d7
|
|
7
|
+
data.tar.gz: 03c5075c171920a16245b73ab1925a4013f029d5aabe686fdd3a904886c8113837c11a8584f4b1243517c7935f1ae8216882101d63803c1ad25c209353a64612
|
data/.agents/architecture.md
CHANGED
|
@@ -40,7 +40,7 @@ Adapters for LLM APIs. The base class uses a template-method pattern — `genera
|
|
|
40
40
|
|
|
41
41
|
Providers are registered in `Riffer::Providers::Repository::REPO` with identifiers (e.g., `openai`, `amazon_bedrock`).
|
|
42
42
|
|
|
43
|
-
Each provider declares a preferred skill adapter via `self.skills_adapter
|
|
43
|
+
Each provider declares a preferred skill adapter via `self.skills_adapter(model = nil)`. Default is Markdown; Anthropic returns XML; Amazon Bedrock returns XML when the model identifier matches an Anthropic model (e.g. `anthropic.claude-…` or `us.anthropic.claude-…`); Mock returns XML when the model name contains `claude`. The agent passes the resolved model identifier so proxy providers (Bedrock, Mock) can pick the right adapter without per-agent overrides.
|
|
44
44
|
|
|
45
45
|
### Skills (`lib/riffer/skills/`)
|
|
46
46
|
|
data/.bundle/config
ADDED
data/.release-please-config.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"release-type": "ruby",
|
|
3
|
+
"bump-minor-pre-major": true,
|
|
3
4
|
"packages": {
|
|
4
5
|
".": {
|
|
5
6
|
"release-type": "ruby",
|
|
6
7
|
"package-name": "riffer",
|
|
7
|
-
"version-file": "lib/riffer/version.rb"
|
|
8
|
+
"version-file": "lib/riffer/version.rb",
|
|
9
|
+
"bump-minor-pre-major": true
|
|
8
10
|
}
|
|
9
11
|
}
|
|
10
12
|
}
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
4.0.3
|
data/AGENTS.md
CHANGED
|
@@ -4,7 +4,7 @@ Ruby gem framework for building AI-powered agents with LLM provider adapters.
|
|
|
4
4
|
|
|
5
5
|
## Quick Reference
|
|
6
6
|
|
|
7
|
-
- **Ruby**: 3.3.0+
|
|
7
|
+
- **Ruby**: 3.3.0+ (CI: 3.3, 3.4, 4.0)
|
|
8
8
|
- **Lint + Test**: `bundle exec rake`
|
|
9
9
|
- **Autoloading**: Zeitwerk (file paths must match module/class names)
|
|
10
10
|
- **Model format**: `provider/model` (e.g., `openai/gpt-4`)
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.26.0](https://github.com/janeapp/riffer/compare/riffer/v0.25.0...riffer/v0.26.0) (2026-04-29)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* model-aware skills adapter selection ([#232](https://github.com/janeapp/riffer/issues/232)) ([74a5323](https://github.com/janeapp/riffer/commit/74a5323945f3f6f30538d472400cc5fe27b588da))
|
|
14
|
+
|
|
15
|
+
## [0.25.0](https://github.com/janeapp/riffer/compare/riffer/v0.24.2...riffer/v0.25.0) (2026-04-29)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### ⚠ BREAKING CHANGES
|
|
19
|
+
|
|
20
|
+
* Removed Riffer::Skills::Adapter#activate_tool. Set the activation tool via Riffer.config.skills.default_activate_tool, or per-agent with `skills do; activate_tool MyTool; end`.
|
|
21
|
+
* Riffer::Skills::Adapter.new now requires skill_activate_tool:. The agent wires this up; only matters if you construct an adapter yourself. Custom adapters that override #initialize must call super.
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* class-level tool resolution; lift activation tool to global config ([#230](https://github.com/janeapp/riffer/issues/230)) ([936c4ba](https://github.com/janeapp/riffer/commit/936c4baa6beff4f2cd6c87bfe90be8c20a7f30e1))
|
|
26
|
+
|
|
8
27
|
## [0.24.2](https://github.com/janeapp/riffer/compare/riffer/v0.24.1...riffer/v0.24.2) (2026-04-23)
|
|
9
28
|
|
|
10
29
|
|
data/README.md
CHANGED
data/docs/10_CONFIGURATION.md
CHANGED
|
@@ -54,6 +54,34 @@ end
|
|
|
54
54
|
|
|
55
55
|
Per-agent configuration overrides this global default. See [Advanced Tool Configuration — Tool Runtime](07_TOOL_ADVANCED.md#tool-runtime-experimental) for details.
|
|
56
56
|
|
|
57
|
+
### Skills
|
|
58
|
+
|
|
59
|
+
Skills-related global configuration lives under `config.skills`.
|
|
60
|
+
|
|
61
|
+
#### Default activation tool
|
|
62
|
+
|
|
63
|
+
Override the tool the LLM calls to activate a skill. Defaults to `Riffer::Skills::ActivateTool`:
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
Riffer.configure do |config|
|
|
67
|
+
config.skills.default_activate_tool = MyCustomActivateTool
|
|
68
|
+
end
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Per-agent override is available inside the `skills` block via `activate_tool MyCustomActivateTool`. See [Skills — Custom Activation Tool](13_SKILLS.md#custom-activation-tool).
|
|
72
|
+
|
|
73
|
+
#### Default backend
|
|
74
|
+
|
|
75
|
+
Set an app-wide default skills backend. Used by any agent that declares a `skills` block without specifying its own `backend`:
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
Riffer.configure do |config|
|
|
79
|
+
config.skills.default_backend = Riffer::Skills::FilesystemBackend.new(".skills")
|
|
80
|
+
end
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Accepts a `Riffer::Skills::Backend` instance or a `Proc` that receives `context` and returns a backend. Defaults to `nil` — agents that don't set their own backend get no skills, matching pre-existing behavior. Per-agent backends override this default.
|
|
84
|
+
|
|
57
85
|
### Message ID Strategy
|
|
58
86
|
|
|
59
87
|
Opt in to stable identifiers on every message for logging, persistence, or replay:
|
data/docs/13_SKILLS.md
CHANGED
|
@@ -70,7 +70,7 @@ end
|
|
|
70
70
|
|
|
71
71
|
### Custom Adapter
|
|
72
72
|
|
|
73
|
-
The adapter controls how the skill catalog is rendered in the system prompt and which tool the LLM calls to activate a skill. The adapter is auto-selected by provider
|
|
73
|
+
The adapter controls how the skill catalog is rendered in the system prompt and which tool the LLM calls to activate a skill. The adapter is auto-selected by provider, with model-aware fallback for proxy providers — Markdown for most providers, XML for Anthropic, and XML for Anthropic models routed through Amazon Bedrock (e.g. `us.anthropic.claude-sonnet-4-6`). Override with:
|
|
74
74
|
|
|
75
75
|
```ruby
|
|
76
76
|
skills do
|
|
@@ -125,24 +125,48 @@ end
|
|
|
125
125
|
|
|
126
126
|
## Custom Adapters
|
|
127
127
|
|
|
128
|
-
Subclass `Riffer::Skills::Adapter` to customize how the skill catalog is rendered
|
|
128
|
+
Subclass `Riffer::Skills::Adapter` to customize how the skill catalog is rendered in the system prompt:
|
|
129
129
|
|
|
130
130
|
```ruby
|
|
131
131
|
class CustomAdapter < Riffer::Skills::Adapter
|
|
132
132
|
def render_catalog(skills)
|
|
133
133
|
# Return String (skill catalog for the system prompt)
|
|
134
|
-
# Use `
|
|
134
|
+
# Use `skill_activate_tool.name` to reference the activation tool the LLM should call
|
|
135
135
|
end
|
|
136
|
+
end
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The activation tool is set on the adapter at construction (`Riffer::Skills::Adapter.new(skill_activate_tool: ...)`) and exposed via the `skill_activate_tool` reader. The agent wires this up automatically — custom adapters that override `initialize` must call `super`.
|
|
140
|
+
|
|
141
|
+
The built-in adapters are `Riffer::Skills::MarkdownAdapter` (default) and `Riffer::Skills::XmlAdapter` (used by Anthropic).
|
|
136
142
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
143
|
+
## Custom Activation Tool
|
|
144
|
+
|
|
145
|
+
The activation tool is global. Set it once via `Riffer.config.skills.default_activate_tool` to apply across all agents, or override per-agent inside the `skills` block.
|
|
146
|
+
|
|
147
|
+
The recommended approach is to subclass `Riffer::Skills::ActivateTool` so the identifier, description, params, and timeout are inherited — you only override the behavior you need to change:
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
# Wrap the default behavior with telemetry
|
|
151
|
+
class InstrumentedActivateTool < Riffer::Skills::ActivateTool
|
|
152
|
+
def call(context:, name:)
|
|
153
|
+
Telemetry.measure("skill_activate", skill: name) { super }
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Global default
|
|
158
|
+
Riffer.config.skills.default_activate_tool = InstrumentedActivateTool
|
|
159
|
+
|
|
160
|
+
# Per-agent override
|
|
161
|
+
class MyAgent < Riffer::Agent
|
|
162
|
+
skills do
|
|
163
|
+
backend Riffer::Skills::FilesystemBackend.new(".skills")
|
|
164
|
+
activate_tool InstrumentedActivateTool
|
|
141
165
|
end
|
|
142
166
|
end
|
|
143
167
|
```
|
|
144
168
|
|
|
145
|
-
|
|
169
|
+
If you need a different parameter shape entirely, subclass `Riffer::Tool` directly and provide your own `identifier`, `description`, `params`, and `call`.
|
|
146
170
|
|
|
147
171
|
## Accessing Skills in Tools
|
|
148
172
|
|
data/lib/riffer/agent.rb
CHANGED
|
@@ -132,6 +132,46 @@ class Riffer::Agent
|
|
|
132
132
|
@tools_config = tools_or_lambda
|
|
133
133
|
end
|
|
134
134
|
|
|
135
|
+
# Returns the tool classes the LLM should see for this agent.
|
|
136
|
+
#
|
|
137
|
+
# Class-level companion to the instance #resolved_tools. Resolves the
|
|
138
|
+
# Proc form of +uses_tools+ and appends the skill activation tool when
|
|
139
|
+
# a +skills+ block is configured. Does not read the skills backend —
|
|
140
|
+
# the LLM-facing tool schema reflects class-level intent, not the
|
|
141
|
+
# runtime state of any backend.
|
|
142
|
+
#
|
|
143
|
+
# When +uses_tools+ is a Proc, +context+ is forwarded to it.
|
|
144
|
+
#
|
|
145
|
+
# The activation tool class is resolved from the agent's
|
|
146
|
+
# <tt>skills do; activate_tool ...; end</tt> override when set, otherwise
|
|
147
|
+
# from <tt>Riffer.config.skills.default_activate_tool</tt>.
|
|
148
|
+
#
|
|
149
|
+
# Raises Riffer::ArgumentError on tool name conflicts with the skill
|
|
150
|
+
# activation tool.
|
|
151
|
+
#
|
|
152
|
+
#--
|
|
153
|
+
#: (?context: Hash[Symbol, untyped]?) -> Array[singleton(Riffer::Tool)]
|
|
154
|
+
def self.resolved_tool_classes(context: nil)
|
|
155
|
+
base = resolve_uses_tools_config(context)
|
|
156
|
+
return base unless skills
|
|
157
|
+
|
|
158
|
+
skill_activate_tool_class = skills.activate_tool || Riffer.config.skills.default_activate_tool
|
|
159
|
+
if base.any? { |t| t.name == skill_activate_tool_class.name }
|
|
160
|
+
raise Riffer::ArgumentError, "Tool name conflict with skill tools: #{skill_activate_tool_class.name}"
|
|
161
|
+
end
|
|
162
|
+
base + [skill_activate_tool_class]
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
#--
|
|
166
|
+
#: (Hash[Symbol, untyped]?) -> Array[singleton(Riffer::Tool)]
|
|
167
|
+
def self.resolve_uses_tools_config(context)
|
|
168
|
+
config = uses_tools
|
|
169
|
+
return [] if config.nil?
|
|
170
|
+
return config unless config.is_a?(Proc)
|
|
171
|
+
config.arity.zero? ? config.call : config.call(context)
|
|
172
|
+
end
|
|
173
|
+
private_class_method :resolve_uses_tools_config
|
|
174
|
+
|
|
135
175
|
# Gets or sets the tool runtime for this agent.
|
|
136
176
|
#
|
|
137
177
|
# Accepts a Riffer::ToolRuntime subclass, a Riffer::ToolRuntime instance,
|
|
@@ -717,25 +757,7 @@ class Riffer::Agent
|
|
|
717
757
|
#--
|
|
718
758
|
#: () -> Array[singleton(Riffer::Tool)]
|
|
719
759
|
def resolved_tools
|
|
720
|
-
@resolved_tools ||=
|
|
721
|
-
config = self.class.uses_tools
|
|
722
|
-
|
|
723
|
-
tools = if config.nil?
|
|
724
|
-
[]
|
|
725
|
-
elsif config.is_a?(Proc)
|
|
726
|
-
(config.arity == 0) ? config.call : config.call(@context)
|
|
727
|
-
else
|
|
728
|
-
config
|
|
729
|
-
end
|
|
730
|
-
|
|
731
|
-
if @skills_state
|
|
732
|
-
activate_tool = @skills_state.adapter.activate_tool
|
|
733
|
-
raise Riffer::ArgumentError, "Tool name conflict with skill tools: #{activate_tool.name}" if tools.any? { |t| t.name == activate_tool.name }
|
|
734
|
-
tools + [activate_tool]
|
|
735
|
-
else
|
|
736
|
-
tools
|
|
737
|
-
end
|
|
738
|
-
end
|
|
760
|
+
@resolved_tools ||= self.class.resolved_tool_classes(context: @context)
|
|
739
761
|
end
|
|
740
762
|
|
|
741
763
|
#--
|
|
@@ -769,7 +791,7 @@ class Riffer::Agent
|
|
|
769
791
|
def resolve_skills(context = @context)
|
|
770
792
|
return nil unless self.class.skills
|
|
771
793
|
|
|
772
|
-
backend = self.class.skills.backend
|
|
794
|
+
backend = self.class.skills.backend || Riffer.config.skills.default_backend
|
|
773
795
|
return nil unless backend
|
|
774
796
|
|
|
775
797
|
backend = backend.is_a?(Proc) ? backend.call(context) : backend
|
|
@@ -777,9 +799,14 @@ class Riffer::Agent
|
|
|
777
799
|
return nil if skills_list.empty?
|
|
778
800
|
|
|
779
801
|
skills = skills_list.to_h { |s| [s.name, s] }
|
|
780
|
-
adapter_class = self.class.skills.adapter || provider_class.skills_adapter
|
|
802
|
+
adapter_class = self.class.skills.adapter || provider_class.skills_adapter(@model_name)
|
|
803
|
+
skill_activate_tool_class = self.class.skills.activate_tool || Riffer.config.skills.default_activate_tool
|
|
781
804
|
|
|
782
|
-
skills_context = Riffer::Skills::Context.new(
|
|
805
|
+
skills_context = Riffer::Skills::Context.new(
|
|
806
|
+
backend: backend,
|
|
807
|
+
skills: skills,
|
|
808
|
+
adapter: adapter_class.new(skill_activate_tool: skill_activate_tool_class)
|
|
809
|
+
)
|
|
783
810
|
ctx = (context || {}).merge(skills: skills_context)
|
|
784
811
|
|
|
785
812
|
activate = self.class.skills.activate
|
|
@@ -802,7 +829,10 @@ class Riffer::Agent
|
|
|
802
829
|
#--
|
|
803
830
|
#: () -> Riffer::Messages::Assistant?
|
|
804
831
|
def extract_final_response
|
|
832
|
+
# TODO: Replace with rfind when minimum Ruby is 4.0+
|
|
833
|
+
# rubocop:disable Style/ReverseFind
|
|
805
834
|
@messages.reverse.find { |msg| msg.is_a?(Riffer::Messages::Assistant) } #: Riffer::Messages::Assistant?
|
|
835
|
+
# rubocop:enable Style/ReverseFind
|
|
806
836
|
end
|
|
807
837
|
|
|
808
838
|
#--
|
data/lib/riffer/config.rb
CHANGED
|
@@ -22,6 +22,57 @@ class Riffer::Config
|
|
|
22
22
|
OpenAI = Struct.new(:api_key, keyword_init: true)
|
|
23
23
|
Evals = Struct.new(:judge_model, keyword_init: true)
|
|
24
24
|
|
|
25
|
+
# Skills-related global configuration.
|
|
26
|
+
#
|
|
27
|
+
# See <tt>Riffer.config.skills.default_activate_tool</tt> and
|
|
28
|
+
# <tt>Riffer.config.skills.default_backend</tt>.
|
|
29
|
+
class Skills
|
|
30
|
+
# Default skill activation tool class.
|
|
31
|
+
#
|
|
32
|
+
# The tool class the LLM calls to activate a skill. Defaults to
|
|
33
|
+
# <tt>Riffer::Skills::ActivateTool</tt>. Per-agent override is available
|
|
34
|
+
# via <tt>skills do; activate_tool ...; end</tt>.
|
|
35
|
+
attr_reader :default_activate_tool #: singleton(Riffer::Tool)
|
|
36
|
+
|
|
37
|
+
# Default skills backend.
|
|
38
|
+
#
|
|
39
|
+
# Used by agents that declare a +skills+ block without specifying a
|
|
40
|
+
# backend. Accepts a Riffer::Skills::Backend instance or a Proc.
|
|
41
|
+
# Defaults to +nil+ (no global default).
|
|
42
|
+
attr_reader :default_backend #: (Riffer::Skills::Backend | Proc)?
|
|
43
|
+
|
|
44
|
+
#--
|
|
45
|
+
#: () -> void
|
|
46
|
+
def initialize
|
|
47
|
+
@default_activate_tool = Riffer::Skills::ActivateTool
|
|
48
|
+
@default_backend = nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Sets the default skill activation tool class.
|
|
52
|
+
#
|
|
53
|
+
# Raises +Riffer::ArgumentError+ if the value is not a Riffer::Tool subclass.
|
|
54
|
+
#
|
|
55
|
+
#--
|
|
56
|
+
#: (singleton(Riffer::Tool)) -> void
|
|
57
|
+
def default_activate_tool=(value)
|
|
58
|
+
raise Riffer::ArgumentError, "default_activate_tool must be a Riffer::Tool subclass" unless value.is_a?(Class) && value < Riffer::Tool
|
|
59
|
+
@default_activate_tool = value
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Sets the default skills backend.
|
|
63
|
+
#
|
|
64
|
+
# Raises +Riffer::ArgumentError+ if the value is not a
|
|
65
|
+
# Riffer::Skills::Backend instance, a Proc, or +nil+.
|
|
66
|
+
#
|
|
67
|
+
#--
|
|
68
|
+
#: ((Riffer::Skills::Backend | Proc)?) -> void
|
|
69
|
+
def default_backend=(value)
|
|
70
|
+
valid = value.nil? || value.is_a?(Riffer::Skills::Backend) || value.is_a?(Proc)
|
|
71
|
+
raise Riffer::ArgumentError, "default_backend must be a Riffer::Skills::Backend instance, Proc, or nil" unless valid
|
|
72
|
+
@default_backend = value
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
25
76
|
VALID_MESSAGE_ID_STRATEGIES = %i[none uuid uuidv7].freeze
|
|
26
77
|
|
|
27
78
|
# Amazon Bedrock configuration (Struct with +api_token+ and +region+).
|
|
@@ -61,6 +112,10 @@ class Riffer::Config
|
|
|
61
112
|
@tool_runtime = value
|
|
62
113
|
end
|
|
63
114
|
|
|
115
|
+
# Skills-related global configuration. Returns a Riffer::Config::Skills
|
|
116
|
+
# object — see <tt>Riffer.config.skills.default_activate_tool</tt>.
|
|
117
|
+
attr_reader :skills #: Riffer::Config::Skills
|
|
118
|
+
|
|
64
119
|
# Strategy for auto-generating message ids. One of +:none+ (default, no id),
|
|
65
120
|
# +:uuid+ (UUIDv4), or +:uuidv7+ (time-ordered UUIDv7).
|
|
66
121
|
#
|
|
@@ -94,6 +149,7 @@ class Riffer::Config
|
|
|
94
149
|
@openai = OpenAI.new
|
|
95
150
|
@evals = Evals.new
|
|
96
151
|
@tool_runtime = Riffer::ToolRuntime::Inline.new
|
|
152
|
+
@skills = Skills.new
|
|
97
153
|
@message_id_strategy = :none
|
|
98
154
|
end
|
|
99
155
|
end
|
|
@@ -9,6 +9,24 @@ require "base64"
|
|
|
9
9
|
#
|
|
10
10
|
# See https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/BedrockRuntime/Client.html
|
|
11
11
|
class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
|
|
12
|
+
# Matches Anthropic models on Bedrock: bare ids like
|
|
13
|
+
# +anthropic.claude-3-5-sonnet-20241022-v2:0+ and cross-region prefixed
|
|
14
|
+
# ids like +us.anthropic.claude-sonnet-4-6+.
|
|
15
|
+
ANTHROPIC_MODEL_PATTERN = /(?:^|\.)anthropic\./ #: Regexp
|
|
16
|
+
|
|
17
|
+
# Returns the preferred skill adapter for the given Bedrock model.
|
|
18
|
+
#
|
|
19
|
+
# Bedrock hosts models from multiple vendors. Anthropic models prefer
|
|
20
|
+
# XML-rendered catalogs; everything else falls back to the default
|
|
21
|
+
# Markdown adapter.
|
|
22
|
+
#
|
|
23
|
+
#--
|
|
24
|
+
#: (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
25
|
+
def self.skills_adapter(model = nil)
|
|
26
|
+
return Riffer::Skills::XmlAdapter if model && ANTHROPIC_MODEL_PATTERN.match?(model)
|
|
27
|
+
Riffer::Skills::MarkdownAdapter
|
|
28
|
+
end
|
|
29
|
+
|
|
12
30
|
# Initializes the Amazon Bedrock provider.
|
|
13
31
|
#
|
|
14
32
|
#--
|
|
@@ -12,8 +12,8 @@ class Riffer::Providers::Anthropic < Riffer::Providers::Base
|
|
|
12
12
|
# Returns the XML skill adapter for Anthropic/Claude.
|
|
13
13
|
#
|
|
14
14
|
#--
|
|
15
|
-
#: () -> singleton(Riffer::Skills::Adapter)
|
|
16
|
-
def self.skills_adapter
|
|
15
|
+
#: (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
16
|
+
def self.skills_adapter(model = nil)
|
|
17
17
|
Riffer::Skills::XmlAdapter
|
|
18
18
|
end
|
|
19
19
|
|
|
@@ -24,11 +24,15 @@ class Riffer::Providers::Base
|
|
|
24
24
|
|
|
25
25
|
# Returns the preferred skill adapter for this provider.
|
|
26
26
|
#
|
|
27
|
-
# Override in subclasses for provider-specific formats.
|
|
27
|
+
# Override in subclasses for provider-specific formats. Subclasses may
|
|
28
|
+
# introspect +model+ (the resolved model identifier, e.g. the part after
|
|
29
|
+
# +provider/+) to pick an adapter that matches the underlying model
|
|
30
|
+
# family — useful for proxy providers like Amazon Bedrock that host
|
|
31
|
+
# models from multiple vendors.
|
|
28
32
|
#
|
|
29
33
|
#--
|
|
30
|
-
#: () -> singleton(Riffer::Skills::Adapter)
|
|
31
|
-
def self.skills_adapter
|
|
34
|
+
#: (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
35
|
+
def self.skills_adapter(model = nil)
|
|
32
36
|
Riffer::Skills::MarkdownAdapter
|
|
33
37
|
end
|
|
34
38
|
|
|
@@ -5,6 +5,21 @@
|
|
|
5
5
|
#
|
|
6
6
|
# No external gems required.
|
|
7
7
|
class Riffer::Providers::Mock < Riffer::Providers::Base
|
|
8
|
+
# Returns the preferred skill adapter for the given mock model.
|
|
9
|
+
#
|
|
10
|
+
# Mock is used to stand in for any real provider in tests, so the model
|
|
11
|
+
# string itself is the only signal we have. When the model name contains
|
|
12
|
+
# +claude+ (e.g. +mock/claude-sonnet-4-6+), pick the XML adapter to
|
|
13
|
+
# mirror what a real Claude-backed provider would do; otherwise fall
|
|
14
|
+
# back to Markdown.
|
|
15
|
+
#
|
|
16
|
+
#--
|
|
17
|
+
#: (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
18
|
+
def self.skills_adapter(model = nil)
|
|
19
|
+
return Riffer::Skills::XmlAdapter if model&.include?("claude")
|
|
20
|
+
Riffer::Skills::MarkdownAdapter
|
|
21
|
+
end
|
|
22
|
+
|
|
8
23
|
# Array of recorded method calls for assertions.
|
|
9
24
|
attr_reader :calls #: Array[Hash[Symbol, untyped]]
|
|
10
25
|
|
|
@@ -3,16 +3,31 @@
|
|
|
3
3
|
|
|
4
4
|
# Base class defining the interface for skill adapters.
|
|
5
5
|
#
|
|
6
|
-
# A skill adapter encapsulates the provider-specific
|
|
7
|
-
# how the
|
|
8
|
-
# the LLM calls to activate a skill.
|
|
6
|
+
# A skill adapter encapsulates the provider-specific catalog rendering for
|
|
7
|
+
# skills — how the available-skills section appears in the system prompt.
|
|
9
8
|
#
|
|
10
|
-
# Subclass and override +render_catalog
|
|
11
|
-
#
|
|
9
|
+
# Subclass and override +render_catalog+. The activation tool is set at
|
|
10
|
+
# construction time and is exposed via +#skill_activate_tool+ for use in
|
|
11
|
+
# rendered output.
|
|
12
12
|
#
|
|
13
13
|
# See Riffer::Skills::MarkdownAdapter for the default implementation.
|
|
14
14
|
# See Riffer::Skills::XmlAdapter for the Anthropic/Claude variant.
|
|
15
15
|
class Riffer::Skills::Adapter
|
|
16
|
+
# The activation tool class for this adapter.
|
|
17
|
+
attr_reader :skill_activate_tool #: singleton(Riffer::Tool)
|
|
18
|
+
|
|
19
|
+
# Creates a new adapter.
|
|
20
|
+
#
|
|
21
|
+
# [skill_activate_tool] the activation tool class — referenced by name
|
|
22
|
+
# in the rendered catalog so the LLM knows which
|
|
23
|
+
# tool to call.
|
|
24
|
+
#
|
|
25
|
+
#--
|
|
26
|
+
#: (skill_activate_tool: singleton(Riffer::Tool)) -> void
|
|
27
|
+
def initialize(skill_activate_tool:)
|
|
28
|
+
@skill_activate_tool = skill_activate_tool
|
|
29
|
+
end
|
|
30
|
+
|
|
16
31
|
# Renders a skill catalog section for the system prompt.
|
|
17
32
|
#
|
|
18
33
|
# [skills] array of Frontmatter objects to render.
|
|
@@ -24,14 +39,4 @@ class Riffer::Skills::Adapter
|
|
|
24
39
|
def render_catalog(skills)
|
|
25
40
|
raise NotImplementedError, "#{self.class} must implement #render_catalog"
|
|
26
41
|
end
|
|
27
|
-
|
|
28
|
-
# Returns the tool class used to activate skills.
|
|
29
|
-
#
|
|
30
|
-
# Override to provide a custom activation tool.
|
|
31
|
-
#
|
|
32
|
-
#--
|
|
33
|
-
#: () -> singleton(Riffer::Tool)
|
|
34
|
-
def activate_tool
|
|
35
|
-
Riffer::Skills::ActivateTool
|
|
36
|
-
end
|
|
37
42
|
end
|
data/lib/riffer/skills/config.rb
CHANGED
|
@@ -19,6 +19,7 @@ class Riffer::Skills::Config
|
|
|
19
19
|
@backend = nil
|
|
20
20
|
@adapter = nil
|
|
21
21
|
@activate = nil
|
|
22
|
+
@activate_tool = nil
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
# Gets or sets the skills backend.
|
|
@@ -59,4 +60,21 @@ class Riffer::Skills::Config
|
|
|
59
60
|
return @activate if value.nil?
|
|
60
61
|
@activate = value
|
|
61
62
|
end
|
|
63
|
+
|
|
64
|
+
# Gets or sets the per-agent override for the skill activation tool class.
|
|
65
|
+
#
|
|
66
|
+
# Returns the configured override when set, or +nil+ when unset. The
|
|
67
|
+
# global fallback to <tt>Riffer.config.skills.default_activate_tool</tt>
|
|
68
|
+
# is applied by the agent at resolution time (see
|
|
69
|
+
# Riffer::Agent.resolved_tool_classes), not by this getter.
|
|
70
|
+
#
|
|
71
|
+
# The override must be a subclass of Riffer::Tool.
|
|
72
|
+
#
|
|
73
|
+
#--
|
|
74
|
+
#: (?singleton(Riffer::Tool)?) -> singleton(Riffer::Tool)?
|
|
75
|
+
def activate_tool(value = nil)
|
|
76
|
+
return @activate_tool if value.nil?
|
|
77
|
+
raise Riffer::ArgumentError, "activate_tool must be a Riffer::Tool subclass" unless value.is_a?(Class) && value < Riffer::Tool
|
|
78
|
+
@activate_tool = value
|
|
79
|
+
end
|
|
62
80
|
end
|
|
@@ -24,7 +24,8 @@ class Riffer::Skills::Context
|
|
|
24
24
|
#
|
|
25
25
|
# [backend] the skills backend for reading skill bodies.
|
|
26
26
|
# [skills] skill catalog indexed by name.
|
|
27
|
-
# [adapter] the adapter used to render skill content.
|
|
27
|
+
# [adapter] the adapter used to render skill content. The adapter
|
|
28
|
+
# carries the activation tool class via its initializer.
|
|
28
29
|
#
|
|
29
30
|
#--
|
|
30
31
|
#: (backend: Riffer::Skills::Backend, skills: Hash[String, Riffer::Skills::Frontmatter], adapter: Riffer::Skills::Adapter) -> void
|
|
@@ -18,7 +18,7 @@ class Riffer::Skills::MarkdownAdapter < Riffer::Skills::Adapter
|
|
|
18
18
|
lines = []
|
|
19
19
|
lines << "## Available Skills"
|
|
20
20
|
lines << ""
|
|
21
|
-
lines << "When a user's request matches a skill description below, call the `#{
|
|
21
|
+
lines << "When a user's request matches a skill description below, call the `#{skill_activate_tool.name}` tool with the skill name. After activation, follow the skill's instructions."
|
|
22
22
|
lines << ""
|
|
23
23
|
skills.each do |skill|
|
|
24
24
|
lines << "- **#{skill.name}**: #{skill.description}"
|
|
@@ -17,7 +17,7 @@ class Riffer::Skills::XmlAdapter < Riffer::Skills::Adapter
|
|
|
17
17
|
#: (Array[Riffer::Skills::Frontmatter]) -> String
|
|
18
18
|
def render_catalog(skills)
|
|
19
19
|
lines = []
|
|
20
|
-
lines << "When a user's request matches a skill description below, call the `#{
|
|
20
|
+
lines << "When a user's request matches a skill description below, call the `#{skill_activate_tool.name}` tool with the skill name. After activation, follow the skill's instructions."
|
|
21
21
|
lines << ""
|
|
22
22
|
lines << "<available_skills>"
|
|
23
23
|
skills.each do |skill|
|
data/lib/riffer/version.rb
CHANGED
|
@@ -88,6 +88,31 @@ class Riffer::Agent
|
|
|
88
88
|
# : (?(Array[singleton(Riffer::Tool)] | Proc)?) -> (Array[singleton(Riffer::Tool)] | Proc)?
|
|
89
89
|
def self.uses_tools: (?(Array[singleton(Riffer::Tool)] | Proc)?) -> (Array[singleton(Riffer::Tool)] | Proc)?
|
|
90
90
|
|
|
91
|
+
# Returns the tool classes the LLM should see for this agent.
|
|
92
|
+
#
|
|
93
|
+
# Class-level companion to the instance #resolved_tools. Resolves the
|
|
94
|
+
# Proc form of +uses_tools+ and appends the skill activation tool when
|
|
95
|
+
# a +skills+ block is configured. Does not read the skills backend —
|
|
96
|
+
# the LLM-facing tool schema reflects class-level intent, not the
|
|
97
|
+
# runtime state of any backend.
|
|
98
|
+
#
|
|
99
|
+
# When +uses_tools+ is a Proc, +context+ is forwarded to it.
|
|
100
|
+
#
|
|
101
|
+
# The activation tool class is resolved from the agent's
|
|
102
|
+
# <tt>skills do; activate_tool ...; end</tt> override when set, otherwise
|
|
103
|
+
# from <tt>Riffer.config.skills.default_activate_tool</tt>.
|
|
104
|
+
#
|
|
105
|
+
# Raises Riffer::ArgumentError on tool name conflicts with the skill
|
|
106
|
+
# activation tool.
|
|
107
|
+
#
|
|
108
|
+
# --
|
|
109
|
+
# : (?context: Hash[Symbol, untyped]?) -> Array[singleton(Riffer::Tool)]
|
|
110
|
+
def self.resolved_tool_classes: (?context: Hash[Symbol, untyped]?) -> Array[singleton(Riffer::Tool)]
|
|
111
|
+
|
|
112
|
+
# --
|
|
113
|
+
# : (Hash[Symbol, untyped]?) -> Array[singleton(Riffer::Tool)]
|
|
114
|
+
def self.resolve_uses_tools_config: (Hash[Symbol, untyped]?) -> Array[singleton(Riffer::Tool)]
|
|
115
|
+
|
|
91
116
|
# Gets or sets the tool runtime for this agent.
|
|
92
117
|
#
|
|
93
118
|
# Accepts a Riffer::ToolRuntime subclass, a Riffer::ToolRuntime instance,
|
|
@@ -63,6 +63,47 @@ class Riffer::Config
|
|
|
63
63
|
| ({ ?judge_model: untyped }) -> instance
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
+
# Skills-related global configuration.
|
|
67
|
+
#
|
|
68
|
+
# See <tt>Riffer.config.skills.default_activate_tool</tt> and
|
|
69
|
+
# <tt>Riffer.config.skills.default_backend</tt>.
|
|
70
|
+
class Skills
|
|
71
|
+
# Default skill activation tool class.
|
|
72
|
+
#
|
|
73
|
+
# The tool class the LLM calls to activate a skill. Defaults to
|
|
74
|
+
# <tt>Riffer::Skills::ActivateTool</tt>. Per-agent override is available
|
|
75
|
+
# via <tt>skills do; activate_tool ...; end</tt>.
|
|
76
|
+
attr_reader default_activate_tool: singleton(Riffer::Tool)
|
|
77
|
+
|
|
78
|
+
# Default skills backend.
|
|
79
|
+
#
|
|
80
|
+
# Used by agents that declare a +skills+ block without specifying a
|
|
81
|
+
# backend. Accepts a Riffer::Skills::Backend instance or a Proc.
|
|
82
|
+
# Defaults to +nil+ (no global default).
|
|
83
|
+
attr_reader default_backend: (Riffer::Skills::Backend | Proc)?
|
|
84
|
+
|
|
85
|
+
# --
|
|
86
|
+
# : () -> void
|
|
87
|
+
def initialize: () -> void
|
|
88
|
+
|
|
89
|
+
# Sets the default skill activation tool class.
|
|
90
|
+
#
|
|
91
|
+
# Raises +Riffer::ArgumentError+ if the value is not a Riffer::Tool subclass.
|
|
92
|
+
#
|
|
93
|
+
# --
|
|
94
|
+
# : (singleton(Riffer::Tool)) -> void
|
|
95
|
+
def default_activate_tool=: (singleton(Riffer::Tool)) -> void
|
|
96
|
+
|
|
97
|
+
# Sets the default skills backend.
|
|
98
|
+
#
|
|
99
|
+
# Raises +Riffer::ArgumentError+ if the value is not a
|
|
100
|
+
# Riffer::Skills::Backend instance, a Proc, or +nil+.
|
|
101
|
+
#
|
|
102
|
+
# --
|
|
103
|
+
# : ((Riffer::Skills::Backend | Proc)?) -> void
|
|
104
|
+
def default_backend=: ((Riffer::Skills::Backend | Proc)?) -> void
|
|
105
|
+
end
|
|
106
|
+
|
|
66
107
|
VALID_MESSAGE_ID_STRATEGIES: untyped
|
|
67
108
|
|
|
68
109
|
# Amazon Bedrock configuration (Struct with +api_token+ and +region+).
|
|
@@ -98,6 +139,10 @@ class Riffer::Config
|
|
|
98
139
|
# : ((singleton(Riffer::ToolRuntime) | Riffer::ToolRuntime | Proc)) -> void
|
|
99
140
|
def tool_runtime=: (singleton(Riffer::ToolRuntime) | Riffer::ToolRuntime | Proc) -> void
|
|
100
141
|
|
|
142
|
+
# Skills-related global configuration. Returns a Riffer::Config::Skills
|
|
143
|
+
# object — see <tt>Riffer.config.skills.default_activate_tool</tt>.
|
|
144
|
+
attr_reader skills: Riffer::Config::Skills
|
|
145
|
+
|
|
101
146
|
# Strategy for auto-generating message ids. One of +:none+ (default, no id),
|
|
102
147
|
# +:uuid+ (UUIDv4), or +:uuidv7+ (time-ordered UUIDv7).
|
|
103
148
|
#
|
|
@@ -6,6 +6,21 @@
|
|
|
6
6
|
#
|
|
7
7
|
# See https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/BedrockRuntime/Client.html
|
|
8
8
|
class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
|
|
9
|
+
# Matches Anthropic models on Bedrock: bare ids like
|
|
10
|
+
# +anthropic.claude-3-5-sonnet-20241022-v2:0+ and cross-region prefixed
|
|
11
|
+
# ids like +us.anthropic.claude-sonnet-4-6+.
|
|
12
|
+
ANTHROPIC_MODEL_PATTERN: Regexp
|
|
13
|
+
|
|
14
|
+
# Returns the preferred skill adapter for the given Bedrock model.
|
|
15
|
+
#
|
|
16
|
+
# Bedrock hosts models from multiple vendors. Anthropic models prefer
|
|
17
|
+
# XML-rendered catalogs; everything else falls back to the default
|
|
18
|
+
# Markdown adapter.
|
|
19
|
+
#
|
|
20
|
+
# --
|
|
21
|
+
# : (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
22
|
+
def self.skills_adapter: (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
23
|
+
|
|
9
24
|
# Initializes the Amazon Bedrock provider.
|
|
10
25
|
#
|
|
11
26
|
# --
|
|
@@ -11,8 +11,8 @@ class Riffer::Providers::Anthropic < Riffer::Providers::Base
|
|
|
11
11
|
# Returns the XML skill adapter for Anthropic/Claude.
|
|
12
12
|
#
|
|
13
13
|
# --
|
|
14
|
-
# : () -> singleton(Riffer::Skills::Adapter)
|
|
15
|
-
def self.skills_adapter: () -> singleton(Riffer::Skills::Adapter)
|
|
14
|
+
# : (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
15
|
+
def self.skills_adapter: (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
16
16
|
|
|
17
17
|
# Initializes the Anthropic provider.
|
|
18
18
|
#
|
|
@@ -22,11 +22,15 @@ class Riffer::Providers::Base
|
|
|
22
22
|
|
|
23
23
|
# Returns the preferred skill adapter for this provider.
|
|
24
24
|
#
|
|
25
|
-
# Override in subclasses for provider-specific formats.
|
|
25
|
+
# Override in subclasses for provider-specific formats. Subclasses may
|
|
26
|
+
# introspect +model+ (the resolved model identifier, e.g. the part after
|
|
27
|
+
# +provider/+) to pick an adapter that matches the underlying model
|
|
28
|
+
# family — useful for proxy providers like Amazon Bedrock that host
|
|
29
|
+
# models from multiple vendors.
|
|
26
30
|
#
|
|
27
31
|
# --
|
|
28
|
-
# : () -> singleton(Riffer::Skills::Adapter)
|
|
29
|
-
def self.skills_adapter: () -> singleton(Riffer::Skills::Adapter)
|
|
32
|
+
# : (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
33
|
+
def self.skills_adapter: (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
30
34
|
|
|
31
35
|
# Generates text using the provider.
|
|
32
36
|
#
|
|
@@ -4,6 +4,18 @@
|
|
|
4
4
|
#
|
|
5
5
|
# No external gems required.
|
|
6
6
|
class Riffer::Providers::Mock < Riffer::Providers::Base
|
|
7
|
+
# Returns the preferred skill adapter for the given mock model.
|
|
8
|
+
#
|
|
9
|
+
# Mock is used to stand in for any real provider in tests, so the model
|
|
10
|
+
# string itself is the only signal we have. When the model name contains
|
|
11
|
+
# +claude+ (e.g. +mock/claude-sonnet-4-6+), pick the XML adapter to
|
|
12
|
+
# mirror what a real Claude-backed provider would do; otherwise fall
|
|
13
|
+
# back to Markdown.
|
|
14
|
+
#
|
|
15
|
+
# --
|
|
16
|
+
# : (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
17
|
+
def self.skills_adapter: (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
18
|
+
|
|
7
19
|
# Array of recorded method calls for assertions.
|
|
8
20
|
attr_reader calls: Array[Hash[Symbol, untyped]]
|
|
9
21
|
|
|
@@ -2,16 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
# Base class defining the interface for skill adapters.
|
|
4
4
|
#
|
|
5
|
-
# A skill adapter encapsulates the provider-specific
|
|
6
|
-
# how the
|
|
7
|
-
# the LLM calls to activate a skill.
|
|
5
|
+
# A skill adapter encapsulates the provider-specific catalog rendering for
|
|
6
|
+
# skills — how the available-skills section appears in the system prompt.
|
|
8
7
|
#
|
|
9
|
-
# Subclass and override +render_catalog
|
|
10
|
-
#
|
|
8
|
+
# Subclass and override +render_catalog+. The activation tool is set at
|
|
9
|
+
# construction time and is exposed via +#skill_activate_tool+ for use in
|
|
10
|
+
# rendered output.
|
|
11
11
|
#
|
|
12
12
|
# See Riffer::Skills::MarkdownAdapter for the default implementation.
|
|
13
13
|
# See Riffer::Skills::XmlAdapter for the Anthropic/Claude variant.
|
|
14
14
|
class Riffer::Skills::Adapter
|
|
15
|
+
# The activation tool class for this adapter.
|
|
16
|
+
attr_reader skill_activate_tool: singleton(Riffer::Tool)
|
|
17
|
+
|
|
18
|
+
# Creates a new adapter.
|
|
19
|
+
#
|
|
20
|
+
# [skill_activate_tool] the activation tool class — referenced by name
|
|
21
|
+
# in the rendered catalog so the LLM knows which
|
|
22
|
+
# tool to call.
|
|
23
|
+
#
|
|
24
|
+
# --
|
|
25
|
+
# : (skill_activate_tool: singleton(Riffer::Tool)) -> void
|
|
26
|
+
def initialize: (skill_activate_tool: singleton(Riffer::Tool)) -> void
|
|
27
|
+
|
|
15
28
|
# Renders a skill catalog section for the system prompt.
|
|
16
29
|
#
|
|
17
30
|
# [skills] array of Frontmatter objects to render.
|
|
@@ -21,12 +34,4 @@ class Riffer::Skills::Adapter
|
|
|
21
34
|
# --
|
|
22
35
|
# : (Array[Riffer::Skills::Frontmatter]) -> String
|
|
23
36
|
def render_catalog: (Array[Riffer::Skills::Frontmatter]) -> String
|
|
24
|
-
|
|
25
|
-
# Returns the tool class used to activate skills.
|
|
26
|
-
#
|
|
27
|
-
# Override to provide a custom activation tool.
|
|
28
|
-
#
|
|
29
|
-
# --
|
|
30
|
-
# : () -> singleton(Riffer::Tool)
|
|
31
|
-
def activate_tool: () -> singleton(Riffer::Tool)
|
|
32
37
|
end
|
|
@@ -45,4 +45,17 @@ class Riffer::Skills::Config
|
|
|
45
45
|
# --
|
|
46
46
|
# : (?(Array[String] | Proc)?) -> (Array[String] | Proc)?
|
|
47
47
|
def activate: (?(Array[String] | Proc)?) -> (Array[String] | Proc)?
|
|
48
|
+
|
|
49
|
+
# Gets or sets the per-agent override for the skill activation tool class.
|
|
50
|
+
#
|
|
51
|
+
# Returns the configured override when set, or +nil+ when unset. The
|
|
52
|
+
# global fallback to <tt>Riffer.config.skills.default_activate_tool</tt>
|
|
53
|
+
# is applied by the agent at resolution time (see
|
|
54
|
+
# Riffer::Agent.resolved_tool_classes), not by this getter.
|
|
55
|
+
#
|
|
56
|
+
# The override must be a subclass of Riffer::Tool.
|
|
57
|
+
#
|
|
58
|
+
# --
|
|
59
|
+
# : (?singleton(Riffer::Tool)?) -> singleton(Riffer::Tool)?
|
|
60
|
+
def activate_tool: (?singleton(Riffer::Tool)?) -> singleton(Riffer::Tool)?
|
|
48
61
|
end
|
|
@@ -23,7 +23,8 @@ class Riffer::Skills::Context
|
|
|
23
23
|
#
|
|
24
24
|
# [backend] the skills backend for reading skill bodies.
|
|
25
25
|
# [skills] skill catalog indexed by name.
|
|
26
|
-
# [adapter] the adapter used to render skill content.
|
|
26
|
+
# [adapter] the adapter used to render skill content. The adapter
|
|
27
|
+
# carries the activation tool class via its initializer.
|
|
27
28
|
#
|
|
28
29
|
# --
|
|
29
30
|
# : (backend: Riffer::Skills::Backend, skills: Hash[String, Riffer::Skills::Frontmatter], adapter: Riffer::Skills::Adapter) -> void
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: riffer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.26.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jake Bottrall
|
|
@@ -35,14 +35,14 @@ dependencies:
|
|
|
35
35
|
requirements:
|
|
36
36
|
- - "~>"
|
|
37
37
|
- !ruby/object:Gem::Version
|
|
38
|
-
version: 1.
|
|
38
|
+
version: 1.36.0
|
|
39
39
|
type: :development
|
|
40
40
|
prerelease: false
|
|
41
41
|
version_requirements: !ruby/object:Gem::Requirement
|
|
42
42
|
requirements:
|
|
43
43
|
- - "~>"
|
|
44
44
|
- !ruby/object:Gem::Version
|
|
45
|
-
version: 1.
|
|
45
|
+
version: 1.36.0
|
|
46
46
|
- !ruby/object:Gem::Dependency
|
|
47
47
|
name: aws-sdk-bedrockruntime
|
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -221,6 +221,7 @@ files:
|
|
|
221
221
|
- ".agents/rbs-inline.md"
|
|
222
222
|
- ".agents/rdoc.md"
|
|
223
223
|
- ".agents/testing.md"
|
|
224
|
+
- ".bundle/config"
|
|
224
225
|
- ".release-please-config.json"
|
|
225
226
|
- ".release-please-manifest.json"
|
|
226
227
|
- ".ruby-version"
|
|
@@ -449,7 +450,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
449
450
|
- !ruby/object:Gem::Version
|
|
450
451
|
version: '0'
|
|
451
452
|
requirements: []
|
|
452
|
-
rubygems_version:
|
|
453
|
+
rubygems_version: 4.0.6
|
|
453
454
|
specification_version: 4
|
|
454
455
|
summary: The all-in-one Ruby framework for building AI-powered applications and agents.
|
|
455
456
|
test_files: []
|