riffer 0.30.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.
Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/.agents/code-style.md +63 -4
  3. data/.agents/rbs-inline.md +1 -6
  4. data/.release-please-manifest.json +1 -1
  5. data/AGENTS.md +1 -2
  6. data/CHANGELOG.md +25 -0
  7. data/docs/08_MESSAGES.md +1 -1
  8. data/docs/14_MCP.md +50 -5
  9. data/docs/15_SERIALIZATION.md +23 -12
  10. data/docs/providers/02_AMAZON_BEDROCK.md +14 -0
  11. data/lib/riffer/agent/config.rb +42 -47
  12. data/lib/riffer/agent/context.rb +70 -50
  13. data/lib/riffer/agent/response.rb +4 -20
  14. data/lib/riffer/agent/run.rb +28 -67
  15. data/lib/riffer/agent/serializer.rb +36 -85
  16. data/lib/riffer/agent/session/repair.rb +14 -40
  17. data/lib/riffer/agent/session.rb +25 -67
  18. data/lib/riffer/agent/structured_output/result.rb +3 -11
  19. data/lib/riffer/agent/structured_output.rb +5 -13
  20. data/lib/riffer/agent.rb +81 -199
  21. data/lib/riffer/config.rb +34 -101
  22. data/lib/riffer/evals/evaluator.rb +7 -27
  23. data/lib/riffer/evals/evaluator_runner.rb +11 -19
  24. data/lib/riffer/evals/judge.rb +4 -25
  25. data/lib/riffer/evals/result.rb +1 -18
  26. data/lib/riffer/evals/run_result.rb +0 -11
  27. data/lib/riffer/evals/scenario_result.rb +0 -14
  28. data/lib/riffer/evals.rb +0 -6
  29. data/lib/riffer/guardrail.rb +4 -27
  30. data/lib/riffer/guardrails/modification.rb +0 -10
  31. data/lib/riffer/guardrails/result.rb +3 -30
  32. data/lib/riffer/guardrails/runner.rb +5 -22
  33. data/lib/riffer/guardrails/tripwire.rb +1 -19
  34. data/lib/riffer/guardrails.rb +2 -4
  35. data/lib/riffer/helpers/call_or_value.rb +4 -3
  36. data/lib/riffer/helpers/class_name_converter.rb +3 -1
  37. data/lib/riffer/helpers/dependencies.rb +5 -7
  38. data/lib/riffer/helpers.rb +0 -5
  39. data/lib/riffer/mcp/authenticated_tool.rb +9 -9
  40. data/lib/riffer/mcp/client.rb +12 -17
  41. data/lib/riffer/mcp/manifest.rb +13 -10
  42. data/lib/riffer/mcp/registration.rb +2 -11
  43. data/lib/riffer/mcp/registry.rb +44 -52
  44. data/lib/riffer/mcp/search_tool.rb +53 -0
  45. data/lib/riffer/mcp/tool_factory.rb +13 -18
  46. data/lib/riffer/mcp.rb +12 -17
  47. data/lib/riffer/messages/assistant.rb +2 -9
  48. data/lib/riffer/messages/base.rb +46 -16
  49. data/lib/riffer/messages/file_part.rb +32 -24
  50. data/lib/riffer/messages/system.rb +0 -5
  51. data/lib/riffer/messages/tool.rb +0 -10
  52. data/lib/riffer/messages/user.rb +0 -10
  53. data/lib/riffer/messages.rb +0 -7
  54. data/lib/riffer/params/boolean.rb +2 -4
  55. data/lib/riffer/params/param.rb +28 -39
  56. data/lib/riffer/params.rb +9 -21
  57. data/lib/riffer/providers/amazon_bedrock.rb +42 -28
  58. data/lib/riffer/providers/anthropic.rb +4 -9
  59. data/lib/riffer/providers/azure_open_ai.rb +3 -19
  60. data/lib/riffer/providers/base.rb +13 -26
  61. data/lib/riffer/providers/gemini.rb +4 -4
  62. data/lib/riffer/providers/mock.rb +6 -26
  63. data/lib/riffer/providers/open_ai.rb +6 -8
  64. data/lib/riffer/providers/open_router.rb +4 -10
  65. data/lib/riffer/providers/repository.rb +4 -3
  66. data/lib/riffer/providers/token_usage.rb +9 -20
  67. data/lib/riffer/providers.rb +0 -8
  68. data/lib/riffer/runner/fibers.rb +10 -16
  69. data/lib/riffer/runner/sequential.rb +1 -4
  70. data/lib/riffer/runner/threaded.rb +3 -14
  71. data/lib/riffer/runner.rb +2 -15
  72. data/lib/riffer/skills/activate_tool.rb +2 -11
  73. data/lib/riffer/skills/adapter.rb +4 -22
  74. data/lib/riffer/skills/backend.rb +7 -21
  75. data/lib/riffer/skills/config.rb +10 -31
  76. data/lib/riffer/skills/context.rb +5 -20
  77. data/lib/riffer/skills/filesystem_backend.rb +7 -25
  78. data/lib/riffer/skills/frontmatter.rb +10 -28
  79. data/lib/riffer/skills/markdown_adapter.rb +2 -9
  80. data/lib/riffer/skills/xml_adapter.rb +2 -8
  81. data/lib/riffer/stream_events/base.rb +1 -6
  82. data/lib/riffer/stream_events/guardrail_modification.rb +1 -8
  83. data/lib/riffer/stream_events/guardrail_tripwire.rb +1 -8
  84. data/lib/riffer/stream_events/interrupt.rb +4 -7
  85. data/lib/riffer/stream_events/reasoning_delta.rb +2 -4
  86. data/lib/riffer/stream_events/reasoning_done.rb +2 -4
  87. data/lib/riffer/stream_events/skill_activation.rb +2 -4
  88. data/lib/riffer/stream_events/text_delta.rb +0 -2
  89. data/lib/riffer/stream_events/text_done.rb +1 -3
  90. data/lib/riffer/stream_events/token_usage_done.rb +1 -8
  91. data/lib/riffer/stream_events/tool_call_delta.rb +2 -3
  92. data/lib/riffer/stream_events/tool_call_done.rb +1 -3
  93. data/lib/riffer/stream_events/web_search_done.rb +1 -3
  94. data/lib/riffer/stream_events/web_search_status.rb +2 -3
  95. data/lib/riffer/stream_events.rb +0 -10
  96. data/lib/riffer/tool.rb +6 -13
  97. data/lib/riffer/tools/response.rb +8 -4
  98. data/lib/riffer/tools/runtime/fibers.rb +0 -3
  99. data/lib/riffer/tools/runtime/inline.rb +1 -4
  100. data/lib/riffer/tools/runtime/threaded.rb +0 -2
  101. data/lib/riffer/tools/runtime.rb +5 -38
  102. data/lib/riffer/tools/toolable.rb +5 -16
  103. data/lib/riffer/tools.rb +0 -4
  104. data/lib/riffer/version.rb +1 -1
  105. data/lib/riffer.rb +7 -8
  106. data/sig/generated/riffer/agent/config.rbs +29 -46
  107. data/sig/generated/riffer/agent/context.rbs +40 -48
  108. data/sig/generated/riffer/agent/response.rbs +4 -20
  109. data/sig/generated/riffer/agent/run.rbs +12 -61
  110. data/sig/generated/riffer/agent/serializer.rbs +28 -81
  111. data/sig/generated/riffer/agent/session/repair.rbs +12 -40
  112. data/sig/generated/riffer/agent/session.rbs +25 -67
  113. data/sig/generated/riffer/agent/structured_output/result.rbs +2 -10
  114. data/sig/generated/riffer/agent/structured_output.rbs +5 -12
  115. data/sig/generated/riffer/agent.rbs +62 -191
  116. data/sig/generated/riffer/config.rbs +34 -100
  117. data/sig/generated/riffer/evals/evaluator.rbs +7 -27
  118. data/sig/generated/riffer/evals/evaluator_runner.rbs +9 -19
  119. data/sig/generated/riffer/evals/judge.rbs +4 -24
  120. data/sig/generated/riffer/evals/result.rbs +1 -17
  121. data/sig/generated/riffer/evals/run_result.rbs +0 -10
  122. data/sig/generated/riffer/evals/scenario_result.rbs +0 -13
  123. data/sig/generated/riffer/evals.rbs +0 -6
  124. data/sig/generated/riffer/guardrail.rbs +4 -27
  125. data/sig/generated/riffer/guardrails/modification.rbs +0 -10
  126. data/sig/generated/riffer/guardrails/result.rbs +3 -30
  127. data/sig/generated/riffer/guardrails/runner.rbs +5 -22
  128. data/sig/generated/riffer/guardrails/tripwire.rbs +1 -19
  129. data/sig/generated/riffer/guardrails.rbs +2 -4
  130. data/sig/generated/riffer/helpers/call_or_value.rbs +4 -3
  131. data/sig/generated/riffer/helpers/class_name_converter.rbs +1 -1
  132. data/sig/generated/riffer/helpers/dependencies.rbs +3 -7
  133. data/sig/generated/riffer/helpers.rbs +0 -5
  134. data/sig/generated/riffer/mcp/authenticated_tool.rbs +5 -4
  135. data/sig/generated/riffer/mcp/client.rbs +10 -16
  136. data/sig/generated/riffer/mcp/manifest.rbs +9 -9
  137. data/sig/generated/riffer/mcp/registration.rbs +2 -10
  138. data/sig/generated/riffer/mcp/registry.rbs +11 -18
  139. data/sig/generated/riffer/mcp/search_tool.rbs +26 -0
  140. data/sig/generated/riffer/mcp/tool_factory.rbs +10 -15
  141. data/sig/generated/riffer/mcp.rbs +10 -17
  142. data/sig/generated/riffer/messages/assistant.rbs +2 -8
  143. data/sig/generated/riffer/messages/base.rbs +11 -16
  144. data/sig/generated/riffer/messages/file_part.rbs +13 -23
  145. data/sig/generated/riffer/messages/system.rbs +0 -4
  146. data/sig/generated/riffer/messages/tool.rbs +0 -9
  147. data/sig/generated/riffer/messages/user.rbs +0 -9
  148. data/sig/generated/riffer/messages.rbs +0 -7
  149. data/sig/generated/riffer/params/boolean.rbs +2 -4
  150. data/sig/generated/riffer/params/param.rbs +21 -39
  151. data/sig/generated/riffer/params.rbs +9 -21
  152. data/sig/generated/riffer/providers/amazon_bedrock.rbs +21 -25
  153. data/sig/generated/riffer/providers/anthropic.rbs +2 -7
  154. data/sig/generated/riffer/providers/azure_open_ai.rbs +3 -18
  155. data/sig/generated/riffer/providers/base.rbs +9 -25
  156. data/sig/generated/riffer/providers/gemini.rbs +0 -2
  157. data/sig/generated/riffer/providers/mock.rbs +6 -26
  158. data/sig/generated/riffer/providers/open_ai.rbs +1 -5
  159. data/sig/generated/riffer/providers/open_router.rbs +4 -10
  160. data/sig/generated/riffer/providers/repository.rbs +2 -3
  161. data/sig/generated/riffer/providers/token_usage.rbs +6 -16
  162. data/sig/generated/riffer/providers.rbs +0 -8
  163. data/sig/generated/riffer/runner/fibers.rbs +8 -15
  164. data/sig/generated/riffer/runner/sequential.rbs +1 -3
  165. data/sig/generated/riffer/runner/threaded.rbs +3 -13
  166. data/sig/generated/riffer/runner.rbs +2 -14
  167. data/sig/generated/riffer/skills/activate_tool.rbs +2 -11
  168. data/sig/generated/riffer/skills/adapter.rbs +4 -22
  169. data/sig/generated/riffer/skills/backend.rbs +7 -21
  170. data/sig/generated/riffer/skills/config.rbs +10 -31
  171. data/sig/generated/riffer/skills/context.rbs +5 -20
  172. data/sig/generated/riffer/skills/filesystem_backend.rbs +7 -24
  173. data/sig/generated/riffer/skills/frontmatter.rbs +10 -27
  174. data/sig/generated/riffer/skills/markdown_adapter.rbs +2 -9
  175. data/sig/generated/riffer/skills/xml_adapter.rbs +2 -8
  176. data/sig/generated/riffer/stream_events/base.rbs +1 -6
  177. data/sig/generated/riffer/stream_events/guardrail_modification.rbs +1 -8
  178. data/sig/generated/riffer/stream_events/guardrail_tripwire.rbs +1 -8
  179. data/sig/generated/riffer/stream_events/interrupt.rbs +4 -7
  180. data/sig/generated/riffer/stream_events/reasoning_delta.rbs +2 -4
  181. data/sig/generated/riffer/stream_events/reasoning_done.rbs +2 -4
  182. data/sig/generated/riffer/stream_events/skill_activation.rbs +2 -4
  183. data/sig/generated/riffer/stream_events/text_delta.rbs +0 -2
  184. data/sig/generated/riffer/stream_events/text_done.rbs +1 -3
  185. data/sig/generated/riffer/stream_events/token_usage_done.rbs +1 -7
  186. data/sig/generated/riffer/stream_events/tool_call_delta.rbs +2 -3
  187. data/sig/generated/riffer/stream_events/tool_call_done.rbs +1 -3
  188. data/sig/generated/riffer/stream_events/web_search_done.rbs +1 -3
  189. data/sig/generated/riffer/stream_events/web_search_status.rbs +2 -3
  190. data/sig/generated/riffer/stream_events.rbs +0 -10
  191. data/sig/generated/riffer/tool.rbs +5 -12
  192. data/sig/generated/riffer/tools/response.rbs +6 -4
  193. data/sig/generated/riffer/tools/runtime/fibers.rbs +0 -3
  194. data/sig/generated/riffer/tools/runtime/inline.rbs +1 -3
  195. data/sig/generated/riffer/tools/runtime/threaded.rbs +0 -2
  196. data/sig/generated/riffer/tools/runtime.rbs +5 -37
  197. data/sig/generated/riffer/tools/toolable.rbs +4 -14
  198. data/sig/generated/riffer/tools.rbs +0 -4
  199. data/sig/generated/riffer.rbs +5 -4
  200. data/sig/manual/riffer/agent/session/repair.rbs +5 -0
  201. data/sig/manual/riffer/evals/evaluator_runner.rbs +5 -0
  202. data/sig/manual/riffer/helpers/class_name_converter.rbs +5 -0
  203. data/sig/manual/riffer/helpers/dependencies.rbs +5 -0
  204. data/sig/manual/riffer/mcp/authenticated_tool.rbs +5 -0
  205. data/sig/manual/riffer/mcp/registry.rbs +5 -0
  206. data/sig/manual/riffer/mcp/tool_factory.rbs +5 -0
  207. data/sig/manual/riffer/mcp.rbs +5 -0
  208. data/sig/manual/riffer/providers/repository.rbs +5 -0
  209. data/sig/manual/riffer.rbs +5 -0
  210. metadata +17 -9
  211. data/.agents/rdoc.md +0 -69
  212. data/lib/riffer/messages/converter.rb +0 -90
  213. data/sig/generated/riffer/messages/converter.rbs +0 -33
  214. data/sig/manual/riffer/tools/toolable.rbs +0 -6
