riffer 0.31.0 → 0.32.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/code-style.md +63 -4
- data/.agents/rbs-inline.md +1 -6
- data/.release-please-manifest.json +1 -1
- data/AGENTS.md +1 -2
- data/CHANGELOG.md +18 -0
- data/docs/08_MESSAGES.md +1 -1
- data/docs/14_MCP.md +50 -5
- data/docs/providers/02_AMAZON_BEDROCK.md +14 -0
- data/lib/riffer/agent/config.rb +42 -47
- data/lib/riffer/agent/context.rb +70 -50
- data/lib/riffer/agent/response.rb +4 -20
- data/lib/riffer/agent/run.rb +28 -67
- data/lib/riffer/agent/serializer.rb +22 -81
- data/lib/riffer/agent/session/repair.rb +14 -40
- data/lib/riffer/agent/session.rb +25 -67
- data/lib/riffer/agent/structured_output/result.rb +3 -11
- data/lib/riffer/agent/structured_output.rb +5 -13
- data/lib/riffer/agent.rb +74 -192
- data/lib/riffer/config.rb +34 -101
- data/lib/riffer/evals/evaluator.rb +7 -27
- data/lib/riffer/evals/evaluator_runner.rb +11 -19
- data/lib/riffer/evals/judge.rb +4 -25
- data/lib/riffer/evals/result.rb +1 -18
- data/lib/riffer/evals/run_result.rb +0 -11
- data/lib/riffer/evals/scenario_result.rb +0 -14
- data/lib/riffer/evals.rb +0 -6
- data/lib/riffer/guardrail.rb +4 -27
- data/lib/riffer/guardrails/modification.rb +0 -10
- data/lib/riffer/guardrails/result.rb +3 -30
- data/lib/riffer/guardrails/runner.rb +5 -22
- data/lib/riffer/guardrails/tripwire.rb +1 -19
- data/lib/riffer/guardrails.rb +2 -4
- data/lib/riffer/helpers/call_or_value.rb +4 -3
- data/lib/riffer/helpers/class_name_converter.rb +3 -1
- data/lib/riffer/helpers/dependencies.rb +5 -7
- data/lib/riffer/helpers.rb +0 -5
- data/lib/riffer/mcp/authenticated_tool.rb +9 -9
- data/lib/riffer/mcp/client.rb +12 -17
- data/lib/riffer/mcp/manifest.rb +13 -10
- data/lib/riffer/mcp/registration.rb +2 -11
- data/lib/riffer/mcp/registry.rb +44 -52
- data/lib/riffer/mcp/search_tool.rb +53 -0
- data/lib/riffer/mcp/tool_factory.rb +13 -18
- data/lib/riffer/mcp.rb +12 -17
- data/lib/riffer/messages/assistant.rb +2 -9
- data/lib/riffer/messages/base.rb +46 -16
- data/lib/riffer/messages/file_part.rb +32 -24
- data/lib/riffer/messages/system.rb +0 -5
- data/lib/riffer/messages/tool.rb +0 -10
- data/lib/riffer/messages/user.rb +0 -10
- data/lib/riffer/messages.rb +0 -7
- data/lib/riffer/params/boolean.rb +2 -4
- data/lib/riffer/params/param.rb +28 -39
- data/lib/riffer/params.rb +9 -21
- data/lib/riffer/providers/amazon_bedrock.rb +42 -28
- data/lib/riffer/providers/anthropic.rb +4 -9
- data/lib/riffer/providers/azure_open_ai.rb +3 -19
- data/lib/riffer/providers/base.rb +13 -26
- data/lib/riffer/providers/gemini.rb +4 -4
- data/lib/riffer/providers/mock.rb +6 -26
- data/lib/riffer/providers/open_ai.rb +6 -8
- data/lib/riffer/providers/open_router.rb +4 -10
- data/lib/riffer/providers/repository.rb +4 -3
- data/lib/riffer/providers/token_usage.rb +9 -20
- data/lib/riffer/providers.rb +0 -8
- data/lib/riffer/runner/fibers.rb +10 -16
- data/lib/riffer/runner/sequential.rb +1 -4
- data/lib/riffer/runner/threaded.rb +3 -14
- data/lib/riffer/runner.rb +2 -15
- data/lib/riffer/skills/activate_tool.rb +2 -11
- data/lib/riffer/skills/adapter.rb +4 -22
- data/lib/riffer/skills/backend.rb +7 -21
- data/lib/riffer/skills/config.rb +10 -31
- data/lib/riffer/skills/context.rb +5 -20
- data/lib/riffer/skills/filesystem_backend.rb +7 -25
- data/lib/riffer/skills/frontmatter.rb +10 -28
- data/lib/riffer/skills/markdown_adapter.rb +2 -9
- data/lib/riffer/skills/xml_adapter.rb +2 -8
- data/lib/riffer/stream_events/base.rb +1 -6
- data/lib/riffer/stream_events/guardrail_modification.rb +1 -8
- data/lib/riffer/stream_events/guardrail_tripwire.rb +1 -8
- data/lib/riffer/stream_events/interrupt.rb +4 -7
- data/lib/riffer/stream_events/reasoning_delta.rb +2 -4
- data/lib/riffer/stream_events/reasoning_done.rb +2 -4
- data/lib/riffer/stream_events/skill_activation.rb +2 -4
- data/lib/riffer/stream_events/text_delta.rb +0 -2
- data/lib/riffer/stream_events/text_done.rb +1 -3
- data/lib/riffer/stream_events/token_usage_done.rb +1 -8
- data/lib/riffer/stream_events/tool_call_delta.rb +2 -3
- data/lib/riffer/stream_events/tool_call_done.rb +1 -3
- data/lib/riffer/stream_events/web_search_done.rb +1 -3
- data/lib/riffer/stream_events/web_search_status.rb +2 -3
- data/lib/riffer/stream_events.rb +0 -10
- data/lib/riffer/tool.rb +6 -13
- data/lib/riffer/tools/response.rb +8 -4
- data/lib/riffer/tools/runtime/fibers.rb +0 -3
- data/lib/riffer/tools/runtime/inline.rb +1 -4
- data/lib/riffer/tools/runtime/threaded.rb +0 -2
- data/lib/riffer/tools/runtime.rb +5 -38
- data/lib/riffer/tools/toolable.rb +5 -16
- data/lib/riffer/tools.rb +0 -4
- data/lib/riffer/version.rb +1 -1
- data/lib/riffer.rb +7 -8
- data/sig/generated/riffer/agent/config.rbs +29 -46
- data/sig/generated/riffer/agent/context.rbs +40 -48
- data/sig/generated/riffer/agent/response.rbs +4 -20
- data/sig/generated/riffer/agent/run.rbs +12 -61
- data/sig/generated/riffer/agent/serializer.rbs +21 -80
- data/sig/generated/riffer/agent/session/repair.rbs +12 -40
- data/sig/generated/riffer/agent/session.rbs +25 -67
- data/sig/generated/riffer/agent/structured_output/result.rbs +2 -10
- data/sig/generated/riffer/agent/structured_output.rbs +5 -12
- data/sig/generated/riffer/agent.rbs +57 -186
- data/sig/generated/riffer/config.rbs +34 -100
- data/sig/generated/riffer/evals/evaluator.rbs +7 -27
- data/sig/generated/riffer/evals/evaluator_runner.rbs +9 -19
- data/sig/generated/riffer/evals/judge.rbs +4 -24
- data/sig/generated/riffer/evals/result.rbs +1 -17
- data/sig/generated/riffer/evals/run_result.rbs +0 -10
- data/sig/generated/riffer/evals/scenario_result.rbs +0 -13
- data/sig/generated/riffer/evals.rbs +0 -6
- data/sig/generated/riffer/guardrail.rbs +4 -27
- data/sig/generated/riffer/guardrails/modification.rbs +0 -10
- data/sig/generated/riffer/guardrails/result.rbs +3 -30
- data/sig/generated/riffer/guardrails/runner.rbs +5 -22
- data/sig/generated/riffer/guardrails/tripwire.rbs +1 -19
- data/sig/generated/riffer/guardrails.rbs +2 -4
- data/sig/generated/riffer/helpers/call_or_value.rbs +4 -3
- data/sig/generated/riffer/helpers/class_name_converter.rbs +1 -1
- data/sig/generated/riffer/helpers/dependencies.rbs +3 -7
- data/sig/generated/riffer/helpers.rbs +0 -5
- data/sig/generated/riffer/mcp/authenticated_tool.rbs +5 -4
- data/sig/generated/riffer/mcp/client.rbs +10 -16
- data/sig/generated/riffer/mcp/manifest.rbs +9 -9
- data/sig/generated/riffer/mcp/registration.rbs +2 -10
- data/sig/generated/riffer/mcp/registry.rbs +11 -18
- data/sig/generated/riffer/mcp/search_tool.rbs +26 -0
- data/sig/generated/riffer/mcp/tool_factory.rbs +10 -15
- data/sig/generated/riffer/mcp.rbs +10 -17
- data/sig/generated/riffer/messages/assistant.rbs +2 -8
- data/sig/generated/riffer/messages/base.rbs +11 -16
- data/sig/generated/riffer/messages/file_part.rbs +13 -23
- data/sig/generated/riffer/messages/system.rbs +0 -4
- data/sig/generated/riffer/messages/tool.rbs +0 -9
- data/sig/generated/riffer/messages/user.rbs +0 -9
- data/sig/generated/riffer/messages.rbs +0 -7
- data/sig/generated/riffer/params/boolean.rbs +2 -4
- data/sig/generated/riffer/params/param.rbs +21 -39
- data/sig/generated/riffer/params.rbs +9 -21
- data/sig/generated/riffer/providers/amazon_bedrock.rbs +21 -25
- data/sig/generated/riffer/providers/anthropic.rbs +2 -7
- data/sig/generated/riffer/providers/azure_open_ai.rbs +3 -18
- data/sig/generated/riffer/providers/base.rbs +9 -25
- data/sig/generated/riffer/providers/gemini.rbs +0 -2
- data/sig/generated/riffer/providers/mock.rbs +6 -26
- data/sig/generated/riffer/providers/open_ai.rbs +1 -5
- data/sig/generated/riffer/providers/open_router.rbs +4 -10
- data/sig/generated/riffer/providers/repository.rbs +2 -3
- data/sig/generated/riffer/providers/token_usage.rbs +6 -16
- data/sig/generated/riffer/providers.rbs +0 -8
- data/sig/generated/riffer/runner/fibers.rbs +8 -15
- data/sig/generated/riffer/runner/sequential.rbs +1 -3
- data/sig/generated/riffer/runner/threaded.rbs +3 -13
- data/sig/generated/riffer/runner.rbs +2 -14
- data/sig/generated/riffer/skills/activate_tool.rbs +2 -11
- data/sig/generated/riffer/skills/adapter.rbs +4 -22
- data/sig/generated/riffer/skills/backend.rbs +7 -21
- data/sig/generated/riffer/skills/config.rbs +10 -31
- data/sig/generated/riffer/skills/context.rbs +5 -20
- data/sig/generated/riffer/skills/filesystem_backend.rbs +7 -24
- data/sig/generated/riffer/skills/frontmatter.rbs +10 -27
- data/sig/generated/riffer/skills/markdown_adapter.rbs +2 -9
- data/sig/generated/riffer/skills/xml_adapter.rbs +2 -8
- data/sig/generated/riffer/stream_events/base.rbs +1 -6
- data/sig/generated/riffer/stream_events/guardrail_modification.rbs +1 -8
- data/sig/generated/riffer/stream_events/guardrail_tripwire.rbs +1 -8
- data/sig/generated/riffer/stream_events/interrupt.rbs +4 -7
- data/sig/generated/riffer/stream_events/reasoning_delta.rbs +2 -4
- data/sig/generated/riffer/stream_events/reasoning_done.rbs +2 -4
- data/sig/generated/riffer/stream_events/skill_activation.rbs +2 -4
- data/sig/generated/riffer/stream_events/text_delta.rbs +0 -2
- data/sig/generated/riffer/stream_events/text_done.rbs +1 -3
- data/sig/generated/riffer/stream_events/token_usage_done.rbs +1 -7
- data/sig/generated/riffer/stream_events/tool_call_delta.rbs +2 -3
- data/sig/generated/riffer/stream_events/tool_call_done.rbs +1 -3
- data/sig/generated/riffer/stream_events/web_search_done.rbs +1 -3
- data/sig/generated/riffer/stream_events/web_search_status.rbs +2 -3
- data/sig/generated/riffer/stream_events.rbs +0 -10
- data/sig/generated/riffer/tool.rbs +5 -12
- data/sig/generated/riffer/tools/response.rbs +6 -4
- data/sig/generated/riffer/tools/runtime/fibers.rbs +0 -3
- data/sig/generated/riffer/tools/runtime/inline.rbs +1 -3
- data/sig/generated/riffer/tools/runtime/threaded.rbs +0 -2
- data/sig/generated/riffer/tools/runtime.rbs +5 -37
- data/sig/generated/riffer/tools/toolable.rbs +4 -14
- data/sig/generated/riffer/tools.rbs +0 -4
- data/sig/generated/riffer.rbs +5 -4
- data/sig/manual/riffer/agent/session/repair.rbs +5 -0
- data/sig/manual/riffer/evals/evaluator_runner.rbs +5 -0
- data/sig/manual/riffer/helpers/class_name_converter.rbs +5 -0
- data/sig/manual/riffer/helpers/dependencies.rbs +5 -0
- data/sig/manual/riffer/mcp/authenticated_tool.rbs +5 -0
- data/sig/manual/riffer/mcp/registry.rbs +5 -0
- data/sig/manual/riffer/mcp/tool_factory.rbs +5 -0
- data/sig/manual/riffer/mcp.rbs +5 -0
- data/sig/manual/riffer/providers/repository.rbs +5 -0
- data/sig/manual/riffer.rbs +5 -0
- metadata +17 -9
- data/.agents/rdoc.md +0 -69
- data/lib/riffer/messages/converter.rb +0 -90
- data/sig/generated/riffer/messages/converter.rbs +0 -33
- data/sig/manual/riffer/tools/toolable.rbs +0 -6
|
@@ -3,35 +3,17 @@
|
|
|
3
3
|
|
|
4
4
|
require "json"
|
|
5
5
|
|
|
6
|
-
# Base class for all LLM providers
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
# ==== Hook methods
|
|
12
|
-
#
|
|
13
|
-
# [build_request_params] convert messages, tools, and options into SDK params
|
|
14
|
-
# [execute_generate] call the SDK and return the raw response
|
|
15
|
-
# [execute_stream] call the streaming SDK, mapping events to the yielder
|
|
16
|
-
# [extract_token_usage] pull token counts from the SDK response
|
|
17
|
-
# [extract_content] extract text content from the SDK response
|
|
18
|
-
# [extract_tool_calls] extract tool calls from the SDK response
|
|
6
|
+
# Base class for all LLM providers. A template-method flow: subclasses implement
|
|
7
|
+
# the hooks (+build_request_params+, +execute_generate+, +execute_stream+,
|
|
8
|
+
# +extract_token_usage+, +extract_content+, +extract_tool_calls+) and the base
|
|
9
|
+
# class orchestrates them.
|
|
19
10
|
class Riffer::Providers::Base
|
|
20
11
|
# @rbs @current_tools: Array[singleton(Riffer::Tool)]
|
|
21
12
|
|
|
22
|
-
include Riffer::Helpers::Dependencies
|
|
23
|
-
include Riffer::Messages::Converter
|
|
24
|
-
|
|
25
13
|
WIRE_SEPARATOR = "__" #: String
|
|
26
14
|
|
|
27
|
-
# Returns the preferred skill adapter for this provider
|
|
28
|
-
#
|
|
29
|
-
# Override in subclasses for provider-specific formats. Subclasses may
|
|
30
|
-
# introspect +model+ (the resolved model identifier, e.g. the part after
|
|
31
|
-
# +provider/+) to pick an adapter that matches the underlying model
|
|
32
|
-
# family — useful for proxy providers like Amazon Bedrock that host
|
|
33
|
-
# models from multiple vendors.
|
|
34
|
-
#
|
|
15
|
+
# Returns the preferred skill adapter for this provider; override in
|
|
16
|
+
# subclasses (optionally introspecting +model+) for provider-specific formats.
|
|
35
17
|
#--
|
|
36
18
|
#: (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
37
19
|
def self.skills_adapter(model = nil)
|
|
@@ -82,6 +64,11 @@ class Riffer::Providers::Base
|
|
|
82
64
|
|
|
83
65
|
private
|
|
84
66
|
|
|
67
|
+
#: (String) -> true
|
|
68
|
+
def depends_on(gem_name)
|
|
69
|
+
Riffer::Helpers::Dependencies.depends_on(gem_name)
|
|
70
|
+
end
|
|
71
|
+
|
|
85
72
|
#--
|
|
86
73
|
#: (String) -> String
|
|
87
74
|
def encode_tool_name(name)
|
|
@@ -175,12 +162,12 @@ class Riffer::Providers::Base
|
|
|
175
162
|
end
|
|
176
163
|
|
|
177
164
|
if messages
|
|
178
|
-
return messages.map { |msg|
|
|
165
|
+
return messages.map { |msg| Riffer::Messages::Base.from_hash(msg) }
|
|
179
166
|
end
|
|
180
167
|
|
|
181
168
|
result = [] #: Array[Riffer::Messages::Base]
|
|
182
169
|
result << Riffer::Messages::System.new(system) if system
|
|
183
|
-
file_parts = (files || []).map { |f|
|
|
170
|
+
file_parts = (files || []).map { |f| Riffer::Messages::FilePart.from_hash(f) }
|
|
184
171
|
prompt_text = prompt #: String
|
|
185
172
|
result << Riffer::Messages::User.new(prompt_text, files: file_parts)
|
|
186
173
|
result
|
|
@@ -17,8 +17,6 @@ class Riffer::Providers::Gemini < Riffer::Providers::Base
|
|
|
17
17
|
DEFAULT_OPEN_TIMEOUT = 10 #: Integer
|
|
18
18
|
DEFAULT_READ_TIMEOUT = 60 #: Integer
|
|
19
19
|
|
|
20
|
-
# Initializes the Gemini provider.
|
|
21
|
-
#
|
|
22
20
|
#--
|
|
23
21
|
#: (?api_key: String?, ?open_timeout: Integer?, ?read_timeout: Integer?, **untyped) -> void
|
|
24
22
|
def initialize(api_key: nil, open_timeout: nil, read_timeout: nil, **options)
|
|
@@ -107,7 +105,8 @@ class Riffer::Providers::Gemini < Riffer::Providers::Base
|
|
|
107
105
|
|
|
108
106
|
Riffer::Providers::TokenUsage.new(
|
|
109
107
|
input_tokens: usage[:promptTokenCount] || 0,
|
|
110
|
-
output_tokens: usage[:candidatesTokenCount] || 0
|
|
108
|
+
output_tokens: usage[:candidatesTokenCount] || 0,
|
|
109
|
+
cache_read_tokens: usage[:cachedContentTokenCount]
|
|
111
110
|
)
|
|
112
111
|
end
|
|
113
112
|
|
|
@@ -163,7 +162,8 @@ class Riffer::Providers::Gemini < Riffer::Providers::Base
|
|
|
163
162
|
yielder << Riffer::StreamEvents::TokenUsageDone.new(
|
|
164
163
|
token_usage: Riffer::Providers::TokenUsage.new(
|
|
165
164
|
input_tokens: usage[:promptTokenCount] || 0,
|
|
166
|
-
output_tokens: usage[:candidatesTokenCount] || 0
|
|
165
|
+
output_tokens: usage[:candidatesTokenCount] || 0,
|
|
166
|
+
cache_read_tokens: usage[:cachedContentTokenCount]
|
|
167
167
|
)
|
|
168
168
|
)
|
|
169
169
|
end
|
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Mock provider for mocking LLM responses in tests.
|
|
5
|
-
#
|
|
6
|
-
# No external gems required.
|
|
4
|
+
# Mock provider for mocking LLM responses in tests; no external gems required.
|
|
7
5
|
class Riffer::Providers::Mock < Riffer::Providers::Base
|
|
8
6
|
# @rbs @responses: Array[Hash[Symbol, untyped]]
|
|
9
7
|
# @rbs @current_index: Integer
|
|
10
8
|
# @rbs @stubbed_responses: Array[Hash[Symbol, untyped]]
|
|
11
9
|
|
|
12
|
-
# Returns the
|
|
13
|
-
#
|
|
14
|
-
# Mock is used to stand in for any real provider in tests, so the model
|
|
15
|
-
# string itself is the only signal we have. When the model name contains
|
|
16
|
-
# +claude+ (e.g. +mock/claude-sonnet-4-6+), pick the XML adapter to
|
|
17
|
-
# mirror what a real Claude-backed provider would do; otherwise fall
|
|
18
|
-
# back to Markdown.
|
|
19
|
-
#
|
|
10
|
+
# Returns the skill adapter for the mock model — XML when the model name
|
|
11
|
+
# contains +claude+ (mirroring a real Claude provider), else Markdown.
|
|
20
12
|
#--
|
|
21
13
|
#: (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
22
14
|
def self.skills_adapter(model = nil)
|
|
@@ -27,13 +19,8 @@ class Riffer::Providers::Mock < Riffer::Providers::Base
|
|
|
27
19
|
# Array of recorded method calls for assertions.
|
|
28
20
|
attr_reader :calls #: Array[Hash[Symbol, untyped]]
|
|
29
21
|
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
# +responses:+ accepts an array of response hashes in the same shape
|
|
33
|
-
# +#stub_response+ takes — raw +tool_calls:+ hashes are normalised to
|
|
34
|
-
# +Riffer::Messages::Assistant::ToolCall+ instances. This is the canonical
|
|
35
|
-
# way to pre-configure canned LLM responses on an agent via
|
|
36
|
-
# +provider_options responses: [...]+.
|
|
22
|
+
# +responses:+ pre-configures canned responses (same shape as
|
|
23
|
+
# +#stub_response+), typically set via +provider_options responses: [...]+.
|
|
37
24
|
#
|
|
38
25
|
# Riffer::Providers::Mock.new(responses: [
|
|
39
26
|
# {content: "", tool_calls: [{name: "tool_a", arguments: "{}"}]},
|
|
@@ -49,9 +36,7 @@ class Riffer::Providers::Mock < Riffer::Providers::Base
|
|
|
49
36
|
@stubbed_responses = []
|
|
50
37
|
end
|
|
51
38
|
|
|
52
|
-
# Stubs the next response
|
|
53
|
-
#
|
|
54
|
-
# Can be called multiple times to queue responses.
|
|
39
|
+
# Stubs the next response; call repeatedly to queue several.
|
|
55
40
|
#
|
|
56
41
|
# provider.stub_response("Hello")
|
|
57
42
|
# provider.stub_response("", tool_calls: [{name: "my_tool", arguments: '{"key":"value"}'}])
|
|
@@ -73,11 +58,6 @@ class Riffer::Providers::Mock < Riffer::Providers::Base
|
|
|
73
58
|
|
|
74
59
|
private
|
|
75
60
|
|
|
76
|
-
# Normalises a response hash into Mock's internal format. Accepts the
|
|
77
|
-
# +#stub_response+ kwargs shape (+content:+, +tool_calls:+, +token_usage:+)
|
|
78
|
-
# or a pre-built hash with already-converted ToolCall instances. Raw
|
|
79
|
-
# +tool_calls:+ hashes are wrapped in +Riffer::Messages::Assistant::ToolCall+.
|
|
80
|
-
#
|
|
81
61
|
#--
|
|
82
62
|
#: (Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
|
|
83
63
|
def normalize_response(response)
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# OpenAI provider for GPT models.
|
|
5
|
-
#
|
|
6
|
-
# Requires the +openai+ gem to be installed.
|
|
4
|
+
# OpenAI provider for GPT models. Requires the +openai+ gem.
|
|
7
5
|
class Riffer::Providers::OpenAI < Riffer::Providers::Base
|
|
8
6
|
WEB_SEARCH_TOOL_TYPE = "web_search_preview" #: String
|
|
9
7
|
|
|
10
|
-
# Initializes the OpenAI provider.
|
|
11
|
-
#
|
|
12
8
|
#--
|
|
13
9
|
#: (**untyped) -> void
|
|
14
10
|
def initialize(**options)
|
|
@@ -80,7 +76,8 @@ class Riffer::Providers::OpenAI < Riffer::Providers::Base
|
|
|
80
76
|
|
|
81
77
|
Riffer::Providers::TokenUsage.new(
|
|
82
78
|
input_tokens: usage.input_tokens,
|
|
83
|
-
output_tokens: usage.output_tokens
|
|
79
|
+
output_tokens: usage.output_tokens,
|
|
80
|
+
cache_read_tokens: usage.input_tokens_details&.cached_tokens
|
|
84
81
|
)
|
|
85
82
|
end
|
|
86
83
|
|
|
@@ -229,7 +226,8 @@ class Riffer::Providers::OpenAI < Riffer::Providers::Base
|
|
|
229
226
|
yielder << Riffer::StreamEvents::TokenUsageDone.new(
|
|
230
227
|
token_usage: Riffer::Providers::TokenUsage.new(
|
|
231
228
|
input_tokens: usage.input_tokens,
|
|
232
|
-
output_tokens: usage.output_tokens
|
|
229
|
+
output_tokens: usage.output_tokens,
|
|
230
|
+
cache_read_tokens: usage.input_tokens_details&.cached_tokens
|
|
233
231
|
)
|
|
234
232
|
)
|
|
235
233
|
end
|
|
@@ -251,7 +249,7 @@ class Riffer::Providers::OpenAI < Riffer::Providers::Base
|
|
|
251
249
|
yielder << Riffer::StreamEvents::WebSearchStatus.new("open_page", url: action.url)
|
|
252
250
|
when ::OpenAI::Models::Responses::ResponseFunctionWebSearch::Action::Search
|
|
253
251
|
sources = (action.sources || []).map { |s| {title: nil, url: s.url} }
|
|
254
|
-
yielder << Riffer::StreamEvents::WebSearchDone.new(action.query, sources: sources)
|
|
252
|
+
yielder << Riffer::StreamEvents::WebSearchDone.new(action.query || "", sources: sources)
|
|
255
253
|
end
|
|
256
254
|
end
|
|
257
255
|
|
|
@@ -3,19 +3,13 @@
|
|
|
3
3
|
|
|
4
4
|
require "json"
|
|
5
5
|
|
|
6
|
-
# OpenRouter provider
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# the OpenAI Ruby SDK with a +base_url+ override.
|
|
11
|
-
#
|
|
12
|
-
# The +api_key+ falls back to <tt>Riffer.config.openrouter.api_key</tt>
|
|
13
|
-
# and then to +OPENROUTER_API_KEY+.
|
|
6
|
+
# OpenRouter provider (https://openrouter.ai). Requires the +openai+ gem —
|
|
7
|
+
# OpenRouter exposes an OpenAI-compatible endpoint, so this reuses the OpenAI
|
|
8
|
+
# SDK with a +base_url+ override. +api_key+ falls back to config, then
|
|
9
|
+
# +OPENROUTER_API_KEY+.
|
|
14
10
|
class Riffer::Providers::OpenRouter < Riffer::Providers::Base
|
|
15
11
|
BASE_URL = "https://openrouter.ai/api/v1" #: String
|
|
16
12
|
|
|
17
|
-
# Initializes the OpenRouter provider.
|
|
18
|
-
#
|
|
19
13
|
#--
|
|
20
14
|
#: (?api_key: String?, **untyped) -> void
|
|
21
15
|
def initialize(api_key: nil, **options)
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
4
|
# Registry for finding provider classes by identifier.
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
module Riffer::Providers::Repository
|
|
6
|
+
extend self
|
|
7
|
+
|
|
7
8
|
REPO = {
|
|
8
9
|
amazon_bedrock: -> { Riffer::Providers::AmazonBedrock },
|
|
9
10
|
anthropic: -> { Riffer::Providers::Anthropic },
|
|
@@ -18,7 +19,7 @@ class Riffer::Providers::Repository
|
|
|
18
19
|
#
|
|
19
20
|
#--
|
|
20
21
|
#: ((String | Symbol)) -> singleton(Riffer::Providers::Base)?
|
|
21
|
-
def
|
|
22
|
+
def find(identifier)
|
|
22
23
|
REPO.fetch(identifier.to_sym, nil)&.call
|
|
23
24
|
end
|
|
24
25
|
end
|
|
@@ -2,14 +2,6 @@
|
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
4
|
# Represents token usage data from an LLM API call.
|
|
5
|
-
#
|
|
6
|
-
# Tracks input tokens, output tokens, and optional cache statistics.
|
|
7
|
-
#
|
|
8
|
-
# token_usage = Riffer::Providers::TokenUsage.new(input_tokens: 100, output_tokens: 50)
|
|
9
|
-
# token_usage.total_tokens # => 150
|
|
10
|
-
#
|
|
11
|
-
# combined = token_usage1 + token_usage2 # Combine multiple token usage objects
|
|
12
|
-
#
|
|
13
5
|
class Riffer::Providers::TokenUsage
|
|
14
6
|
# Number of tokens in the input/prompt.
|
|
15
7
|
attr_reader :input_tokens #: Integer
|
|
@@ -17,18 +9,18 @@ class Riffer::Providers::TokenUsage
|
|
|
17
9
|
# Number of tokens in the output/response.
|
|
18
10
|
attr_reader :output_tokens #: Integer
|
|
19
11
|
|
|
20
|
-
# Number of tokens written to cache
|
|
21
|
-
attr_reader :
|
|
12
|
+
# Number of tokens written to cache, when the provider reports it.
|
|
13
|
+
attr_reader :cache_write_tokens #: Integer?
|
|
22
14
|
|
|
23
|
-
# Number of tokens read from cache
|
|
15
|
+
# Number of tokens read from cache, when the provider reports it.
|
|
24
16
|
attr_reader :cache_read_tokens #: Integer?
|
|
25
17
|
|
|
26
18
|
#--
|
|
27
|
-
#: (input_tokens: Integer, output_tokens: Integer, ?
|
|
28
|
-
def initialize(input_tokens:, output_tokens:,
|
|
19
|
+
#: (input_tokens: Integer, output_tokens: Integer, ?cache_write_tokens: Integer?, ?cache_read_tokens: Integer?) -> void
|
|
20
|
+
def initialize(input_tokens:, output_tokens:, cache_write_tokens: nil, cache_read_tokens: nil)
|
|
29
21
|
@input_tokens = input_tokens
|
|
30
22
|
@output_tokens = output_tokens
|
|
31
|
-
@
|
|
23
|
+
@cache_write_tokens = cache_write_tokens
|
|
32
24
|
@cache_read_tokens = cache_read_tokens
|
|
33
25
|
end
|
|
34
26
|
|
|
@@ -48,20 +40,17 @@ class Riffer::Providers::TokenUsage
|
|
|
48
40
|
Riffer::Providers::TokenUsage.new(
|
|
49
41
|
input_tokens: input_tokens + other.input_tokens,
|
|
50
42
|
output_tokens: output_tokens + other.output_tokens,
|
|
51
|
-
|
|
43
|
+
cache_write_tokens: add_nullable(cache_write_tokens, other.cache_write_tokens),
|
|
52
44
|
cache_read_tokens: add_nullable(cache_read_tokens, other.cache_read_tokens)
|
|
53
45
|
)
|
|
54
46
|
end
|
|
55
47
|
|
|
56
|
-
# Converts the token usage to a hash
|
|
57
|
-
#
|
|
58
|
-
# Cache tokens are omitted if nil.
|
|
59
|
-
#
|
|
48
|
+
# Converts the token usage to a hash; cache tokens are omitted when nil.
|
|
60
49
|
#--
|
|
61
50
|
#: () -> Hash[Symbol, Integer]
|
|
62
51
|
def to_h
|
|
63
52
|
hash = {input_tokens: input_tokens, output_tokens: output_tokens}
|
|
64
|
-
hash[:
|
|
53
|
+
hash[:cache_write_tokens] = cache_write_tokens if cache_write_tokens
|
|
65
54
|
hash[:cache_read_tokens] = cache_read_tokens if cache_read_tokens
|
|
66
55
|
hash
|
|
67
56
|
end
|
data/lib/riffer/providers.rb
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Namespace for LLM provider adapters in the Riffer framework.
|
|
5
|
-
#
|
|
6
|
-
# Providers connect Riffer to LLM services:
|
|
7
|
-
# - Riffer::Providers::OpenAI - OpenAI GPT models
|
|
8
|
-
# - Riffer::Providers::AzureOpenAI - Azure OpenAI GPT models
|
|
9
|
-
# - Riffer::Providers::AmazonBedrock - AWS Bedrock models
|
|
10
|
-
# - Riffer::Providers::OpenRouter - OpenRouter unified gateway
|
|
11
|
-
# - Riffer::Providers::Mock - Mock provider for testing
|
|
12
4
|
module Riffer::Providers
|
|
13
5
|
end
|
data/lib/riffer/runner/fibers.rb
CHANGED
|
@@ -2,25 +2,12 @@
|
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
4
|
# Processes items concurrently using fibers via the +async+ gem.
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# fibers execute at once.
|
|
9
|
-
#
|
|
10
|
-
# If multiple fibers raise, only the first exception is re-raised
|
|
11
|
-
# after all fibers finish; subsequent errors are discarded.
|
|
12
|
-
#
|
|
13
|
-
# runner = Riffer::Runner::Fibers.new
|
|
14
|
-
# runner.map(items) { |item| expensive_operation(item) }
|
|
15
|
-
#
|
|
5
|
+
# +max_concurrency+ caps simultaneous fibers via an <tt>Async::Semaphore</tt>.
|
|
6
|
+
# If multiple fibers raise, only the first exception is re-raised after all
|
|
7
|
+
# finish.
|
|
16
8
|
class Riffer::Runner::Fibers < Riffer::Runner
|
|
17
9
|
# @rbs @max_concurrency: Integer?
|
|
18
10
|
|
|
19
|
-
include Riffer::Helpers::Dependencies
|
|
20
|
-
|
|
21
|
-
# [max_concurrency] maximum number of fibers to run simultaneously.
|
|
22
|
-
# When +nil+, all fibers run without limit.
|
|
23
|
-
#
|
|
24
11
|
#--
|
|
25
12
|
#: (?max_concurrency: Integer?) -> void
|
|
26
13
|
def initialize(max_concurrency: nil)
|
|
@@ -62,4 +49,11 @@ class Riffer::Runner::Fibers < Riffer::Runner
|
|
|
62
49
|
|
|
63
50
|
results
|
|
64
51
|
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
#: (String) -> true
|
|
56
|
+
def depends_on(gem_name)
|
|
57
|
+
Riffer::Helpers::Dependencies.depends_on(gem_name)
|
|
58
|
+
end
|
|
65
59
|
end
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Processes items sequentially in the current thread.
|
|
5
|
-
#
|
|
6
|
-
# This is the default runner used when no concurrency is needed.
|
|
7
|
-
#
|
|
4
|
+
# Processes items sequentially in the current thread — the default runner.
|
|
8
5
|
class Riffer::Runner::Sequential < Riffer::Runner
|
|
9
6
|
#--
|
|
10
7
|
#: (Array[untyped], context: Riffer::Agent::Context?) { (untyped) -> untyped } -> Array[untyped]
|
|
@@ -1,25 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Processes items concurrently using a thread pool
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# a shared queue. When a worker finishes one item it immediately picks
|
|
8
|
-
# up the next, so a single slow item does not block other workers.
|
|
9
|
-
#
|
|
10
|
-
# If multiple workers raise, only the first exception is re-raised
|
|
11
|
-
# after all workers finish; subsequent errors are discarded.
|
|
12
|
-
#
|
|
13
|
-
# runner = Riffer::Runner::Threaded.new(max_concurrency: 3)
|
|
14
|
-
# runner.map(items) { |item| expensive_operation(item) }
|
|
15
|
-
#
|
|
4
|
+
# Processes items concurrently using a thread pool of up to +max_concurrency+
|
|
5
|
+
# workers pulling from a shared queue, so a slow item doesn't block others. If
|
|
6
|
+
# multiple workers raise, only the first exception is re-raised after all finish.
|
|
16
7
|
class Riffer::Runner::Threaded < Riffer::Runner
|
|
17
8
|
# @rbs @max_concurrency: Integer
|
|
18
9
|
|
|
19
10
|
DEFAULT_MAX_CONCURRENCY = 5 #: Integer
|
|
20
11
|
|
|
21
|
-
# [max_concurrency] maximum number of threads to run simultaneously.
|
|
22
|
-
#
|
|
23
12
|
#--
|
|
24
13
|
#: (?max_concurrency: Integer) -> void
|
|
25
14
|
def initialize(max_concurrency: DEFAULT_MAX_CONCURRENCY)
|
data/lib/riffer/runner.rb
CHANGED
|
@@ -1,23 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Generic concurrency primitive for batch execution.
|
|
5
|
-
#
|
|
6
|
-
# Subclasses implement +map+ to control how items are processed
|
|
7
|
-
# (sequentially, threaded, etc.).
|
|
8
|
-
#
|
|
9
|
-
# runner = Riffer::Runner::Sequential.new
|
|
10
|
-
# runner.map([1, 2, 3], context: ctx) { |n| n * 2 }
|
|
11
|
-
# # => [2, 4, 6]
|
|
12
|
-
#
|
|
4
|
+
# Generic concurrency primitive for batch execution. Subclasses implement
|
|
5
|
+
# +map+ to control how items are processed.
|
|
13
6
|
class Riffer::Runner
|
|
14
7
|
# Maps over items using the provided block.
|
|
15
|
-
#
|
|
16
|
-
# [items] the items to process.
|
|
17
|
-
# [context] context hash forwarded from the agent.
|
|
18
|
-
#
|
|
19
|
-
# Raises NotImplementedError if not implemented by subclass.
|
|
20
|
-
#
|
|
21
8
|
#--
|
|
22
9
|
#: (Array[untyped], context: Riffer::Agent::Context?) { (untyped) -> untyped } -> Array[untyped]
|
|
23
10
|
def map(items, context:, &block)
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Tool
|
|
5
|
-
#
|
|
6
|
-
# Registered automatically when an agent has skills configured.
|
|
7
|
-
# The LLM calls this when a task matches an available skill's description.
|
|
8
|
-
#
|
|
9
|
-
# See Riffer::Skills::Context.
|
|
4
|
+
# Tool the LLM calls to activate a skill and receive its instructions;
|
|
5
|
+
# registered automatically when an agent has skills configured.
|
|
10
6
|
class Riffer::Skills::ActivateTool < Riffer::Tool
|
|
11
7
|
identifier "skill_activate"
|
|
12
8
|
description "Activates a skill and returns its instructions. " \
|
|
@@ -18,11 +14,6 @@ class Riffer::Skills::ActivateTool < Riffer::Tool
|
|
|
18
14
|
end
|
|
19
15
|
|
|
20
16
|
# Activates a skill by name and returns its body.
|
|
21
|
-
#
|
|
22
|
-
# [context] the agent's +Riffer::Agent::Context+, exposing +#skills+
|
|
23
|
-
# (a +Riffer::Skills::Context+).
|
|
24
|
-
# [name] the skill name to activate.
|
|
25
|
-
#
|
|
26
17
|
#--
|
|
27
18
|
#: (context: Riffer::Agent::Context?, name: String) -> Riffer::Tools::Response
|
|
28
19
|
def call(context:, name:)
|
|
@@ -1,27 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
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
|
-
#
|
|
13
|
-
# See Riffer::Skills::MarkdownAdapter for the default implementation.
|
|
14
|
-
# See Riffer::Skills::XmlAdapter for the Anthropic/Claude variant.
|
|
4
|
+
# Interface for skill adapters — provider-specific rendering of the
|
|
5
|
+
# available-skills section in the system prompt. Subclass and override
|
|
6
|
+
# +render_catalog+; the activation tool is exposed via +#skill_activate_tool+
|
|
7
|
+
# for the rendered output.
|
|
15
8
|
class Riffer::Skills::Adapter
|
|
16
9
|
# The activation tool class for this adapter.
|
|
17
10
|
attr_reader :skill_activate_tool #: singleton(Riffer::Tool)
|
|
18
11
|
|
|
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
12
|
#--
|
|
26
13
|
#: (skill_activate_tool: singleton(Riffer::Tool)) -> void
|
|
27
14
|
def initialize(skill_activate_tool:)
|
|
@@ -29,11 +16,6 @@ class Riffer::Skills::Adapter
|
|
|
29
16
|
end
|
|
30
17
|
|
|
31
18
|
# Renders a skill catalog section for the system prompt.
|
|
32
|
-
#
|
|
33
|
-
# [skills] array of Frontmatter objects to render.
|
|
34
|
-
#
|
|
35
|
-
# Raises NotImplementedError if not implemented by subclass.
|
|
36
|
-
#
|
|
37
19
|
#--
|
|
38
20
|
#: (Array[Riffer::Skills::Frontmatter]) -> String
|
|
39
21
|
def render_catalog(skills)
|
|
@@ -1,38 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# custom skill storage (database, S3, etc.).
|
|
8
|
-
#
|
|
9
|
-
# Use Riffer::Skills::Frontmatter.parse to parse raw SKILL.md content.
|
|
10
|
-
#
|
|
11
|
-
# See Riffer::Skills::FilesystemBackend for the built-in implementation.
|
|
4
|
+
# Interface for skill storage backends. Subclass and implement +list_skills+
|
|
5
|
+
# and +read_skill+ for custom storage (database, S3, etc.); use
|
|
6
|
+
# Riffer::Skills::Frontmatter.parse on raw SKILL.md content.
|
|
12
7
|
class Riffer::Skills::Backend
|
|
13
8
|
SKILL_FILENAME = "SKILL.md" #: String
|
|
14
9
|
|
|
15
10
|
def initialize = nil
|
|
16
11
|
|
|
17
|
-
# Returns frontmatter for all available skills
|
|
18
|
-
#
|
|
19
|
-
# Called once at the start of generate/stream.
|
|
20
|
-
#
|
|
21
|
-
# Raises NotImplementedError if not implemented by subclass.
|
|
22
|
-
#
|
|
12
|
+
# Returns frontmatter for all available skills; called once at the start of
|
|
13
|
+
# generate/stream.
|
|
23
14
|
#--
|
|
24
15
|
#: () -> Array[Riffer::Skills::Frontmatter]
|
|
25
16
|
def list_skills
|
|
26
17
|
raise NotImplementedError, "#{self.class} must implement #list_skills"
|
|
27
18
|
end
|
|
28
19
|
|
|
29
|
-
# Returns the full SKILL.md body (without frontmatter) for a skill.
|
|
30
|
-
#
|
|
31
|
-
# [name] the skill name to read.
|
|
32
|
-
#
|
|
33
|
-
# Raises NotImplementedError if not implemented by subclass.
|
|
34
|
-
# Raises Riffer::ArgumentError if skill not found.
|
|
35
|
-
#
|
|
20
|
+
# Returns the full SKILL.md body (without frontmatter) for a skill. Raises
|
|
21
|
+
# Riffer::ArgumentError if the skill is not found.
|
|
36
22
|
#--
|
|
37
23
|
#: (String) -> String
|
|
38
24
|
def read_skill(name)
|
data/lib/riffer/skills/config.rb
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
|
|
4
4
|
# Configuration object for the skills block DSL.
|
|
5
5
|
#
|
|
6
|
-
# Used inside the +skills+ block on Riffer::Agent:
|
|
7
|
-
#
|
|
8
6
|
# skills do
|
|
9
7
|
# backend Riffer::Skills::FilesystemBackend.new(".skills")
|
|
10
8
|
# adapter Riffer::Skills::XmlAdapter
|
|
@@ -16,8 +14,6 @@ class Riffer::Skills::Config
|
|
|
16
14
|
# @rbs @activate: (Array[String] | Proc)?
|
|
17
15
|
# @rbs @activate_tool: singleton(Riffer::Tool)?
|
|
18
16
|
|
|
19
|
-
# Creates a new Config with all options unset.
|
|
20
|
-
#
|
|
21
17
|
#--
|
|
22
18
|
#: () -> void
|
|
23
19
|
def initialize
|
|
@@ -27,11 +23,7 @@ class Riffer::Skills::Config
|
|
|
27
23
|
@activate_tool = nil
|
|
28
24
|
end
|
|
29
25
|
|
|
30
|
-
# Gets or sets the skills backend.
|
|
31
|
-
#
|
|
32
|
-
# Accepts a Riffer::Skills::Backend instance, or a Proc that receives
|
|
33
|
-
# +context+ and returns a Backend.
|
|
34
|
-
#
|
|
26
|
+
# Gets or sets the skills backend (a Backend or a +context+-resolved Proc).
|
|
35
27
|
#--
|
|
36
28
|
#: (?(Riffer::Skills::Backend | Proc)?) -> (Riffer::Skills::Backend | Proc)?
|
|
37
29
|
def backend(value = nil)
|
|
@@ -39,11 +31,8 @@ class Riffer::Skills::Config
|
|
|
39
31
|
@backend = value
|
|
40
32
|
end
|
|
41
33
|
|
|
42
|
-
# Gets or sets a custom skill adapter class
|
|
43
|
-
#
|
|
44
|
-
# Must be a subclass of Riffer::Skills::Adapter.
|
|
45
|
-
# Defaults to the provider's preferred adapter.
|
|
46
|
-
#
|
|
34
|
+
# Gets or sets a custom skill adapter class; defaults to the provider's
|
|
35
|
+
# preferred adapter.
|
|
47
36
|
#--
|
|
48
37
|
#: (?singleton(Riffer::Skills::Adapter)?) -> singleton(Riffer::Skills::Adapter)?
|
|
49
38
|
def adapter(value = nil)
|
|
@@ -51,14 +40,9 @@ class Riffer::Skills::Config
|
|
|
51
40
|
@adapter = value
|
|
52
41
|
end
|
|
53
42
|
|
|
54
|
-
# Gets or sets skill names to activate at startup
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
# without requiring a tool call.
|
|
58
|
-
#
|
|
59
|
-
# Accepts an array of skill name strings or a Proc that receives
|
|
60
|
-
# +context+ and returns an array of names.
|
|
61
|
-
#
|
|
43
|
+
# Gets or sets skill names to activate at startup (an array or a
|
|
44
|
+
# +context+-resolved Proc); activated skills' bodies are included in the
|
|
45
|
+
# system prompt without a tool call.
|
|
62
46
|
#--
|
|
63
47
|
#: (?(Array[String] | Proc)?) -> (Array[String] | Proc)?
|
|
64
48
|
def activate(value = nil)
|
|
@@ -66,15 +50,10 @@ class Riffer::Skills::Config
|
|
|
66
50
|
@activate = value
|
|
67
51
|
end
|
|
68
52
|
|
|
69
|
-
# Gets or sets the per-agent
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
# is applied by the agent at resolution time (see
|
|
74
|
-
# Riffer::Agent#resolve_tools), not by this getter.
|
|
75
|
-
#
|
|
76
|
-
# The override must be a subclass of Riffer::Tool.
|
|
77
|
-
#
|
|
53
|
+
# Gets or sets the per-agent skill activation tool override, or +nil+ when
|
|
54
|
+
# unset — the global fallback to <tt>Riffer.config.skills.default_activate_tool</tt>
|
|
55
|
+
# is applied by the agent at resolution, not here. Raises Riffer::ArgumentError
|
|
56
|
+
# on an invalid value.
|
|
78
57
|
#--
|
|
79
58
|
#: (?singleton(Riffer::Tool)?) -> singleton(Riffer::Tool)?
|
|
80
59
|
def activate_tool(value = nil)
|