riffer 0.48.0 → 0.49.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/.claude/rules/comments.md +2 -4
- data/.claude/rules/rbs-inline.md +2 -12
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +5 -0
- data/CHANGELOG.md +19 -0
- data/docs/AGENTS.md +3 -5
- data/docs/AGENT_LIFECYCLE.md +13 -16
- data/docs/CONFIGURATION.md +22 -33
- data/docs/TOOL_ADVANCED.md +1 -3
- data/docs/TRACING.md +1 -1
- data/docs/providers/AMAZON_BEDROCK.md +31 -0
- data/docs/providers/OPENROUTER.md +18 -1
- data/docs-site/build.rb +0 -6
- data/docs-site/check.rb +1 -5
- data/lib/riffer/agent/config.rb +4 -45
- data/lib/riffer/agent/context.rb +2 -26
- data/lib/riffer/agent/outcome.rb +0 -20
- data/lib/riffer/agent/response.rb +0 -38
- data/lib/riffer/agent/run.rb +11 -43
- data/lib/riffer/agent/serializer.rb +10 -39
- data/lib/riffer/agent/session/repair.rb +3 -15
- data/lib/riffer/agent/session.rb +25 -38
- data/lib/riffer/agent/structured_output/result.rb +0 -8
- data/lib/riffer/agent/structured_output.rb +0 -7
- data/lib/riffer/agent.rb +10 -130
- data/lib/riffer/config/amazon_bedrock.rb +30 -0
- data/lib/riffer/config/anthropic.rb +21 -0
- data/lib/riffer/config/azure_open_ai.rb +30 -0
- data/lib/riffer/config/evals.rb +18 -0
- data/lib/riffer/config/files.rb +61 -0
- data/lib/riffer/config/gemini.rb +21 -0
- data/lib/riffer/config/mcp.rb +31 -0
- data/lib/riffer/config/open_ai.rb +30 -0
- data/lib/riffer/config/open_router.rb +21 -0
- data/lib/riffer/config/pricing/rates.rb +36 -0
- data/lib/riffer/config/pricing.rb +64 -0
- data/lib/riffer/config/skills.rb +38 -0
- data/lib/riffer/config/tracing.rb +43 -0
- data/lib/riffer/config.rb +3 -362
- data/lib/riffer/evals/evaluator.rb +1 -29
- data/lib/riffer/evals/evaluator_runner.rb +0 -15
- data/lib/riffer/evals/judge.rb +0 -8
- data/lib/riffer/evals/result.rb +1 -11
- data/lib/riffer/evals/run_result.rb +0 -12
- data/lib/riffer/evals/scenario_result.rb +0 -19
- data/lib/riffer/files/downloader.rb +2 -3
- data/lib/riffer/files/resolver.rb +2 -7
- data/lib/riffer/guardrail.rb +2 -22
- data/lib/riffer/guardrails/modification.rb +0 -8
- data/lib/riffer/guardrails/result.rb +0 -17
- data/lib/riffer/guardrails/runner.rb +2 -11
- data/lib/riffer/guardrails/tripwire.rb +0 -8
- data/lib/riffer/guardrails.rb +0 -2
- data/lib/riffer/helpers/boolean.rb +0 -4
- data/lib/riffer/helpers/call_or_value.rb +0 -3
- data/lib/riffer/helpers/deep_dup.rb +3 -8
- data/lib/riffer/helpers/dependencies.rb +0 -4
- data/lib/riffer/helpers/identifier.rb +3 -12
- data/lib/riffer/helpers/validate.rb +42 -0
- data/lib/riffer/mcp/authenticated_tool.rb +4 -12
- data/lib/riffer/mcp/client.rb +0 -7
- data/lib/riffer/mcp/manifest.rb +3 -7
- data/lib/riffer/mcp/registration.rb +0 -10
- data/lib/riffer/mcp/registry.rb +0 -9
- data/lib/riffer/mcp/search_tool.rb +0 -4
- data/lib/riffer/mcp/tool.rb +1 -4
- data/lib/riffer/mcp/tool_factory.rb +3 -6
- data/lib/riffer/mcp.rb +2 -23
- data/lib/riffer/messages/assistant/reasoning_part.rb +4 -21
- data/lib/riffer/messages/assistant/tool_call.rb +1 -9
- data/lib/riffer/messages/assistant.rb +1 -21
- data/lib/riffer/messages/base.rb +0 -12
- data/lib/riffer/messages/system.rb +0 -3
- data/lib/riffer/messages/tool.rb +0 -15
- data/lib/riffer/messages/user/file_part.rb +2 -30
- data/lib/riffer/messages/user.rb +0 -4
- data/lib/riffer/params/boolean.rb +1 -5
- data/lib/riffer/params/param.rb +3 -31
- data/lib/riffer/params.rb +8 -41
- data/lib/riffer/providers/amazon_bedrock.rb +101 -42
- data/lib/riffer/providers/anthropic.rb +9 -24
- data/lib/riffer/providers/azure_open_ai.rb +3 -8
- data/lib/riffer/providers/base.rb +7 -28
- data/lib/riffer/providers/finish_reason.rb +0 -6
- data/lib/riffer/providers/gemini/client.rb +4 -17
- data/lib/riffer/providers/gemini.rb +4 -10
- data/lib/riffer/providers/mock.rb +1 -26
- data/lib/riffer/providers/open_ai.rb +7 -17
- data/lib/riffer/providers/open_router.rb +105 -30
- data/lib/riffer/providers/repository.rb +2 -14
- data/lib/riffer/providers/token_usage.rb +5 -14
- data/lib/riffer/registrable.rb +11 -45
- data/lib/riffer/runner/fibers.rb +1 -6
- data/lib/riffer/runner/sequential.rb +0 -1
- data/lib/riffer/runner/threaded.rb +0 -3
- data/lib/riffer/runner.rb +0 -3
- data/lib/riffer/skills/activate_tool.rb +0 -3
- data/lib/riffer/skills/adapter.rb +0 -8
- data/lib/riffer/skills/backend.rb +2 -7
- data/lib/riffer/skills/config.rb +4 -20
- data/lib/riffer/skills/context.rb +0 -29
- data/lib/riffer/skills/filesystem_backend.rb +0 -7
- data/lib/riffer/skills/frontmatter.rb +2 -16
- data/lib/riffer/skills/markdown_adapter.rb +3 -6
- data/lib/riffer/skills/xml_adapter.rb +0 -3
- data/lib/riffer/stream_events/base.rb +0 -3
- data/lib/riffer/stream_events/finish_reason_done.rb +1 -6
- data/lib/riffer/stream_events/guardrail_modification.rb +0 -10
- data/lib/riffer/stream_events/guardrail_tripwire.rb +0 -10
- data/lib/riffer/stream_events/interrupt.rb +2 -12
- data/lib/riffer/stream_events/reasoning_delta.rb +0 -3
- data/lib/riffer/stream_events/reasoning_done.rb +1 -5
- data/lib/riffer/stream_events/skill_activation.rb +0 -3
- data/lib/riffer/stream_events/text_delta.rb +0 -2
- data/lib/riffer/stream_events/text_done.rb +0 -2
- data/lib/riffer/stream_events/token_usage_done.rb +0 -2
- data/lib/riffer/stream_events/tool_call_delta.rb +1 -5
- data/lib/riffer/stream_events/tool_call_done.rb +0 -5
- data/lib/riffer/stream_events/web_search_done.rb +0 -3
- data/lib/riffer/stream_events/web_search_status.rb +1 -5
- data/lib/riffer/testing/minitest.rb +4 -5
- data/lib/riffer/testing.rb +5 -38
- data/lib/riffer/tool.rb +2 -28
- data/lib/riffer/tools/response.rb +3 -32
- data/lib/riffer/tools/runtime/fibers.rb +0 -6
- data/lib/riffer/tools/runtime/inline.rb +0 -1
- data/lib/riffer/tools/runtime/threaded.rb +0 -6
- data/lib/riffer/tools/runtime.rb +5 -26
- data/lib/riffer/tools/toolable.rb +0 -37
- data/lib/riffer/tracing/capture.rb +3 -5
- data/lib/riffer/tracing/no_op.rb +0 -7
- data/lib/riffer/tracing/otel.rb +7 -16
- data/lib/riffer/tracing/stream_recorder.rb +0 -7
- data/lib/riffer/tracing.rb +4 -27
- data/lib/riffer/version.rb +1 -1
- data/lib/riffer.rb +2 -30
- data/sig/generated/riffer/agent/config.rbs +12 -48
- data/sig/generated/riffer/agent/context.rbs +2 -26
- data/sig/generated/riffer/agent/outcome.rbs +0 -20
- data/sig/generated/riffer/agent/response.rbs +1 -29
- data/sig/generated/riffer/agent/run.rbs +1 -27
- data/sig/generated/riffer/agent/serializer.rbs +2 -27
- data/sig/generated/riffer/agent/session/repair.rbs +2 -10
- data/sig/generated/riffer/agent/session.rbs +10 -36
- data/sig/generated/riffer/agent/structured_output/result.rbs +0 -7
- data/sig/generated/riffer/agent/structured_output.rbs +0 -7
- data/sig/generated/riffer/agent.rbs +5 -121
- data/sig/generated/riffer/config/amazon_bedrock.rbs +21 -0
- data/sig/generated/riffer/config/anthropic.rbs +15 -0
- data/sig/generated/riffer/config/azure_open_ai.rbs +21 -0
- data/sig/generated/riffer/config/evals.rbs +13 -0
- data/sig/generated/riffer/config/files.rbs +43 -0
- data/sig/generated/riffer/config/gemini.rbs +15 -0
- data/sig/generated/riffer/config/mcp.rbs +19 -0
- data/sig/generated/riffer/config/open_ai.rbs +21 -0
- data/sig/generated/riffer/config/open_router.rbs +15 -0
- data/sig/generated/riffer/config/pricing/rates.rbs +19 -0
- data/sig/generated/riffer/config/pricing.rbs +31 -0
- data/sig/generated/riffer/config/skills.rbs +19 -0
- data/sig/generated/riffer/config/tracing.rbs +25 -0
- data/sig/generated/riffer/config.rbs +2 -307
- data/sig/generated/riffer/evals/evaluator.rbs +0 -28
- data/sig/generated/riffer/evals/evaluator_runner.rbs +0 -14
- data/sig/generated/riffer/evals/judge.rbs +0 -7
- data/sig/generated/riffer/evals/result.rbs +1 -11
- data/sig/generated/riffer/evals/run_result.rbs +0 -12
- data/sig/generated/riffer/evals/scenario_result.rbs +0 -14
- data/sig/generated/riffer/files/resolver.rbs +0 -7
- data/sig/generated/riffer/guardrail.rbs +2 -22
- data/sig/generated/riffer/guardrails/modification.rbs +0 -6
- data/sig/generated/riffer/guardrails/result.rbs +0 -15
- data/sig/generated/riffer/guardrails/runner.rbs +0 -11
- data/sig/generated/riffer/guardrails/tripwire.rbs +0 -8
- data/sig/generated/riffer/guardrails.rbs +0 -2
- data/sig/generated/riffer/helpers/boolean.rbs +0 -4
- data/sig/generated/riffer/helpers/call_or_value.rbs +0 -3
- data/sig/generated/riffer/helpers/deep_dup.rbs +0 -8
- data/sig/generated/riffer/helpers/dependencies.rbs +0 -4
- data/sig/generated/riffer/helpers/identifier.rbs +0 -12
- data/sig/generated/riffer/helpers/validate.rbs +21 -0
- data/sig/generated/riffer/mcp/authenticated_tool.rbs +0 -5
- data/sig/generated/riffer/mcp/client.rbs +0 -7
- data/sig/generated/riffer/mcp/manifest.rbs +3 -7
- data/sig/generated/riffer/mcp/registration.rbs +0 -10
- data/sig/generated/riffer/mcp/registry.rbs +0 -9
- data/sig/generated/riffer/mcp/search_tool.rbs +0 -4
- data/sig/generated/riffer/mcp/tool.rbs +0 -4
- data/sig/generated/riffer/mcp/tool_factory.rbs +0 -6
- data/sig/generated/riffer/mcp.rbs +2 -22
- data/sig/generated/riffer/messages/assistant/reasoning_part.rbs +4 -17
- data/sig/generated/riffer/messages/assistant/tool_call.rbs +1 -9
- data/sig/generated/riffer/messages/assistant.rbs +10 -30
- data/sig/generated/riffer/messages/base.rbs +0 -12
- data/sig/generated/riffer/messages/system.rbs +0 -3
- data/sig/generated/riffer/messages/tool.rbs +0 -12
- data/sig/generated/riffer/messages/user/file_part.rbs +0 -30
- data/sig/generated/riffer/messages/user.rbs +0 -4
- data/sig/generated/riffer/params/boolean.rbs +1 -4
- data/sig/generated/riffer/params/param.rbs +0 -31
- data/sig/generated/riffer/params.rbs +4 -40
- data/sig/generated/riffer/providers/amazon_bedrock.rbs +29 -25
- data/sig/generated/riffer/providers/anthropic.rbs +0 -10
- data/sig/generated/riffer/providers/azure_open_ai.rbs +0 -8
- data/sig/generated/riffer/providers/base.rbs +0 -28
- data/sig/generated/riffer/providers/finish_reason.rbs +0 -6
- data/sig/generated/riffer/providers/gemini/client.rbs +4 -17
- data/sig/generated/riffer/providers/gemini.rbs +0 -6
- data/sig/generated/riffer/providers/mock.rbs +0 -26
- data/sig/generated/riffer/providers/open_ai.rbs +2 -9
- data/sig/generated/riffer/providers/open_router.rbs +33 -14
- data/sig/generated/riffer/providers/repository.rbs +2 -14
- data/sig/generated/riffer/providers/token_usage.rbs +5 -14
- data/sig/generated/riffer/registrable.rbs +0 -45
- data/sig/generated/riffer/runner/fibers.rbs +0 -6
- data/sig/generated/riffer/runner/sequential.rbs +0 -1
- data/sig/generated/riffer/runner/threaded.rbs +0 -3
- data/sig/generated/riffer/runner.rbs +0 -3
- data/sig/generated/riffer/skills/activate_tool.rbs +0 -3
- data/sig/generated/riffer/skills/adapter.rbs +0 -8
- data/sig/generated/riffer/skills/backend.rbs +2 -7
- data/sig/generated/riffer/skills/config.rbs +0 -20
- data/sig/generated/riffer/skills/context.rbs +0 -29
- data/sig/generated/riffer/skills/filesystem_backend.rbs +0 -7
- data/sig/generated/riffer/skills/frontmatter.rbs +2 -16
- data/sig/generated/riffer/skills/markdown_adapter.rbs +0 -6
- data/sig/generated/riffer/skills/xml_adapter.rbs +0 -3
- data/sig/generated/riffer/stream_events/base.rbs +0 -3
- data/sig/generated/riffer/stream_events/finish_reason_done.rbs +1 -6
- data/sig/generated/riffer/stream_events/guardrail_modification.rbs +0 -10
- data/sig/generated/riffer/stream_events/guardrail_tripwire.rbs +0 -10
- data/sig/generated/riffer/stream_events/interrupt.rbs +2 -10
- data/sig/generated/riffer/stream_events/reasoning_delta.rbs +0 -3
- data/sig/generated/riffer/stream_events/reasoning_done.rbs +1 -5
- data/sig/generated/riffer/stream_events/skill_activation.rbs +0 -3
- data/sig/generated/riffer/stream_events/text_delta.rbs +0 -2
- data/sig/generated/riffer/stream_events/text_done.rbs +0 -2
- data/sig/generated/riffer/stream_events/token_usage_done.rbs +0 -2
- data/sig/generated/riffer/stream_events/tool_call_delta.rbs +1 -5
- data/sig/generated/riffer/stream_events/tool_call_done.rbs +0 -5
- data/sig/generated/riffer/stream_events/web_search_done.rbs +0 -3
- data/sig/generated/riffer/stream_events/web_search_status.rbs +1 -5
- data/sig/generated/riffer/testing.rbs +0 -38
- data/sig/generated/riffer/tool.rbs +0 -27
- data/sig/generated/riffer/tools/response.rbs +3 -29
- data/sig/generated/riffer/tools/runtime/fibers.rbs +0 -5
- data/sig/generated/riffer/tools/runtime/inline.rbs +0 -1
- data/sig/generated/riffer/tools/runtime/threaded.rbs +0 -5
- data/sig/generated/riffer/tools/runtime.rbs +2 -24
- data/sig/generated/riffer/tools/toolable.rbs +0 -37
- data/sig/generated/riffer/tracing/capture.rbs +2 -5
- data/sig/generated/riffer/tracing/no_op.rbs +0 -7
- data/sig/generated/riffer/tracing/otel.rbs +7 -16
- data/sig/generated/riffer/tracing/stream_recorder.rbs +0 -2
- data/sig/generated/riffer/tracing.rbs +4 -23
- data/sig/generated/riffer.rbs +2 -29
- data/sig/manual/riffer/helpers/validate.rbs +5 -0
- metadata +30 -1
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
# Generated from lib/riffer/agent.rb with RBS::Inline
|
|
2
2
|
|
|
3
|
-
# Base class for all agents in the Riffer framework. Subclass it to define an
|
|
4
|
-
# agent's model, instructions, tools, and guardrails.
|
|
5
|
-
#
|
|
6
|
-
# class MyAgent < Riffer::Agent
|
|
7
|
-
# model 'openai/gpt-4o'
|
|
8
|
-
# instructions 'You are a helpful assistant.'
|
|
9
|
-
# end
|
|
10
|
-
#
|
|
11
|
-
# agent = MyAgent.new
|
|
12
|
-
# agent.generate('Hello!')
|
|
13
3
|
class Riffer::Agent
|
|
14
4
|
extend Riffer::Registrable
|
|
15
5
|
|
|
@@ -17,237 +7,131 @@ class Riffer::Agent
|
|
|
17
7
|
|
|
18
8
|
INTERRUPT_MAX_STEPS: Symbol
|
|
19
9
|
|
|
20
|
-
# Returns the per-class Riffer::Agent::Config holding every DSL setting.
|
|
21
10
|
# --
|
|
22
11
|
# : () -> Riffer::Agent::Config
|
|
23
12
|
def self.config: () -> Riffer::Agent::Config
|
|
24
13
|
|
|
25
|
-
# +identifier+ is cleared because it is configuration here but identity on the
|
|
26
|
-
# subclass; two classes claiming one raise Riffer::DuplicateIdentifierError at
|
|
27
|
-
# the next registry lookup.
|
|
28
14
|
# --
|
|
29
15
|
# : (Class) -> void
|
|
30
16
|
def self.inherited: (Class) -> void
|
|
31
17
|
|
|
32
|
-
# Gets or sets the agent identifier.
|
|
33
|
-
#
|
|
34
18
|
# --
|
|
35
19
|
# : (?String?) -> String
|
|
36
20
|
def self.identifier: (?String?) -> String
|
|
37
21
|
|
|
38
|
-
# Gets or sets the model string (e.g., "openai/gpt-4o").
|
|
39
|
-
#
|
|
40
22
|
# --
|
|
41
23
|
# : (?(String | Proc)?) -> (String | Proc)?
|
|
42
24
|
def self.model: (?(String | Proc)?) -> (String | Proc)?
|
|
43
25
|
|
|
44
|
-
# Gets or sets the agent instructions. A Proc is called at generate time with
|
|
45
|
-
# the +context+ hash (which may be +nil+).
|
|
46
|
-
#
|
|
47
|
-
# instructions "You are a helpful assistant."
|
|
48
|
-
#
|
|
49
|
-
# instructions -> (context) {
|
|
50
|
-
# "You are assisting #{context[:name]}"
|
|
51
|
-
# }
|
|
52
|
-
#
|
|
53
26
|
# --
|
|
54
27
|
# : (?(String | Proc)?) -> (String | Proc)?
|
|
55
28
|
def self.instructions: (?(String | Proc)?) -> (String | Proc)?
|
|
56
29
|
|
|
57
|
-
# Gets or sets model options passed to generate_text/stream_text.
|
|
58
|
-
#
|
|
59
30
|
# --
|
|
60
31
|
# : (?Hash[Symbol, untyped]?) -> Hash[Symbol, untyped]
|
|
61
32
|
def self.model_options: (?Hash[Symbol, untyped]?) -> Hash[Symbol, untyped]
|
|
62
33
|
|
|
63
|
-
# Gets or sets the structured output schema for this agent.
|
|
64
34
|
# --
|
|
65
35
|
# : (?Riffer::Params?) ?{ (Riffer::Params) [self: Riffer::Params] -> void } -> Riffer::Params?
|
|
66
36
|
def self.structured_output: (?Riffer::Params?) ?{ (Riffer::Params) [self: Riffer::Params] -> void } -> Riffer::Params?
|
|
67
37
|
|
|
68
|
-
# Gets or sets the maximum number of LLM call steps in the tool-use loop.
|
|
69
|
-
# The splat distinguishes a getter (no argument) from setting the limit to
|
|
70
|
-
# +nil+ (unlimited); it defaults to Riffer::Agent::Config::DEFAULT_MAX_STEPS.
|
|
71
|
-
#
|
|
72
|
-
# max_steps # reads the current limit
|
|
73
|
-
# max_steps 8 # cap the loop at 8 steps
|
|
74
|
-
# max_steps nil # unlimited
|
|
75
|
-
#
|
|
76
38
|
# --
|
|
77
39
|
# : (*Numeric?) -> Numeric?
|
|
78
40
|
def self.max_steps: (*Numeric?) -> Numeric?
|
|
79
41
|
|
|
80
|
-
# Gets or sets the tools used by this agent.
|
|
81
|
-
#
|
|
82
42
|
# --
|
|
83
43
|
# : (?(Array[singleton(Riffer::Tool)] | Proc)?) -> (Array[singleton(Riffer::Tool)] | Proc)?
|
|
84
44
|
def self.uses_tools: (?(Array[singleton(Riffer::Tool)] | Proc)?) -> (Array[singleton(Riffer::Tool)] | Proc)?
|
|
85
45
|
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
46
|
+
# +progressive+ exposes +mcp_search+ instead of every tool schema up front.
|
|
47
|
+
# --
|
|
89
48
|
# : (String | Symbol, ?progressive: bool) -> void
|
|
90
49
|
def self.use_mcp: (String | Symbol, ?progressive: bool) -> void
|
|
91
50
|
|
|
92
|
-
# Returns the accumulated +use_mcp+ configurations for this agent class.
|
|
93
|
-
#
|
|
94
51
|
# : () -> Array[Hash[Symbol, untyped]]
|
|
95
52
|
def self.mcp_configs: () -> Array[Hash[Symbol, untyped]]
|
|
96
53
|
|
|
97
|
-
# Gets or sets the tool runtime for this agent; defaults to
|
|
98
|
-
# <tt>Riffer.config.tool_runtime</tt> when unset.
|
|
99
54
|
# --
|
|
100
55
|
# : (?(singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?) -> (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)
|
|
101
56
|
def self.tool_runtime: (?(singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?) -> (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)
|
|
102
57
|
|
|
103
|
-
# Configures skills for this agent via a block DSL, or returns the current
|
|
104
|
-
# Riffer::Skills::Config when called without a block.
|
|
105
|
-
#
|
|
106
|
-
# skills do
|
|
107
|
-
# backend Riffer::Skills::FilesystemBackend.new(".skills")
|
|
108
|
-
# adapter Riffer::Skills::XmlAdapter
|
|
109
|
-
# activate ["code-review"]
|
|
110
|
-
# end
|
|
111
|
-
#
|
|
112
58
|
# --
|
|
113
59
|
# : () ?{ (Riffer::Skills::Config) [self: Riffer::Skills::Config] -> void } -> Riffer::Skills::Config?
|
|
114
60
|
def self.skills: () ?{ (Riffer::Skills::Config) [self: Riffer::Skills::Config] -> void } -> Riffer::Skills::Config?
|
|
115
61
|
|
|
116
|
-
# Generates a response using a new agent instance.
|
|
117
62
|
# --
|
|
118
63
|
# : (?String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?context: Hash[Symbol, untyped]?, ?tags: Hash[(String | Symbol), untyped]) -> Riffer::Agent::Response
|
|
119
64
|
def self.generate: (?String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?context: Hash[Symbol, untyped]?, ?tags: Hash[String | Symbol, untyped]) -> Riffer::Agent::Response
|
|
120
65
|
|
|
121
|
-
# Streams a response using a new agent instance.
|
|
122
66
|
# --
|
|
123
67
|
# : (?String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?context: Hash[Symbol, untyped]?, ?tags: Hash[(String | Symbol), untyped]) -> Enumerator[Riffer::StreamEvents::Base, Riffer::Agent::Response]
|
|
124
68
|
def self.stream: (?String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?context: Hash[Symbol, untyped]?, ?tags: Hash[String | Symbol, untyped]) -> Enumerator[Riffer::StreamEvents::Base, Riffer::Agent::Response]
|
|
125
69
|
|
|
126
|
-
# Reconstructs a runnable agent from a wire hash produced by +#to_h+.
|
|
127
70
|
# --
|
|
128
71
|
# : (Hash[Symbol, untyped], ?context: Hash[Symbol, untyped]?, ?session: Riffer::Agent::Session?, ?tool_resolver: ^(Hash[Symbol, untyped]) -> singleton(Riffer::Tool), ?tool_runtime: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?) -> Riffer::Agent
|
|
129
72
|
def self.from_h: (Hash[Symbol, untyped], ?context: Hash[Symbol, untyped]?, ?session: Riffer::Agent::Session?, ?tool_resolver: ^(Hash[Symbol, untyped]) -> singleton(Riffer::Tool), ?tool_runtime: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?) -> Riffer::Agent
|
|
130
73
|
|
|
131
|
-
# Reconstructs a runnable agent from a JSON string produced by +#to_json+.
|
|
132
74
|
# --
|
|
133
75
|
# : (String, ?context: Hash[Symbol, untyped]?, ?session: Riffer::Agent::Session?, ?tool_resolver: ^(Hash[Symbol, untyped]) -> singleton(Riffer::Tool), ?tool_runtime: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?) -> Riffer::Agent
|
|
134
76
|
def self.from_json: (String, ?context: Hash[Symbol, untyped]?, ?session: Riffer::Agent::Session?, ?tool_resolver: ^(Hash[Symbol, untyped]) -> singleton(Riffer::Tool), ?tool_runtime: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?) -> Riffer::Agent
|
|
135
77
|
|
|
136
|
-
# Registers a guardrail for input, output, or both phases. Raises
|
|
137
|
-
# Riffer::ArgumentError unless +phase+ is :before, :after, or :around.
|
|
138
78
|
# --
|
|
139
79
|
# : (Symbol, with: singleton(Riffer::Guardrail), **untyped) -> void
|
|
140
80
|
def self.guardrail: (Symbol, with: singleton(Riffer::Guardrail), **untyped) -> void
|
|
141
81
|
|
|
142
|
-
# Returns the registered guardrail configs for a given phase.
|
|
143
82
|
# --
|
|
144
83
|
# : (Symbol) -> Array[Hash[Symbol, untyped]]
|
|
145
84
|
def self.guardrails_for: (Symbol) -> Array[Hash[Symbol, untyped]]
|
|
146
85
|
|
|
147
|
-
# The conversation handle.
|
|
148
86
|
attr_reader session: Riffer::Agent::Session
|
|
149
87
|
|
|
150
|
-
# The per-instance Riffer::Agent::Config.
|
|
151
88
|
attr_reader config: Riffer::Agent::Config
|
|
152
89
|
|
|
153
|
-
# The system message built from the configured +instructions+, or +nil+ when
|
|
154
|
-
# none are configured.
|
|
155
90
|
attr_reader instruction_message: Riffer::Messages::System?
|
|
156
91
|
|
|
157
|
-
# The system message describing the configured skills catalog, or +nil+ when
|
|
158
|
-
# skills are unconfigured or the catalog is empty.
|
|
159
92
|
attr_reader skills_message: Riffer::Messages::System?
|
|
160
93
|
|
|
161
|
-
# The mutable runtime context shared with every +Riffer::Agent::Run+ this
|
|
162
|
-
# agent executes and threaded through all Proc-based settings.
|
|
163
94
|
attr_reader context: Riffer::Agent::Context
|
|
164
95
|
|
|
165
|
-
# The resolved provider name (the part before "/" in the model string),
|
|
166
|
-
# e.g. +"openai"+.
|
|
167
96
|
attr_reader provider_name: String
|
|
168
97
|
|
|
169
|
-
# The resolved model name (the part after "/" in the model string), used as
|
|
170
|
-
# the model argument on every LLM call.
|
|
171
98
|
attr_reader model_name: String
|
|
172
99
|
|
|
173
|
-
#
|
|
174
|
-
# +Riffer::Providers::Mock+ before calling +#generate+.
|
|
100
|
+
# Public so tests can pre-queue responses on Riffer::Providers::Mock.
|
|
175
101
|
attr_reader provider: Riffer::Providers::Base
|
|
176
102
|
|
|
177
|
-
# The +Riffer::Agent::StructuredOutput+ wrapping the configured schema, or
|
|
178
|
-
# +nil+ when not configured.
|
|
179
103
|
attr_reader structured_output: Riffer::Agent::StructuredOutput?
|
|
180
104
|
|
|
181
|
-
# The tool classes the LLM sees on every call this agent makes.
|
|
182
105
|
attr_reader tools: Array[singleton(Riffer::Tool)]
|
|
183
106
|
|
|
184
|
-
# The tool runtime instance used to execute tool calls.
|
|
185
107
|
attr_reader tool_runtime: Riffer::Tools::Runtime
|
|
186
108
|
|
|
187
|
-
# Initializes a new agent.
|
|
188
|
-
#
|
|
189
|
-
# A provided +session:+ is used as-is — the caller owns its contents (e.g.
|
|
190
|
-
# cross-process resume from persisted history); an omitted one is seeded with
|
|
191
|
-
# the instruction and skills messages.
|
|
192
|
-
#
|
|
193
|
-
# Raises Riffer::ArgumentError unless the configured model string is
|
|
194
|
-
# "provider/model" format.
|
|
195
|
-
#
|
|
196
109
|
# --
|
|
197
110
|
# : (?session: Riffer::Agent::Session?, ?context: Hash[Symbol, untyped]?, ?config: Riffer::Agent::Config?) -> void
|
|
198
111
|
def initialize: (?session: Riffer::Agent::Session?, ?context: Hash[Symbol, untyped]?, ?config: Riffer::Agent::Config?) -> void
|
|
199
112
|
|
|
200
|
-
# The identifier for this agent: the instance config's identifier when set
|
|
201
|
-
# (e.g. an agent restored with +Riffer::Agent.from_h+), otherwise the class
|
|
202
|
-
# identifier.
|
|
203
|
-
#
|
|
204
113
|
# --
|
|
205
114
|
# : () -> String
|
|
206
115
|
def identifier: () -> String
|
|
207
116
|
|
|
208
|
-
# Generates a response from the agent.
|
|
209
|
-
#
|
|
210
|
-
# With +prompt+, a new user message is appended (silently — +on_message+ does
|
|
211
|
-
# not fire for user inputs) before the loop runs. Without it, the loop runs
|
|
212
|
-
# against the current session, resuming a persisted conversation or pending
|
|
213
|
-
# tool calls. +files:+ requires +prompt+.
|
|
214
|
-
#
|
|
215
|
-
# +tags:+ is an optional flat hash of attribution tags applied to this single
|
|
216
|
-
# call: they propagate to the provider's native request-metadata field, and
|
|
217
|
-
# are stamped as +riffer.tag.*+ on every span the call emits. See
|
|
218
|
-
# +docs/AGENTS.md+ for the per-provider mapping. The reserved key
|
|
219
|
-
# +user_id+ also maps to the provider's native user identifier where one
|
|
220
|
-
# exists. Riffer adds the default tags +kind+ (+"agent"+) and +agent+ (the
|
|
221
|
-
# agent identifier); a caller tag with the same key wins.
|
|
222
|
-
#
|
|
223
117
|
# --
|
|
224
118
|
# : (?String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?tags: Hash[(String | Symbol), untyped]) -> Riffer::Agent::Response
|
|
225
119
|
def generate: (?String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?tags: Hash[String | Symbol, untyped]) -> Riffer::Agent::Response
|
|
226
120
|
|
|
227
|
-
# Streams a response from the agent as an +Enumerator+ of
|
|
228
|
-
# +Riffer::StreamEvents+ whose block-form +each+ returns the final
|
|
229
|
-
# Riffer::Agent::Response. See +#generate+ for prompt/files/tags semantics.
|
|
230
|
-
#
|
|
231
|
-
# Raises Riffer::ArgumentError if structured output is configured.
|
|
232
|
-
#
|
|
233
121
|
# --
|
|
234
122
|
# : (?String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?tags: Hash[(String | Symbol), untyped]) -> Enumerator[Riffer::StreamEvents::Base, Riffer::Agent::Response]
|
|
235
123
|
def stream: (?String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?tags: Hash[String | Symbol, untyped]) -> Enumerator[Riffer::StreamEvents::Base, Riffer::Agent::Response]
|
|
236
124
|
|
|
237
|
-
# Interrupts the agent loop from an +on_message+ callback. Equivalent to
|
|
238
|
-
# <tt>throw :riffer_interrupt, reason</tt>.
|
|
239
125
|
# --
|
|
240
126
|
# : (?(String | Symbol)?) -> void
|
|
241
127
|
def interrupt!: (?(String | Symbol)?) -> void
|
|
242
128
|
|
|
243
|
-
# Snapshots this resolved agent into a self-contained, provider-neutral wire
|
|
244
|
-
# hash.
|
|
245
129
|
# --
|
|
246
130
|
# : () -> Hash[Symbol, untyped]
|
|
247
131
|
def to_h: () -> Hash[Symbol, untyped]
|
|
248
132
|
|
|
249
|
-
#
|
|
250
|
-
#
|
|
133
|
+
# The +*+ absorbs JSON's generator-state argument so
|
|
134
|
+
# <tt>JSON.generate(agent)</tt> works.
|
|
251
135
|
# --
|
|
252
136
|
# : (*untyped) -> String
|
|
253
137
|
def to_json: (*untyped) -> String
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/amazon_bedrock.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::AmazonBedrock
|
|
4
|
+
attr_reader api_token: String?
|
|
5
|
+
|
|
6
|
+
attr_reader region: String?
|
|
7
|
+
|
|
8
|
+
attr_accessor client: untyped
|
|
9
|
+
|
|
10
|
+
# --
|
|
11
|
+
# : () -> void
|
|
12
|
+
def initialize: () -> void
|
|
13
|
+
|
|
14
|
+
# --
|
|
15
|
+
# : (untyped) -> void
|
|
16
|
+
def api_token=: (untyped) -> void
|
|
17
|
+
|
|
18
|
+
# --
|
|
19
|
+
# : (untyped) -> void
|
|
20
|
+
def region=: (untyped) -> void
|
|
21
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/anthropic.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::Anthropic
|
|
4
|
+
attr_reader api_key: String?
|
|
5
|
+
|
|
6
|
+
attr_accessor client: untyped
|
|
7
|
+
|
|
8
|
+
# --
|
|
9
|
+
# : () -> void
|
|
10
|
+
def initialize: () -> void
|
|
11
|
+
|
|
12
|
+
# --
|
|
13
|
+
# : (untyped) -> void
|
|
14
|
+
def api_key=: (untyped) -> void
|
|
15
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/azure_open_ai.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::AzureOpenAI
|
|
4
|
+
attr_reader api_key: String?
|
|
5
|
+
|
|
6
|
+
attr_reader endpoint: String?
|
|
7
|
+
|
|
8
|
+
attr_accessor client: untyped
|
|
9
|
+
|
|
10
|
+
# --
|
|
11
|
+
# : () -> void
|
|
12
|
+
def initialize: () -> void
|
|
13
|
+
|
|
14
|
+
# --
|
|
15
|
+
# : (untyped) -> void
|
|
16
|
+
def api_key=: (untyped) -> void
|
|
17
|
+
|
|
18
|
+
# --
|
|
19
|
+
# : (untyped) -> void
|
|
20
|
+
def endpoint=: (untyped) -> void
|
|
21
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/evals.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::Evals
|
|
4
|
+
attr_reader judge_model: String?
|
|
5
|
+
|
|
6
|
+
# --
|
|
7
|
+
# : () -> void
|
|
8
|
+
def initialize: () -> void
|
|
9
|
+
|
|
10
|
+
# --
|
|
11
|
+
# : (untyped) -> void
|
|
12
|
+
def judge_model=: (untyped) -> void
|
|
13
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/files.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::Files
|
|
4
|
+
attr_reader allow_downloads: bool
|
|
5
|
+
|
|
6
|
+
attr_reader max_bytes: Integer
|
|
7
|
+
|
|
8
|
+
attr_reader timeout: Integer
|
|
9
|
+
|
|
10
|
+
attr_reader max_per_message: Integer?
|
|
11
|
+
|
|
12
|
+
attr_reader runner: Riffer::Runner
|
|
13
|
+
|
|
14
|
+
attr_reader downloader: untyped
|
|
15
|
+
|
|
16
|
+
# --
|
|
17
|
+
# : () -> void
|
|
18
|
+
def initialize: () -> void
|
|
19
|
+
|
|
20
|
+
# --
|
|
21
|
+
# : (untyped) -> void
|
|
22
|
+
def allow_downloads=: (untyped) -> void
|
|
23
|
+
|
|
24
|
+
# --
|
|
25
|
+
# : (untyped) -> void
|
|
26
|
+
def max_bytes=: (untyped) -> void
|
|
27
|
+
|
|
28
|
+
# --
|
|
29
|
+
# : (untyped) -> void
|
|
30
|
+
def timeout=: (untyped) -> void
|
|
31
|
+
|
|
32
|
+
# --
|
|
33
|
+
# : (untyped) -> void
|
|
34
|
+
def max_per_message=: (untyped) -> void
|
|
35
|
+
|
|
36
|
+
# --
|
|
37
|
+
# : (untyped) -> void
|
|
38
|
+
def runner=: (untyped) -> void
|
|
39
|
+
|
|
40
|
+
# --
|
|
41
|
+
# : (untyped) -> void
|
|
42
|
+
def downloader=: (untyped) -> void
|
|
43
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/gemini.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::Gemini
|
|
4
|
+
attr_reader api_key: String?
|
|
5
|
+
|
|
6
|
+
attr_accessor client: untyped
|
|
7
|
+
|
|
8
|
+
# --
|
|
9
|
+
# : () -> void
|
|
10
|
+
def initialize: () -> void
|
|
11
|
+
|
|
12
|
+
# --
|
|
13
|
+
# : (untyped) -> void
|
|
14
|
+
def api_key=: (untyped) -> void
|
|
15
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/mcp.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::Mcp
|
|
4
|
+
attr_reader credentials: untyped
|
|
5
|
+
|
|
6
|
+
attr_reader discovery_runner: Riffer::Runner
|
|
7
|
+
|
|
8
|
+
# --
|
|
9
|
+
# : () -> void
|
|
10
|
+
def initialize: () -> void
|
|
11
|
+
|
|
12
|
+
# --
|
|
13
|
+
# : (untyped) -> void
|
|
14
|
+
def credentials=: (untyped) -> void
|
|
15
|
+
|
|
16
|
+
# --
|
|
17
|
+
# : (untyped) -> void
|
|
18
|
+
def discovery_runner=: (untyped) -> void
|
|
19
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/open_ai.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::OpenAI
|
|
4
|
+
attr_reader api_key: String?
|
|
5
|
+
|
|
6
|
+
attr_reader base_url: String?
|
|
7
|
+
|
|
8
|
+
attr_accessor client: untyped
|
|
9
|
+
|
|
10
|
+
# --
|
|
11
|
+
# : () -> void
|
|
12
|
+
def initialize: () -> void
|
|
13
|
+
|
|
14
|
+
# --
|
|
15
|
+
# : (untyped) -> void
|
|
16
|
+
def api_key=: (untyped) -> void
|
|
17
|
+
|
|
18
|
+
# --
|
|
19
|
+
# : (untyped) -> void
|
|
20
|
+
def base_url=: (untyped) -> void
|
|
21
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/open_router.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::OpenRouter
|
|
4
|
+
attr_reader api_key: String?
|
|
5
|
+
|
|
6
|
+
attr_accessor client: untyped
|
|
7
|
+
|
|
8
|
+
# --
|
|
9
|
+
# : () -> void
|
|
10
|
+
def initialize: () -> void
|
|
11
|
+
|
|
12
|
+
# --
|
|
13
|
+
# : (untyped) -> void
|
|
14
|
+
def api_key=: (untyped) -> void
|
|
15
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/pricing/rates.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::Pricing::Rates
|
|
4
|
+
attr_reader input: Float
|
|
5
|
+
|
|
6
|
+
attr_reader output: Float
|
|
7
|
+
|
|
8
|
+
attr_reader cache_read: Float?
|
|
9
|
+
|
|
10
|
+
attr_reader cache_write: Float?
|
|
11
|
+
|
|
12
|
+
# --
|
|
13
|
+
# : (input: Float, output: Float, ?cache_read: Float?, ?cache_write: Float?) -> void
|
|
14
|
+
def initialize: (input: Float, output: Float, ?cache_read: Float?, ?cache_write: Float?) -> void
|
|
15
|
+
|
|
16
|
+
# --
|
|
17
|
+
# : (input_tokens: Integer, output_tokens: Integer, ?cache_read_tokens: Integer?, ?cache_write_tokens: Integer?) -> Float
|
|
18
|
+
def cost_for: (input_tokens: Integer, output_tokens: Integer, ?cache_read_tokens: Integer?, ?cache_write_tokens: Integer?) -> Float
|
|
19
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/pricing.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::Pricing
|
|
4
|
+
@rates: Hash[String, Riffer::Config::Pricing::Rates]
|
|
5
|
+
|
|
6
|
+
# --
|
|
7
|
+
# : () -> void
|
|
8
|
+
def initialize: () -> void
|
|
9
|
+
|
|
10
|
+
# --
|
|
11
|
+
# : ((String | Array[String]), input: Numeric, output: Numeric, ?cache_read: Numeric?, ?cache_write: Numeric?) -> void
|
|
12
|
+
def set: (String | Array[String], input: Numeric, output: Numeric, ?cache_read: Numeric?, ?cache_write: Numeric?) -> void
|
|
13
|
+
|
|
14
|
+
# --
|
|
15
|
+
# : (String) -> Riffer::Config::Pricing::Rates?
|
|
16
|
+
def rates_for: (String) -> Riffer::Config::Pricing::Rates?
|
|
17
|
+
|
|
18
|
+
# --
|
|
19
|
+
# : () -> bool
|
|
20
|
+
def empty?: () -> bool
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
# --
|
|
25
|
+
# : (untyped, String) -> Float
|
|
26
|
+
def coerce_rate: (untyped, String) -> Float
|
|
27
|
+
|
|
28
|
+
# --
|
|
29
|
+
# : (untyped, String) -> Float?
|
|
30
|
+
def coerce_optional_rate: (untyped, String) -> Float?
|
|
31
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/skills.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::Skills
|
|
4
|
+
attr_reader default_activate_tool: singleton(Riffer::Tool)
|
|
5
|
+
|
|
6
|
+
attr_reader default_backend: (Riffer::Skills::Backend | Proc)?
|
|
7
|
+
|
|
8
|
+
# --
|
|
9
|
+
# : () -> void
|
|
10
|
+
def initialize: () -> void
|
|
11
|
+
|
|
12
|
+
# --
|
|
13
|
+
# : (singleton(Riffer::Tool)) -> void
|
|
14
|
+
def default_activate_tool=: (singleton(Riffer::Tool)) -> void
|
|
15
|
+
|
|
16
|
+
# --
|
|
17
|
+
# : ((Riffer::Skills::Backend | Proc)?) -> void
|
|
18
|
+
def default_backend=: ((Riffer::Skills::Backend | Proc)?) -> void
|
|
19
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Generated from lib/riffer/config/tracing.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class Riffer::Config::Tracing
|
|
4
|
+
attr_reader enabled: bool
|
|
5
|
+
|
|
6
|
+
attr_reader capture_messages: bool
|
|
7
|
+
|
|
8
|
+
attr_reader backend: untyped
|
|
9
|
+
|
|
10
|
+
# --
|
|
11
|
+
# : () -> void
|
|
12
|
+
def initialize: () -> void
|
|
13
|
+
|
|
14
|
+
# --
|
|
15
|
+
# : (untyped) -> void
|
|
16
|
+
def enabled=: (untyped) -> void
|
|
17
|
+
|
|
18
|
+
# --
|
|
19
|
+
# : (untyped) -> void
|
|
20
|
+
def capture_messages=: (untyped) -> void
|
|
21
|
+
|
|
22
|
+
# --
|
|
23
|
+
# : (untyped) -> void
|
|
24
|
+
def backend=: (untyped) -> void
|
|
25
|
+
end
|