@@ -1,16 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
  # rbs_inline: enabled
3
3
 
4
- # Riffer::Tools::Toolable provides the shared class-level DSL for anything that can
5
- # present as a tool to an LLM tools today, and subagents/workflows in the
6
- # future.
7
- #
8
- # Extend this module to make a class discoverable as a tool by LLM providers.
9
- # Provides identifier, description, params, timeout, and JSON schema
10
- # generation.
11
- #
12
- # Instance-level execution concerns (+call+, +call_with_validation+, etc.)
13
- # are NOT part of Toolable — those belong on Riffer::Tool.
4
+ # Shared class-level DSL for anything that presents as a tool to an LLM. Extend
5
+ # it to make a class discoverable as a tool; instance-level execution (+call+,
6
+ # +call_with_validation+) lives on Riffer::Tool instead.
14
7
  #
15
8
  # class MyTool
16
9
  # extend Riffer::Tools::Toolable
@@ -37,7 +30,6 @@ module Riffer::Tools::Toolable
37
30
  #--
38
31
  #: (Module) -> void
39
32
  def self.extended(base)
40
- base.extend Riffer::Helpers::ClassNameConverter
41
33
  extenders = (@extenders ||= []) #: Array[Module]
42
34
  extenders << base
43
35
  end
@@ -64,7 +56,7 @@ module Riffer::Tools::Toolable
64
56
  #--
65
57
  #: (?String?) -> String
66
58
  def identifier(value = nil)
67
- return @identifier || class_name_to_path(Module.instance_method(:name).bind_call(self)) if value.nil?
59
+ return @identifier || Riffer::Helpers::ClassNameConverter.convert(Module.instance_method(:name).bind_call(self)) if value.nil?
68
60
  @identifier = value.to_s
69
61
  end
70
62
 
@@ -105,10 +97,7 @@ module Riffer::Tools::Toolable
105
97
  @params_builder&.to_json_schema(strict: strict) || empty_schema
106
98
  end
107
99
 
108
- # Returns the kind of toolable entity.
109
- #
110
- # Defaults to +:tool+. Extensible to +:agent+, +:workflow+, etc.
111
- #
100
+ # Returns the kind of toolable entity; defaults to +:tool+.
112
101
  #--
113
102
  #: (?Symbol?) -> Symbol
114
103
  def kind(value = nil)
data/lib/riffer/tools.rb CHANGED
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  # rbs_inline: enabled
3
3
 
4
- # Namespace for tool-related classes in the Riffer framework.
5
- #
6
- # Contains:
7
- # - Riffer::Tools::Response - Required return type for tool execution
8
4
  module Riffer::Tools
9
5
  end
@@ -2,5 +2,5 @@
2
2
  # rbs_inline: enabled
3
3
 
4
4
  module Riffer
5
- VERSION = "0.30.0" #: String
5
+ VERSION = "0.32.0" #: String
6
6
  end
data/lib/riffer.rb CHANGED
@@ -4,10 +4,6 @@
4
4
  require "zeitwerk"
5
5
 
6
6
  # Riffer is the main module for the Riffer AI framework.
7
- #
8
- # Provides configuration, error classes, and versioning for the gem.
9
- #
10
- # See Riffer::Config, Riffer::Agent, Riffer::Providers, and Riffer::Messages.
11
7
  loader = Zeitwerk::Loader.for_gem
12
8
  loader.inflector.inflect(
13
9
  "open_ai" => "OpenAI",
@@ -17,7 +13,9 @@ loader.inflector.inflect(
17
13
  loader.setup
18
14
 
19
15
  module Riffer
20
- # @rbs self.@config: Riffer::Config?
16
+ extend self
17
+
18
+ # @rbs @config: Riffer::Config?
21
19
 
22
20
  # Base error class for Riffer.
23
21
  class Error < StandardError; end
@@ -38,7 +36,7 @@ module Riffer
38
36
  #
39
37
  #--
40
38
  #: () -> Riffer::Config
41
- def self.config
39
+ def config
42
40
  @config ||= Config.new
43
41
  end
44
42
 
@@ -50,13 +48,14 @@ module Riffer
50
48
  #
51
49
  #--
52
50
  #: () ?{ (Riffer::Config) -> void } -> void
53
- def self.configure(&block)
51
+ def configure(&block)
54
52
  yield config if block_given?
55
53
  end
56
54
 
55
+ # Returns the gem version.
57
56
  #--
58
57
  #: () -> String
59
- def self.version
58
+ def version
60
59
  VERSION
61
60
  end
62
61
  end
@@ -1,88 +1,76 @@
1
1
  # Generated from lib/riffer/agent/config.rb with RBS::Inline
2
2
 
3
3
  # Typed configuration object holding every class-level DSL setting on a
4
- # Riffer::Agent subclass.
5
- #
6
- # Each subclass of Riffer::Agent owns one Config, accessible via the class
7
- # method <tt>config</tt>. The class-level DSL (+model+, +instructions+, +uses_tools+,
8
- # etc.) reads and mutates this Config in place. Append-style DSL methods
9
- # (+use_mcp+, +guardrail+) are handled by the +add_mcp+ and +add_guardrail+
10
- # helpers below.
11
- #
12
- # Config stores Procs unresolved. Per-instance resolution happens elsewhere
13
- # (instructions, model, tools, tool runtime, skills).
4
+ # Riffer::Agent subclass. Procs are stored unresolved and resolved per-instance
5
+ # later.
14
6
  class Riffer::Agent::Config
15
7
  DEFAULT_MAX_STEPS: Integer
16
8
 
9
+ # The configured agent identifier.
17
10
  attr_reader identifier: String?
18
11
 
12
+ # The configured model.
19
13
  attr_reader model: (String | Proc)?
20
14
 
15
+ # The configured instructions.
21
16
  attr_reader instructions: (String | Proc)?
22
17
 
18
+ # Options passed to the provider client.
23
19
  attr_accessor provider_options: Hash[Symbol, untyped]
24
20
 
21
+ # Options passed to generate_text/stream_text.
25
22
  attr_accessor model_options: Hash[Symbol, untyped]
26
23
 
24
+ # The configured structured-output schema.
27
25
  attr_reader structured_output: Riffer::Params?
28
26
 
27
+ # The maximum number of LLM call steps in the tool-use loop.
29
28
  attr_accessor max_steps: Numeric?
30
29
 
30
+ # The configured tools.
31
31
  attr_accessor tools_config: (Array[singleton(Riffer::Tool)] | Proc)?
32
32
 
33
+ # The accumulated +use_mcp+ tag configurations.
33
34
  attr_reader mcp_configs: Array[Hash[Symbol, untyped]]
34
35
 
36
+ # The configured tool runtime.
35
37
  attr_reader tool_runtime: singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc
36
38
 
39
+ # The configured skills.
37
40
  attr_accessor skills_config: Riffer::Skills::Config?
38
41
 
42
+ # Registered guardrail entries keyed by phase.
39
43
  attr_reader guardrails: Hash[Symbol, Array[Hash[Symbol, untyped]]]
40
44
 
41
- # Builds a new Config. All fields are optional; unset fields take the
42
- # documented defaults.
43
- #
44
- # Raises Riffer::ArgumentError if +model+ or +instructions+ is provided
45
- # as a non-String, non-Proc value (or as an empty String).
46
- #
45
+ # Builds a new Config. Raises Riffer::ArgumentError if +model+ or
46
+ # +instructions+ is invalid (e.g. an empty string).
47
47
  # --
48
48
  # : (?identifier: String?, ?model: (String | Proc)?, ?instructions: (String | Proc)?, ?provider_options: Hash[Symbol, untyped], ?model_options: Hash[Symbol, untyped], ?structured_output: Riffer::Params?, ?max_steps: Numeric?, ?tools_config: (Array[singleton(Riffer::Tool)] | Proc)?, ?mcp_configs: Array[Hash[Symbol, untyped]], ?tool_runtime: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc), ?skills_config: Riffer::Skills::Config?, ?guardrails: Hash[Symbol, Array[Hash[Symbol, untyped]]]) -> void
49
49
  def initialize: (?identifier: String?, ?model: (String | Proc)?, ?instructions: (String | Proc)?, ?provider_options: Hash[Symbol, untyped], ?model_options: Hash[Symbol, untyped], ?structured_output: Riffer::Params?, ?max_steps: Numeric?, ?tools_config: (Array[singleton(Riffer::Tool)] | Proc)?, ?mcp_configs: Array[Hash[Symbol, untyped]], ?tool_runtime: singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc, ?skills_config: Riffer::Skills::Config?, ?guardrails: Hash[Symbol, Array[Hash[Symbol, untyped]]]) -> void
50
50
 
51
- # Sets +identifier+. Accepts +nil+ or any value, coerced to String.
52
- #
51
+ # Sets +identifier+, coercing the value to String.
53
52
  # --
54
53
  # : (untyped) -> String?
55
54
  def identifier=: (untyped) -> String?
56
55
 
57
- # Sets +structured_output+. Accepts a Riffer::Params instance or +nil+.
58
- #
59
- # Raises Riffer::ArgumentError on any other type.
60
- #
56
+ # Sets +structured_output+. Raises Riffer::ArgumentError on an invalid value.
61
57
  # --
62
58
  # : (Riffer::Params?) -> Riffer::Params?
63
59
  def structured_output=: (Riffer::Params?) -> Riffer::Params?
64
60
 
65
- # Sets +tool_runtime+. Accepts a Riffer::Tools::Runtime subclass, a
66
- # Riffer::Tools::Runtime instance, or a Proc.
67
- #
68
- # Raises Riffer::ArgumentError on any other type.
69
- #
61
+ # Sets +tool_runtime+. Raises Riffer::ArgumentError on an invalid value.
70
62
  # --
71
63
  # : ((singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)) -> (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)
72
64
  def tool_runtime=: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc) -> (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)
73
65
 
74
- # Sets +model+. Accepts a String ("provider/model"), a Proc, or +nil+.
75
- #
76
- # Raises Riffer::ArgumentError on non-String, non-Proc, or empty-String values.
77
- #
66
+ # Sets +model+. Raises Riffer::ArgumentError on an invalid value (e.g. an
67
+ # empty string).
78
68
  # --
79
69
  # : ((String | Proc)?) -> (String | Proc)?
80
70
  def model=: ((String | Proc)?) -> (String | Proc)?
81
71
 
82
- # Sets +instructions+. Accepts a String, a Proc, or +nil+.
83
- #
84
- # Raises Riffer::ArgumentError on non-String, non-Proc, or empty-String values.
85
- #
72
+ # Sets +instructions+. Raises Riffer::ArgumentError on an invalid value (e.g.
73
+ # an empty string).
86
74
  # --
87
75
  # : ((String | Proc)?) -> (String | Proc)?
88
76
  def instructions=: ((String | Proc)?) -> (String | Proc)?
@@ -90,18 +78,12 @@ class Riffer::Agent::Config
90
78
  # Appends an MCP tag entry to +mcp_configs+.
91
79
  #
92
80
  # --
93
- # : (String | Symbol) -> Array[Hash[Symbol, untyped]]
94
- def add_mcp: (String | Symbol) -> Array[Hash[Symbol, untyped]]
81
+ # : (String | Symbol, ?progressive: bool) -> Array[Hash[Symbol, untyped]]
82
+ def add_mcp: (String | Symbol, ?progressive: bool) -> Array[Hash[Symbol, untyped]]
95
83
 
96
- # Appends a guardrail entry to +guardrails+ for the given phase.
97
- #
98
- # [phase] +:before+, +:after+, or +:around+. +:around+ appends to both
99
- # +:before+ and +:after+.
100
- # [klass] the Riffer::Guardrail subclass to register.
101
- # [options] options forwarded to the guardrail at runtime.
102
- #
103
- # Raises Riffer::ArgumentError on an invalid phase or non-Guardrail class.
104
- #
84
+ # Appends a guardrail entry to +guardrails+ for the given phase; +:around+
85
+ # appends to both +:before+ and +:after+. Raises Riffer::ArgumentError unless
86
+ # +phase+ is :before, :after, or :around.
105
87
  # --
106
88
  # : (Symbol, klass: singleton(Riffer::Guardrail), ?options: Hash[Symbol, untyped]) -> void
107
89
  def add_guardrail: (Symbol, klass: singleton(Riffer::Guardrail), ?options: Hash[Symbol, untyped]) -> void
@@ -114,6 +96,7 @@ class Riffer::Agent::Config
114
96
 
115
97
  private
116
98
 
99
+ # --
117
100
  # : (untyped, String) -> void
118
101
  def validate_string_or_proc!: (untyped, String) -> void
119
102
  end
@@ -1,36 +1,15 @@
1
1
  # Generated from lib/riffer/agent/context.rb with RBS::Inline
2
2
 
3
- # Typed value object wrapping the runtime context Hash held by a
4
- # Riffer::Agent. Exposes first-class accessors for the framework-managed
5
- # entries — +skills+ and +token_usage+ and preserves +#[]+ / +#dig+
6
- # reads so tools (which receive +context:+ as a keyword) keep working
7
- # with both built-in and caller-provided keys.
8
- #
9
- # Reserved keys (+:skills+, +:token_usage+) cannot be set by the caller
10
- # at construction; they are owned by Riffer and written through the typed
11
- # setters. Type invariants are enforced on write — +skills+ must be a
12
- # +Riffer::Skills::Context+ (or nil); +token_usage+ must be a
13
- # +Riffer::Providers::TokenUsage+ (or nil).
14
- #
15
- # context = Riffer::Agent::Context.new(user_id: 42)
16
- # context[:user_id] # => 42
17
- # context.skills # => nil
18
- # context.token_usage # => nil
3
+ # Typed value object wrapping the runtime context Hash held by a Riffer::Agent.
4
+ # Exposes typed +skills+, +token_usage+, +mcp_progressive_tools+, and
5
+ # +discovered_tools+ accessors while preserving +#[]+ / +#dig+ for caller-provided keys.
19
6
  class Riffer::Agent::Context
20
7
  @data: Hash[Symbol, untyped]
21
8
 
22
- # Keys reserved for framework use. Passing any of these to the
23
- # constructor raises +Riffer::ArgumentError+.
24
9
  RESERVED_KEYS: Array[Symbol]
25
10
 
26
- # Builds a new context.
27
- #
28
- # [data] caller-provided Hash passed as <tt>Agent.new(context:)</tt>.
29
- # Duped before storage so caller mutations do not affect the
30
- # agent. Must not contain any +RESERVED_KEYS+.
31
- #
32
- # Raises Riffer::ArgumentError when +data+ contains a reserved key.
33
- #
11
+ # Builds a new context. The caller Hash is duped so later caller mutations
12
+ # don't leak in. Raises Riffer::ArgumentError if it contains a reserved key.
34
13
  # --
35
14
  # : (?Hash[Symbol, untyped]) -> void
36
15
  def initialize: (?Hash[Symbol, untyped]) -> void
@@ -42,12 +21,8 @@ class Riffer::Agent::Context
42
21
  # : () -> Riffer::Skills::Context?
43
22
  def skills: () -> Riffer::Skills::Context?
44
23
 
45
- # Sets the resolved skills context. Called once by +Riffer::Agent+
46
- # during construction.
47
- #
48
- # Raises Riffer::ArgumentError if +value+ is neither +nil+ nor a
49
- # +Riffer::Skills::Context+.
50
- #
24
+ # Sets the resolved skills context. Raises Riffer::ArgumentError on an
25
+ # invalid value.
51
26
  # --
52
27
  # : (Riffer::Skills::Context?) -> Riffer::Skills::Context?
53
28
  def skills=: (Riffer::Skills::Context?) -> Riffer::Skills::Context?
@@ -59,34 +34,51 @@ class Riffer::Agent::Context
59
34
  # : () -> Riffer::Providers::TokenUsage?
60
35
  def token_usage: () -> Riffer::Providers::TokenUsage?
61
36
 
62
- # Sets the cumulative token usage. Called by +Riffer::Agent::Run+ after
63
- # each LLM response.
64
- #
65
- # Raises Riffer::ArgumentError if +value+ is neither +nil+ nor a
66
- # +Riffer::Providers::TokenUsage+.
67
- #
37
+ # Sets the cumulative token usage. Raises Riffer::ArgumentError on an invalid
38
+ # value.
68
39
  # --
69
40
  # : (Riffer::Providers::TokenUsage?) -> Riffer::Providers::TokenUsage?
70
41
  def token_usage=: (Riffer::Providers::TokenUsage?) -> Riffer::Providers::TokenUsage?
71
42
 
72
- # Hash-style read. Preserved so downstream tool runtimes pulling
73
- # caller-provided keys via <tt>context[:agent]</tt> or
74
- # <tt>context[:tenant]</tt> keep working unchanged.
75
- #
43
+ # Hash-style read, preserved so tools can pull caller-provided keys via
44
+ # <tt>context[:agent]</tt>.
76
45
  # --
77
46
  # : (Symbol) -> untyped
78
47
  def []: (Symbol) -> untyped
79
48
 
80
- # Hash-style dig. Preserved for tools using
81
- # <tt>context&.dig(:user_id)</tt>.
82
- #
49
+ # Auth-wrapped MCP tool classes for progressive discovery, or +nil+.
50
+ # --
51
+ # : () -> Array[singleton(Riffer::Tool)]?
52
+ def mcp_progressive_tools: () -> Array[singleton(Riffer::Tool)]?
53
+
54
+ # Sets progressive MCP tools. Raises Riffer::ArgumentError on an invalid value.
55
+ # --
56
+ # : (Array[singleton(Riffer::Tool)]?) -> Array[singleton(Riffer::Tool)]?
57
+ def mcp_progressive_tools=: (Array[singleton(Riffer::Tool)]?) -> Array[singleton(Riffer::Tool)]?
58
+
59
+ # MCP tool classes discovered during progressive search. Accumulates across
60
+ # +generate+ calls and is merged into the active tool list on every LLM call.
61
+ # --
62
+ # : () -> Array[singleton(Riffer::Tool)]?
63
+ def discovered_tools: () -> Array[singleton(Riffer::Tool)]?
64
+
65
+ # Sets the discovered tools array. Raises Riffer::ArgumentError on an invalid value.
66
+ # --
67
+ # : (Array[singleton(Riffer::Tool)]?) -> Array[singleton(Riffer::Tool)]?
68
+ def discovered_tools=: (Array[singleton(Riffer::Tool)]?) -> Array[singleton(Riffer::Tool)]?
69
+
70
+ # Accumulates newly discovered MCP tool classes, deduplicating by name.
71
+ # Each call extends the existing set; calling multiple times is safe.
72
+ # --
73
+ # : (Array[singleton(Riffer::Tool)]) -> Array[singleton(Riffer::Tool)]
74
+ def discover_tools: (Array[singleton(Riffer::Tool)]) -> Array[singleton(Riffer::Tool)]
75
+
83
76
  # --
84
77
  # : (*Symbol) -> untyped
85
78
  def dig: (*Symbol) -> untyped
86
79
 
87
- # Returns a copy of the underlying Hash. Mutating the result does not
88
- # affect this context.
89
- #
80
+ # Returns a copy of the underlying Hash; mutating it does not affect this
81
+ # context.
90
82
  # --
91
83
  # : () -> Hash[Symbol, untyped]
92
84
  def to_h: () -> Hash[Symbol, untyped]
@@ -1,9 +1,7 @@
1
1
  # Generated from lib/riffer/agent/response.rb with RBS::Inline
2
2
 
3
- # Wraps agent generation responses with optional tripwire information.
4
- #
5
- # When guardrails block execution, the response will contain a tripwire
6
- # with details about the block. The content will be empty for blocked responses.
3
+ # Wraps an agent generation response. When a guardrail blocks execution,
4
+ # +content+ is empty and +tripwire+ carries the block details.
7
5
  #
8
6
  # response = agent.generate("Hello")
9
7
  # if response.blocked?
@@ -32,24 +30,10 @@ class Riffer::Agent::Response
32
30
  # The full message history from the agent conversation.
33
31
  attr_reader messages: Array[Riffer::Messages::Base]
34
32
 
35
- # Call ids of tool_use blocks that riffer filled with placeholder
36
- # results during this turn — populated when an interrupt left them
37
- # unanswered and +Riffer.config.experimental_history_healing+ is on.
38
- # Empty otherwise.
33
+ # Call ids of tool_use blocks riffer filled with placeholder results this
34
+ # turn (when an interrupt left them unanswered and history healing is on).
39
35
  attr_reader healed_tool_call_ids: Array[String]
40
36
 
41
- # Creates a new response.
42
- #
43
- # [content] the response content.
44
- # [tripwire] optional tripwire for blocked responses.
45
- # [modifications] guardrail modifications applied during processing.
46
- # [interrupted] whether the agent loop was interrupted by a callback.
47
- # [interrupt_reason] optional reason passed via <tt>throw :riffer_interrupt, reason</tt>.
48
- # [structured_output] parsed structured output when structured output is configured.
49
- # [messages] the full message history from the agent conversation.
50
- # [healed_tool_call_ids] call ids filled with placeholder tool results
51
- # when history healing is enabled.
52
- #
53
37
  # --
54
38
  # : (String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?messages: Array[Riffer::Messages::Base], ?healed_tool_call_ids: Array[String]) -> void
55
39
  def initialize: (String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?messages: Array[Riffer::Messages::Base], ?healed_tool_call_ids: Array[String]) -> void
@@ -1,21 +1,8 @@
1
1
  # Generated from lib/riffer/agent/run.rb with RBS::Inline
2
2
 
3
- # Riffer::Agent::Run is the generation loop. A pure module of functions over an
4
- # +agent+ — Agent owns every per-call value (provider, model, tools, tool
5
- # runtime, structured output, session, context); Run just orchestrates.
6
- #
7
- # Tools and user code see the agent's +context+ (a +Riffer::Agent::Context+)
8
- # unchanged through the loop, so downstream tool runtimes can read
9
- # caller-provided keys via <tt>context[:agent]</tt> /
10
- # <tt>context.dig(:key)</tt>, or the framework built-ins via
11
- # +context.skills+. Cumulative token usage is updated into
12
- # +agent.context.token_usage+ as the loop progresses.
13
- #
14
- # Riffer::Agent::Run.generate(agent: my_agent, prompt: "Hello")
15
- # Riffer::Agent::Run.stream(agent: my_agent, prompt: "Hello")
3
+ # The generation loop a pure module of functions over an +agent+, which owns
4
+ # every per-call value; Run just orchestrates.
16
5
  module Riffer::Agent::Run
17
- include Riffer::Messages::Converter
18
-
19
6
  # Runs the generate loop for the given agent. See Riffer::Agent#generate
20
7
  # for prompt/files semantics.
21
8
  #
@@ -32,43 +19,22 @@ module Riffer::Agent::Run
32
19
 
33
20
  private
34
21
 
35
- # The generation loop. When +stream_yielder+ is provided, per-step events are
36
- # pushed to it (and +stream+ discards the return value). When +stream_yielder+
37
- # is +nil+, no events are emitted and +generate+ returns the Response
38
- # directly. The two modes share every step of the loop — the only
39
- # divergences are the LLM call shape (atomic vs. accumulated stream)
40
- # and whether per-step events are emitted.
41
- #
42
22
  # --
43
23
  # : (Riffer::Agent, ?stream_yielder: Enumerator::Yielder?) -> Riffer::Agent::Response
44
24
  def run_loop: (Riffer::Agent, ?stream_yielder: Enumerator::Yielder?) -> Riffer::Agent::Response
45
25
 
46
- # Consumes one provider stream, forwarding every event to +stream_yielder+
47
- # and folding it into an +Assistant+ message.
48
- #
49
26
  # --
50
27
  # : (Riffer::Agent, Enumerator::Yielder) -> Riffer::Messages::Assistant
51
28
  def accumulate_streamed_response: (Riffer::Agent, Enumerator::Yielder) -> Riffer::Messages::Assistant
52
29
 
53
- # Appends +new_modifications+ to +all_modifications+ and emits a
54
- # +GuardrailModification+ event for each one when streaming.
55
- #
56
30
  # --
57
31
  # : (Enumerator::Yielder?, Array[Riffer::Guardrails::Modification], Array[Riffer::Guardrails::Modification]) -> void
58
32
  def record_modifications!: (Enumerator::Yielder?, Array[Riffer::Guardrails::Modification], Array[Riffer::Guardrails::Modification]) -> void
59
33
 
60
- # Emits a +GuardrailTripwire+ event when streaming and returns the
61
- # short-circuit +Response+ for a tripped guardrail.
62
- #
63
34
  # --
64
35
  # : (Riffer::Agent, Enumerator::Yielder?, Riffer::Guardrails::Tripwire, Array[Riffer::Guardrails::Modification]) -> Riffer::Agent::Response
65
36
  def tripwire_response: (Riffer::Agent, Enumerator::Yielder?, Riffer::Guardrails::Tripwire, Array[Riffer::Guardrails::Modification]) -> Riffer::Agent::Response
66
37
 
67
- # Builds the final +Response+ from the session's last assistant
68
- # message, validating structured output when configured. +extra+
69
- # carries the interrupt-only fields (+interrupted:+, +interrupt_reason:+,
70
- # +healed_tool_call_ids:+) on the interrupt exit path.
71
- #
72
38
  # --
73
39
  # : (Riffer::Agent, Array[Riffer::Guardrails::Modification], **untyped) -> Riffer::Agent::Response
74
40
  def final_response: (Riffer::Agent, Array[Riffer::Guardrails::Modification], **untyped) -> Riffer::Agent::Response
@@ -85,31 +51,18 @@ module Riffer::Agent::Run
85
51
  # : (Riffer::Agent, Riffer::Messages::Assistant, ?tool_calls: Array[Riffer::Messages::Assistant::ToolCall]) -> void
86
52
  def execute_tool_calls: (Riffer::Agent, Riffer::Messages::Assistant, ?tool_calls: Array[Riffer::Messages::Assistant::ToolCall]) -> void
87
53
 
88
- # Executes tool calls left unfinished by a prior interrupt.
89
- #
90
- # Detects gaps between the last assistant message's requested tool calls
91
- # and the tool result messages that follow it, executing any that are
92
- # missing. Safe to call unconditionally.
93
- #
54
+ # --
55
+ # : (Riffer::Agent, Array[[Riffer::Messages::Assistant::ToolCall, Riffer::Tools::Response]]) -> void
56
+ def inject_discovered_tools: (Riffer::Agent, Array[[ Riffer::Messages::Assistant::ToolCall, Riffer::Tools::Response ]]) -> void
57
+
94
58
  # --
95
59
  # : (Riffer::Agent) -> void
96
60
  def execute_pending_tool_calls: (Riffer::Agent) -> void
97
61
 
98
- # Runs the +:before+ guardrail phase. Records any modifications into
99
- # +all_modifications+ (and emits them when streaming). When a tripwire
100
- # fires, yields the short-circuit +Response+ — the caller's block is
101
- # expected to +return+ it from +run_loop+.
102
- #
103
62
  # --
104
63
  # : (Riffer::Agent, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::Agent::Response) -> void } -> void
105
64
  def run_before_guardrails: (Riffer::Agent, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::Agent::Response) -> void } -> void
106
65
 
107
- # Runs the +:after+ guardrail phase against the assistant +response+.
108
- # Records any modifications into +all_modifications+ (and emits them
109
- # when streaming). When a tripwire fires, yields the short-circuit
110
- # +Response+ — the caller's block is expected to +return+ it from
111
- # +run_loop+. Otherwise returns the post-guardrails assistant message.
112
- #
113
66
  # --
114
67
  # : (Riffer::Agent, Riffer::Messages::Assistant, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::Agent::Response) -> void } -> untyped
115
68
  def run_after_guardrails: (Riffer::Agent, Riffer::Messages::Assistant, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::Agent::Response) -> void } -> untyped
@@ -118,6 +71,10 @@ module Riffer::Agent::Run
118
71
  # : (Riffer::Agent, Riffer::Messages::Assistant?) -> Hash[Symbol, untyped]?
119
72
  def validate_structured_output: (Riffer::Agent, Riffer::Messages::Assistant?) -> Hash[Symbol, untyped]?
120
73
 
74
+ # --
75
+ # : (Riffer::Agent) -> Array[singleton(Riffer::Tool)]
76
+ def effective_tools: (Riffer::Agent) -> Array[singleton(Riffer::Tool)]
77
+
121
78
  # --
122
79
  # : (Riffer::Agent) -> Hash[Symbol, untyped]
123
80
  def merged_model_options: (Riffer::Agent) -> Hash[Symbol, untyped]
@@ -126,18 +83,12 @@ module Riffer::Agent::Run
126
83
  # : (Riffer::Agent, String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?healed_tool_call_ids: Array[String]) -> Riffer::Agent::Response
127
84
  def build_response: (Riffer::Agent, String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?healed_tool_call_ids: Array[String]) -> Riffer::Agent::Response
128
85
 
129
- # Appends a +User+ message to the session. No-ops when +prompt+ is nil
130
- # and +files+ is empty (the caller had nothing to add). Raises when
131
- # +files+ are supplied without a +prompt+ — the provider needs text to
132
- # anchor the attachments.
133
- #
86
+ # Raises when +files+ are supplied without a +prompt+ the provider needs
87
+ # text to anchor the attachments.
134
88
  # --
135
89
  # : (Riffer::Agent, String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::FilePart]?) -> void
136
90
  def append_user_message: (Riffer::Agent, String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::FilePart]?) -> void
137
91
 
138
- # Accumulates token usage into +agent.context.token_usage+. Updates the
139
- # context so cumulative usage persists across every run on the agent.
140
- #
141
92
  # --
142
93
  # : (Riffer::Agent, Riffer::Providers::TokenUsage?) -> void
143
94
  def track_token_usage: (Riffer::Agent, Riffer::Providers::TokenUsage?) -> void