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.
Files changed (213) 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 +18 -0
  7. data/docs/08_MESSAGES.md +1 -1
  8. data/docs/14_MCP.md +50 -5
  9. data/docs/providers/02_AMAZON_BEDROCK.md +14 -0
  10. data/lib/riffer/agent/config.rb +42 -47
  11. data/lib/riffer/agent/context.rb +70 -50
  12. data/lib/riffer/agent/response.rb +4 -20
  13. data/lib/riffer/agent/run.rb +28 -67
  14. data/lib/riffer/agent/serializer.rb +22 -81
  15. data/lib/riffer/agent/session/repair.rb +14 -40
  16. data/lib/riffer/agent/session.rb +25 -67
  17. data/lib/riffer/agent/structured_output/result.rb +3 -11
  18. data/lib/riffer/agent/structured_output.rb +5 -13
  19. data/lib/riffer/agent.rb +74 -192
  20. data/lib/riffer/config.rb +34 -101
  21. data/lib/riffer/evals/evaluator.rb +7 -27
  22. data/lib/riffer/evals/evaluator_runner.rb +11 -19
  23. data/lib/riffer/evals/judge.rb +4 -25
  24. data/lib/riffer/evals/result.rb +1 -18
  25. data/lib/riffer/evals/run_result.rb +0 -11
  26. data/lib/riffer/evals/scenario_result.rb +0 -14
  27. data/lib/riffer/evals.rb +0 -6
  28. data/lib/riffer/guardrail.rb +4 -27
  29. data/lib/riffer/guardrails/modification.rb +0 -10
  30. data/lib/riffer/guardrails/result.rb +3 -30
  31. data/lib/riffer/guardrails/runner.rb +5 -22
  32. data/lib/riffer/guardrails/tripwire.rb +1 -19
  33. data/lib/riffer/guardrails.rb +2 -4
  34. data/lib/riffer/helpers/call_or_value.rb +4 -3
  35. data/lib/riffer/helpers/class_name_converter.rb +3 -1
  36. data/lib/riffer/helpers/dependencies.rb +5 -7
  37. data/lib/riffer/helpers.rb +0 -5
  38. data/lib/riffer/mcp/authenticated_tool.rb +9 -9
  39. data/lib/riffer/mcp/client.rb +12 -17
  40. data/lib/riffer/mcp/manifest.rb +13 -10
  41. data/lib/riffer/mcp/registration.rb +2 -11
  42. data/lib/riffer/mcp/registry.rb +44 -52
  43. data/lib/riffer/mcp/search_tool.rb +53 -0
  44. data/lib/riffer/mcp/tool_factory.rb +13 -18
  45. data/lib/riffer/mcp.rb +12 -17
  46. data/lib/riffer/messages/assistant.rb +2 -9
  47. data/lib/riffer/messages/base.rb +46 -16
  48. data/lib/riffer/messages/file_part.rb +32 -24
  49. data/lib/riffer/messages/system.rb +0 -5
  50. data/lib/riffer/messages/tool.rb +0 -10
  51. data/lib/riffer/messages/user.rb +0 -10
  52. data/lib/riffer/messages.rb +0 -7
  53. data/lib/riffer/params/boolean.rb +2 -4
  54. data/lib/riffer/params/param.rb +28 -39
  55. data/lib/riffer/params.rb +9 -21
  56. data/lib/riffer/providers/amazon_bedrock.rb +42 -28
  57. data/lib/riffer/providers/anthropic.rb +4 -9
  58. data/lib/riffer/providers/azure_open_ai.rb +3 -19
  59. data/lib/riffer/providers/base.rb +13 -26
  60. data/lib/riffer/providers/gemini.rb +4 -4
  61. data/lib/riffer/providers/mock.rb +6 -26
  62. data/lib/riffer/providers/open_ai.rb +6 -8
  63. data/lib/riffer/providers/open_router.rb +4 -10
  64. data/lib/riffer/providers/repository.rb +4 -3
  65. data/lib/riffer/providers/token_usage.rb +9 -20
  66. data/lib/riffer/providers.rb +0 -8
  67. data/lib/riffer/runner/fibers.rb +10 -16
  68. data/lib/riffer/runner/sequential.rb +1 -4
  69. data/lib/riffer/runner/threaded.rb +3 -14
  70. data/lib/riffer/runner.rb +2 -15
  71. data/lib/riffer/skills/activate_tool.rb +2 -11
  72. data/lib/riffer/skills/adapter.rb +4 -22
  73. data/lib/riffer/skills/backend.rb +7 -21
  74. data/lib/riffer/skills/config.rb +10 -31
  75. data/lib/riffer/skills/context.rb +5 -20
  76. data/lib/riffer/skills/filesystem_backend.rb +7 -25
  77. data/lib/riffer/skills/frontmatter.rb +10 -28
  78. data/lib/riffer/skills/markdown_adapter.rb +2 -9
  79. data/lib/riffer/skills/xml_adapter.rb +2 -8
  80. data/lib/riffer/stream_events/base.rb +1 -6
  81. data/lib/riffer/stream_events/guardrail_modification.rb +1 -8
  82. data/lib/riffer/stream_events/guardrail_tripwire.rb +1 -8
  83. data/lib/riffer/stream_events/interrupt.rb +4 -7
  84. data/lib/riffer/stream_events/reasoning_delta.rb +2 -4
  85. data/lib/riffer/stream_events/reasoning_done.rb +2 -4
  86. data/lib/riffer/stream_events/skill_activation.rb +2 -4
  87. data/lib/riffer/stream_events/text_delta.rb +0 -2
  88. data/lib/riffer/stream_events/text_done.rb +1 -3
  89. data/lib/riffer/stream_events/token_usage_done.rb +1 -8
  90. data/lib/riffer/stream_events/tool_call_delta.rb +2 -3
  91. data/lib/riffer/stream_events/tool_call_done.rb +1 -3
  92. data/lib/riffer/stream_events/web_search_done.rb +1 -3
  93. data/lib/riffer/stream_events/web_search_status.rb +2 -3
  94. data/lib/riffer/stream_events.rb +0 -10
  95. data/lib/riffer/tool.rb +6 -13
  96. data/lib/riffer/tools/response.rb +8 -4
  97. data/lib/riffer/tools/runtime/fibers.rb +0 -3
  98. data/lib/riffer/tools/runtime/inline.rb +1 -4
  99. data/lib/riffer/tools/runtime/threaded.rb +0 -2
  100. data/lib/riffer/tools/runtime.rb +5 -38
  101. data/lib/riffer/tools/toolable.rb +5 -16
  102. data/lib/riffer/tools.rb +0 -4
  103. data/lib/riffer/version.rb +1 -1
  104. data/lib/riffer.rb +7 -8
  105. data/sig/generated/riffer/agent/config.rbs +29 -46
  106. data/sig/generated/riffer/agent/context.rbs +40 -48
  107. data/sig/generated/riffer/agent/response.rbs +4 -20
  108. data/sig/generated/riffer/agent/run.rbs +12 -61
  109. data/sig/generated/riffer/agent/serializer.rbs +21 -80
  110. data/sig/generated/riffer/agent/session/repair.rbs +12 -40
  111. data/sig/generated/riffer/agent/session.rbs +25 -67
  112. data/sig/generated/riffer/agent/structured_output/result.rbs +2 -10
  113. data/sig/generated/riffer/agent/structured_output.rbs +5 -12
  114. data/sig/generated/riffer/agent.rbs +57 -186
  115. data/sig/generated/riffer/config.rbs +34 -100
  116. data/sig/generated/riffer/evals/evaluator.rbs +7 -27
  117. data/sig/generated/riffer/evals/evaluator_runner.rbs +9 -19
  118. data/sig/generated/riffer/evals/judge.rbs +4 -24
  119. data/sig/generated/riffer/evals/result.rbs +1 -17
  120. data/sig/generated/riffer/evals/run_result.rbs +0 -10
  121. data/sig/generated/riffer/evals/scenario_result.rbs +0 -13
  122. data/sig/generated/riffer/evals.rbs +0 -6
  123. data/sig/generated/riffer/guardrail.rbs +4 -27
  124. data/sig/generated/riffer/guardrails/modification.rbs +0 -10
  125. data/sig/generated/riffer/guardrails/result.rbs +3 -30
  126. data/sig/generated/riffer/guardrails/runner.rbs +5 -22
  127. data/sig/generated/riffer/guardrails/tripwire.rbs +1 -19
  128. data/sig/generated/riffer/guardrails.rbs +2 -4
  129. data/sig/generated/riffer/helpers/call_or_value.rbs +4 -3
  130. data/sig/generated/riffer/helpers/class_name_converter.rbs +1 -1
  131. data/sig/generated/riffer/helpers/dependencies.rbs +3 -7
  132. data/sig/generated/riffer/helpers.rbs +0 -5
  133. data/sig/generated/riffer/mcp/authenticated_tool.rbs +5 -4
  134. data/sig/generated/riffer/mcp/client.rbs +10 -16
  135. data/sig/generated/riffer/mcp/manifest.rbs +9 -9
  136. data/sig/generated/riffer/mcp/registration.rbs +2 -10
  137. data/sig/generated/riffer/mcp/registry.rbs +11 -18
  138. data/sig/generated/riffer/mcp/search_tool.rbs +26 -0
  139. data/sig/generated/riffer/mcp/tool_factory.rbs +10 -15
  140. data/sig/generated/riffer/mcp.rbs +10 -17
  141. data/sig/generated/riffer/messages/assistant.rbs +2 -8
  142. data/sig/generated/riffer/messages/base.rbs +11 -16
  143. data/sig/generated/riffer/messages/file_part.rbs +13 -23
  144. data/sig/generated/riffer/messages/system.rbs +0 -4
  145. data/sig/generated/riffer/messages/tool.rbs +0 -9
  146. data/sig/generated/riffer/messages/user.rbs +0 -9
  147. data/sig/generated/riffer/messages.rbs +0 -7
  148. data/sig/generated/riffer/params/boolean.rbs +2 -4
  149. data/sig/generated/riffer/params/param.rbs +21 -39
  150. data/sig/generated/riffer/params.rbs +9 -21
  151. data/sig/generated/riffer/providers/amazon_bedrock.rbs +21 -25
  152. data/sig/generated/riffer/providers/anthropic.rbs +2 -7
  153. data/sig/generated/riffer/providers/azure_open_ai.rbs +3 -18
  154. data/sig/generated/riffer/providers/base.rbs +9 -25
  155. data/sig/generated/riffer/providers/gemini.rbs +0 -2
  156. data/sig/generated/riffer/providers/mock.rbs +6 -26
  157. data/sig/generated/riffer/providers/open_ai.rbs +1 -5
  158. data/sig/generated/riffer/providers/open_router.rbs +4 -10
  159. data/sig/generated/riffer/providers/repository.rbs +2 -3
  160. data/sig/generated/riffer/providers/token_usage.rbs +6 -16
  161. data/sig/generated/riffer/providers.rbs +0 -8
  162. data/sig/generated/riffer/runner/fibers.rbs +8 -15
  163. data/sig/generated/riffer/runner/sequential.rbs +1 -3
  164. data/sig/generated/riffer/runner/threaded.rbs +3 -13
  165. data/sig/generated/riffer/runner.rbs +2 -14
  166. data/sig/generated/riffer/skills/activate_tool.rbs +2 -11
  167. data/sig/generated/riffer/skills/adapter.rbs +4 -22
  168. data/sig/generated/riffer/skills/backend.rbs +7 -21
  169. data/sig/generated/riffer/skills/config.rbs +10 -31
  170. data/sig/generated/riffer/skills/context.rbs +5 -20
  171. data/sig/generated/riffer/skills/filesystem_backend.rbs +7 -24
  172. data/sig/generated/riffer/skills/frontmatter.rbs +10 -27
  173. data/sig/generated/riffer/skills/markdown_adapter.rbs +2 -9
  174. data/sig/generated/riffer/skills/xml_adapter.rbs +2 -8
  175. data/sig/generated/riffer/stream_events/base.rbs +1 -6
  176. data/sig/generated/riffer/stream_events/guardrail_modification.rbs +1 -8
  177. data/sig/generated/riffer/stream_events/guardrail_tripwire.rbs +1 -8
  178. data/sig/generated/riffer/stream_events/interrupt.rbs +4 -7
  179. data/sig/generated/riffer/stream_events/reasoning_delta.rbs +2 -4
  180. data/sig/generated/riffer/stream_events/reasoning_done.rbs +2 -4
  181. data/sig/generated/riffer/stream_events/skill_activation.rbs +2 -4
  182. data/sig/generated/riffer/stream_events/text_delta.rbs +0 -2
  183. data/sig/generated/riffer/stream_events/text_done.rbs +1 -3
  184. data/sig/generated/riffer/stream_events/token_usage_done.rbs +1 -7
  185. data/sig/generated/riffer/stream_events/tool_call_delta.rbs +2 -3
  186. data/sig/generated/riffer/stream_events/tool_call_done.rbs +1 -3
  187. data/sig/generated/riffer/stream_events/web_search_done.rbs +1 -3
  188. data/sig/generated/riffer/stream_events/web_search_status.rbs +2 -3
  189. data/sig/generated/riffer/stream_events.rbs +0 -10
  190. data/sig/generated/riffer/tool.rbs +5 -12
  191. data/sig/generated/riffer/tools/response.rbs +6 -4
  192. data/sig/generated/riffer/tools/runtime/fibers.rbs +0 -3
  193. data/sig/generated/riffer/tools/runtime/inline.rbs +1 -3
  194. data/sig/generated/riffer/tools/runtime/threaded.rbs +0 -2
  195. data/sig/generated/riffer/tools/runtime.rbs +5 -37
  196. data/sig/generated/riffer/tools/toolable.rbs +4 -14
  197. data/sig/generated/riffer/tools.rbs +0 -4
  198. data/sig/generated/riffer.rbs +5 -4
  199. data/sig/manual/riffer/agent/session/repair.rbs +5 -0
  200. data/sig/manual/riffer/evals/evaluator_runner.rbs +5 -0
  201. data/sig/manual/riffer/helpers/class_name_converter.rbs +5 -0
  202. data/sig/manual/riffer/helpers/dependencies.rbs +5 -0
  203. data/sig/manual/riffer/mcp/authenticated_tool.rbs +5 -0
  204. data/sig/manual/riffer/mcp/registry.rbs +5 -0
  205. data/sig/manual/riffer/mcp/tool_factory.rbs +5 -0
  206. data/sig/manual/riffer/mcp.rbs +5 -0
  207. data/sig/manual/riffer/providers/repository.rbs +5 -0
  208. data/sig/manual/riffer.rbs +5 -0
  209. metadata +17 -9
  210. data/.agents/rdoc.md +0 -69
  211. data/lib/riffer/messages/converter.rb +0 -90
  212. data/sig/generated/riffer/messages/converter.rbs +0 -33
  213. data/sig/manual/riffer/tools/toolable.rbs +0 -6
@@ -1,9 +1,7 @@
1
1
  # Generated from lib/riffer/mcp/registration.rb with RBS::Inline
2
2
 
3
- # Per-server state managed by Riffer::Mcp::Registry.
4
- #
5
- # Created when a server is registered. Discovers tools via the MCP
6
- # +tools/list+ call, then generates tool classes.
3
+ # Per-server state managed by Riffer::Mcp::Registry — discovers tools via
4
+ # +tools/list+ and generates tool classes when a server is registered.
7
5
  class Riffer::Mcp::Registration
8
6
  @cancelled: bool
9
7
 
@@ -39,12 +37,6 @@ class Riffer::Mcp::Registration
39
37
 
40
38
  private
41
39
 
42
- # Runs tool discovery using the configured Runner.
43
- #
44
- # With +Runner::Sequential+ (default) discovery blocks inline. With
45
- # +Runner::Threaded+ discovery runs on a pool thread but +map+ still
46
- # blocks the caller — useful for Rails connection-pool isolation.
47
- #
48
40
  # --
49
41
  # : () -> void
50
42
  def run_discovery: () -> void
@@ -1,39 +1,32 @@
1
1
  # Generated from lib/riffer/mcp/registry.rb with RBS::Inline
2
2
 
3
- # Thread-safe global store for MCP server registrations.
4
- #
5
- # Keyed by manifest name. All public methods are mutex-guarded.
3
+ # Thread-safe global store for MCP server registrations, keyed by manifest name.
6
4
  module Riffer::Mcp::Registry
7
- self.@mutex: Thread::Mutex
5
+ @mutex: Thread::Mutex
8
6
 
9
- self.@store: Hash[String, Riffer::Mcp::Registration]
7
+ @store: Hash[String, Riffer::Mcp::Registration]
10
8
 
11
- # Registers an MCP server and starts async tool discovery.
12
- #
13
- # Accepts a Manifest instance or a hash of manifest keyword arguments.
14
- # Replaces any existing registration with the same name.
15
- #
9
+ # Registers an MCP server and starts async tool discovery, replacing any
10
+ # existing registration with the same name.
16
11
  # --
17
12
  # : ((Hash[Symbol, untyped] | Riffer::Mcp::Manifest)) -> Riffer::Mcp::Registration
18
- def self.register: (Hash[Symbol, untyped] | Riffer::Mcp::Manifest) -> Riffer::Mcp::Registration
13
+ def register: (Hash[Symbol, untyped] | Riffer::Mcp::Manifest) -> Riffer::Mcp::Registration
19
14
 
20
15
  # Removes a registration by name.
21
16
  #
22
17
  # --
23
18
  # : ((String | Symbol)) -> void
24
- def self.unregister: (String | Symbol) -> void
19
+ def unregister: (String | Symbol) -> void
25
20
 
26
21
  # Returns a frozen snapshot of all current registrations.
27
22
  #
28
23
  # --
29
24
  # : () -> Hash[String, Riffer::Mcp::Registration]
30
- def self.registrations: () -> Hash[String, Riffer::Mcp::Registration]
25
+ def registrations: () -> Hash[String, Riffer::Mcp::Registration]
31
26
 
32
- # Returns all registrations whose manifest tags intersect with the given tags.
33
- #
34
- # Tags are normalized to symbols before matching.
35
- #
27
+ # Returns all registrations whose manifest tags intersect the given tags
28
+ # (normalized to symbols).
36
29
  # --
37
30
  # : (Array[Symbol]) -> Array[Riffer::Mcp::Registration]
38
- def self.find_by_tags: (Array[Symbol]) -> Array[Riffer::Mcp::Registration]
31
+ def find_by_tags: (Array[Symbol]) -> Array[Riffer::Mcp::Registration]
39
32
  end
@@ -0,0 +1,26 @@
1
+ # Generated from lib/riffer/mcp/search_tool.rb with RBS::Inline
2
+
3
+ # Searches available MCP tools by name or description.
4
+ class Riffer::Mcp::SearchTool < Riffer::Tool
5
+ IDENTIFIER: ::String
6
+
7
+ # Successful search response carrying the matched tool classes.
8
+ class Result < Riffer::Tools::Response
9
+ # Tool classes that matched the search query.
10
+ attr_reader discovered_tools: Array[singleton(Riffer::Tool)]
11
+
12
+ # --
13
+ # : (String, Array[singleton(Riffer::Tool)]) -> void
14
+ def initialize: (String, Array[singleton(Riffer::Tool)]) -> void
15
+ end
16
+
17
+ # Searches progressive MCP tools and returns a +Result+ with +discovered_tools+.
18
+ # --
19
+ # : (context: Riffer::Agent::Context?, query: String) -> Riffer::Tools::Response
20
+ def call: (context: Riffer::Agent::Context?, query: String) -> Riffer::Tools::Response
21
+
22
+ private
23
+
24
+ # : (Array[singleton(Riffer::Tool)], String) -> Array[singleton(Riffer::Tool)]
25
+ def filter: (Array[singleton(Riffer::Tool)], String) -> Array[singleton(Riffer::Tool)]
26
+ end
@@ -1,25 +1,20 @@
1
1
  # Generated from lib/riffer/mcp/tool_factory.rb with RBS::Inline
2
2
 
3
3
  # Generates anonymous Riffer::Tool subclasses from MCP tool definitions.
4
- #
5
- # Each generated class:
6
- # - Has +.name+, +.description+, and +.parameters_schema+ derived from the MCP tool definition.
7
- # - Delegates +#call+ to the MCP client's +tools_call+ method.
8
- # - Skips Riffer's param validation — the MCP server validates inputs.
4
+ # Generated tools delegate +#call+ to the MCP client and skip Riffer's param
5
+ # validation the MCP server validates inputs.
9
6
  module Riffer::Mcp::ToolFactory
10
- # Builds one Riffer::Tool subclass per tool definition.
11
- #
12
- # Tool names are prefixed with the manifest name to avoid collisions
13
- # across MCP servers (e.g. +"jira__search"+). The original server-side
14
- # name is available via +.mcp_server_tool_name+.
15
- #
7
+ # Builds one Riffer::Tool subclass per tool definition, prefixing names with
8
+ # the manifest name to avoid cross-server collisions (e.g. +jira__search+);
9
+ # the server-side name stays on +.mcp_server_tool_name+.
16
10
  # --
17
11
  # : (String, Riffer::Mcp::Client, Array[Hash[Symbol, untyped]]) -> Array[singleton(Riffer::Tool)]
18
- def self.build: (String, Riffer::Mcp::Client, Array[Hash[Symbol, untyped]]) -> Array[singleton(Riffer::Tool)]
12
+ def build: (String, Riffer::Mcp::Client, Array[Hash[Symbol, untyped]]) -> Array[singleton(Riffer::Tool)]
13
+
14
+ private
19
15
 
20
- # Replaces characters that are unsafe in LLM tool names.
21
16
  # : (String) -> String
22
- def self.sanitize_name_component: (String) -> String
17
+ def sanitize_name_component: (String) -> String
23
18
 
24
- def self.build_tool_class: (untyped manifest_name, untyped client, untyped td) -> untyped
19
+ def build_tool_class: (untyped manifest_name, untyped client, untyped td) -> untyped
25
20
  end
@@ -1,9 +1,8 @@
1
1
  # Generated from lib/riffer/mcp.rb with RBS::Inline
2
2
 
3
- # Riffer::Mcp provides integration with Model Context Protocol (MCP) servers.
4
- #
5
- # Register MCP servers globally; agents opt-in by tag via the +use_mcp+ DSL.
6
- # Tags are application-defined; see +docs/14_MCP.md+ (Tags section).
3
+ # Integration with Model Context Protocol (MCP) servers. Register servers
4
+ # globally; agents opt-in by tag via the +use_mcp+ DSL. Tags are
5
+ # application-defined; see +docs/14_MCP.md+.
7
6
  #
8
7
  # Riffer::Mcp.register(
9
8
  # name: "github",
@@ -26,26 +25,20 @@ module Riffer::Mcp
26
25
  class CredentialsDeniedError < Error
27
26
  end
28
27
 
29
- # Registers an MCP server, blocking until tool discovery completes.
30
- #
31
- # Raises on discovery failure. Pass a +Manifest+ instance or a hash with
32
- # the same keys.
33
- #
28
+ # Registers an MCP server, blocking until tool discovery completes. Raises
29
+ # on discovery failure.
34
30
  # --
35
31
  # : ((Hash[Symbol, untyped] | Riffer::Mcp::Manifest)) -> Riffer::Mcp::Registration
36
- def self.register: (Hash[Symbol, untyped] | Riffer::Mcp::Manifest) -> Riffer::Mcp::Registration
32
+ def register: (Hash[Symbol, untyped] | Riffer::Mcp::Manifest) -> Riffer::Mcp::Registration
37
33
 
38
- # Removes a registration by name.
39
- #
40
- # Subsequent agent runs will not see tools from this server.
41
- #
34
+ # Removes a registration by name; subsequent agent runs won't see its tools.
42
35
  # --
43
36
  # : (String) -> void
44
- def self.unregister: (String) -> void
37
+ def unregister: (String) -> void
45
38
 
46
- # Returns all current registrations keyed by name (for introspection).
39
+ # Returns all current registrations keyed by name.
47
40
  #
48
41
  # --
49
42
  # : () -> Hash[String, Riffer::Mcp::Registration]
50
- def self.registrations: () -> Hash[String, Riffer::Mcp::Registration]
43
+ def registrations: () -> Hash[String, Riffer::Mcp::Registration]
51
44
  end
@@ -1,13 +1,7 @@
1
1
  # Generated from lib/riffer/messages/assistant.rb with RBS::Inline
2
2
 
3
- # Represents an assistant (LLM) message in a conversation.
4
- #
5
- # May include tool calls when the LLM requests tool execution.
6
- #
7
- # msg = Riffer::Messages::Assistant.new("Hello!")
8
- # msg.role # => :assistant
9
- # msg.content # => "Hello!"
10
- # msg.tool_calls # => []
3
+ # Represents an assistant (LLM) message in a conversation; may include tool
4
+ # calls when the LLM requests tool execution.
11
5
  class Riffer::Messages::Assistant < Riffer::Messages::Base
12
6
  class ToolCall < Struct[untyped]
13
7
  attr_accessor call_id(): untyped
@@ -1,9 +1,13 @@
1
1
  # Generated from lib/riffer/messages/base.rb with RBS::Inline
2
2
 
3
- # Base class for all message types in the Riffer framework.
4
- #
5
- # Subclasses must implement the +role+ method.
3
+ # Base class for all message types. Subclasses must implement +role+.
6
4
  class Riffer::Messages::Base
5
+ # Builds the matching message subclass from a hash, or returns +msg+ unchanged
6
+ # when it is already a message. Raises Riffer::ArgumentError on an invalid message.
7
+ # --
8
+ # : ((Hash[Symbol, untyped] | Riffer::Messages::Base)) -> Riffer::Messages::Base
9
+ def self.from_hash: (Hash[Symbol, untyped] | Riffer::Messages::Base) -> Riffer::Messages::Base
10
+
7
11
  # The message content.
8
12
  attr_reader content: String
9
13
 
@@ -21,27 +25,18 @@ class Riffer::Messages::Base
21
25
  def to_h: () -> Hash[Symbol, untyped]
22
26
 
23
27
  # Returns the message role.
24
- #
25
- # Raises NotImplementedError if not implemented by subclass.
26
- #
27
28
  # --
28
29
  # : () -> Symbol
29
30
  def role: () -> Symbol
30
31
 
31
- # Whether this message carries pending tool calls. Defaults to +false+;
32
- # +Riffer::Messages::Assistant+ overrides this when its +tool_calls+
33
- # array is non-empty.
34
- #
32
+ # Whether this message carries pending tool calls (overridden by
33
+ # +Riffer::Messages::Assistant+).
35
34
  # --
36
35
  # : () -> bool
37
36
  def has_tool_calls?: () -> bool
38
37
 
39
- # Merges another same-role message into this one.
40
- #
41
- # Raises NotImplementedError unless implemented by subclass. Mergeable
42
- # message types (+User+, +Assistant+, +System+) override this; +Tool+
43
- # messages are never merged.
44
- #
38
+ # Merges another same-role message into this one. +Tool+ messages are never
39
+ # merged.
45
40
  # --
46
41
  # : (untyped) -> Riffer::Messages::Base
47
42
  def +: (untyped) -> Riffer::Messages::Base
@@ -1,14 +1,7 @@
1
1
  # Generated from lib/riffer/messages/file_part.rb with RBS::Inline
2
2
 
3
- # Represents a file attachment (image or document) in a conversation.
4
- #
5
- # Supports two input sources:
6
- # - URLs (stored and passed to providers that support them via +from_url+)
7
- # - Raw base64 data (via +new+)
8
- #
9
- # file = Riffer::Messages::FilePart.from_url("https://example.com/doc.pdf", media_type: "application/pdf")
10
- # file.url? # => true
11
- # file.document? # => true
3
+ # Represents a file attachment (image or document) from a URL (+from_url+) or
4
+ # raw base64 data (+new+).
12
5
  class Riffer::Messages::FilePart
13
6
  @url_string: String?
14
7
 
@@ -22,28 +15,25 @@ class Riffer::Messages::FilePart
22
15
  # The filename, if available.
23
16
  attr_reader filename: String?
24
17
 
25
- # Creates a FilePart from raw base64 data or a URL.
26
- #
27
- # At least one of +data+ or +url+ must be provided.
28
- #
29
- # Raises Riffer::ArgumentError if neither data nor url is provided,
30
- # or if media_type is not supported.
31
- #
18
+ # Raises Riffer::ArgumentError unless +data+ or +url+ is given and
19
+ # +media_type+ is supported.
32
20
  # --
33
21
  # : (media_type: String, ?data: String?, ?filename: String?, ?url: String?) -> void
34
22
  def initialize: (media_type: String, ?data: String?, ?filename: String?, ?url: String?) -> void
35
23
 
36
- # Creates a FilePart from a URL.
37
- #
38
- # The URL is stored and passed directly to providers that support URL sources.
39
- # If +media_type+ is not provided, it is detected from the URL path extension.
40
- #
41
- # Raises Riffer::ArgumentError if media_type cannot be detected.
42
- #
24
+ # Creates a FilePart from a URL, detecting +media_type+ from the path
25
+ # extension when omitted. Raises Riffer::ArgumentError if it can't be detected.
43
26
  # --
44
27
  # : (String, ?media_type: String?) -> Riffer::Messages::FilePart
45
28
  def self.from_url: (String, ?media_type: String?) -> Riffer::Messages::FilePart
46
29
 
30
+ # Builds a FilePart from a +{url:, media_type:}+ or +{data:, media_type:}+ hash,
31
+ # or returns +file+ unchanged when it is already a FilePart. Raises
32
+ # Riffer::ArgumentError on an invalid hash.
33
+ # --
34
+ # : ((Hash[Symbol, untyped] | Riffer::Messages::FilePart)) -> Riffer::Messages::FilePart
35
+ def self.from_hash: (Hash[Symbol, untyped] | Riffer::Messages::FilePart) -> Riffer::Messages::FilePart
36
+
47
37
  # Returns the base64-encoded data, or nil for URL-only sources.
48
38
  attr_reader data: String?
49
39
 
@@ -1,10 +1,6 @@
1
1
  # Generated from lib/riffer/messages/system.rb with RBS::Inline
2
2
 
3
3
  # Represents a system message (instructions) in a conversation.
4
- #
5
- # msg = Riffer::Messages::System.new("You are a helpful assistant.")
6
- # msg.role # => :system
7
- # msg.content # => "You are a helpful assistant."
8
4
  class Riffer::Messages::System < Riffer::Messages::Base
9
5
  # --
10
6
  # : () -> Symbol
@@ -1,15 +1,6 @@
1
1
  # Generated from lib/riffer/messages/tool.rb with RBS::Inline
2
2
 
3
3
  # Represents a tool execution result in a conversation.
4
- #
5
- # msg = Riffer::Messages::Tool.new(
6
- # "The weather is sunny.",
7
- # tool_call_id: "call_123",
8
- # name: "weather_tool"
9
- # )
10
- # msg.role # => :tool
11
- # msg.tool_call_id # => "call_123"
12
- # msg.error? # => false
13
4
  class Riffer::Messages::Tool < Riffer::Messages::Base
14
5
  # The ID of the tool call this result responds to.
15
6
  attr_reader tool_call_id: String
@@ -1,19 +1,10 @@
1
1
  # Generated from lib/riffer/messages/user.rb with RBS::Inline
2
2
 
3
3
  # Represents a user message in a conversation.
4
- #
5
- # msg = Riffer::Messages::User.new("Hello!")
6
- # msg.role # => :user
7
- # msg.content # => "Hello!"
8
- #
9
- # msg = Riffer::Messages::User.new("Describe this image", files: [file_part])
10
- # msg.files # => [#<Riffer::Messages::FilePart ...>]
11
4
  class Riffer::Messages::User < Riffer::Messages::Base
12
5
  # File attachments for this message.
13
6
  attr_reader files: Array[Riffer::Messages::FilePart]
14
7
 
15
- # Initializes a user message.
16
- #
17
8
  # --
18
9
  # : (String, ?id: String?, ?files: Array[Riffer::Messages::FilePart]) -> void
19
10
  def initialize: (String, ?id: String?, ?files: Array[Riffer::Messages::FilePart]) -> void
@@ -1,11 +1,4 @@
1
1
  # Generated from lib/riffer/messages.rb with RBS::Inline
2
2
 
3
- # Namespace for message types in the Riffer framework.
4
- #
5
- # Message objects represent the conversation between users and the assistant:
6
- # - Riffer::Messages::System - System instructions
7
- # - Riffer::Messages::User - User input
8
- # - Riffer::Messages::Assistant - LLM responses
9
- # - Riffer::Messages::Tool - Tool execution results
10
3
  module Riffer::Messages
11
4
  end
@@ -1,9 +1,7 @@
1
1
  # Generated from lib/riffer/params/boolean.rb with RBS::Inline
2
2
 
3
- # Riffer::Params::Boolean is a sentinel type for declaring boolean parameters.
4
- #
5
- # Ruby has no +Boolean+ class (+true+ is +TrueClass+, +false+ is +FalseClass+).
6
- # Use this module wherever you need a single type that means "boolean":
3
+ # Sentinel type for declaring boolean parameters — Ruby has no +Boolean+ class
4
+ # (+true+/+false+ are +TrueClass+/+FalseClass+).
7
5
  #
8
6
  # required :verbose, Riffer::Params::Boolean
9
7
  module Riffer::Params::Boolean
@@ -1,8 +1,7 @@
1
1
  # Generated from lib/riffer/params/param.rb with RBS::Inline
2
2
 
3
- # Riffer::Params::Param represents a single parameter definition.
4
- #
5
- # Handles type validation and JSON Schema generation for individual parameters.
3
+ # A single parameter definition, handling type validation and JSON Schema
4
+ # generation.
6
5
  class Riffer::Params::Param
7
6
  # Maps Ruby types to JSON Schema type strings
8
7
  TYPE_MAPPINGS: Hash[Module, String]
@@ -10,54 +9,47 @@ class Riffer::Params::Param
10
9
  # Primitive types allowed for the <tt>of:</tt> keyword on Array params
11
10
  PRIMITIVE_TYPES: Array[Module]
12
11
 
13
- # Maps JSON Schema type strings back to Ruby types. The inverse of
14
- # TYPE_MAPPINGS, collapsing the three boolean spellings onto
15
- # Riffer::Params::Boolean. Used by +from_json_schema+.
12
+ # Maps JSON Schema type strings back to Ruby types (inverse of TYPE_MAPPINGS),
13
+ # collapsing the three boolean spellings onto Riffer::Params::Boolean.
16
14
  JSON_TYPE_MAPPINGS: Hash[String, Module]
17
15
 
16
+ # The parameter name.
18
17
  attr_reader name: Symbol
19
18
 
19
+ # The Ruby type.
20
20
  attr_reader type: Module
21
21
 
22
+ # Whether the parameter is required.
22
23
  attr_reader required: bool
23
24
 
25
+ # The parameter description, if any.
24
26
  attr_reader description: String?
25
27
 
28
+ # Allowed values, if constrained.
26
29
  attr_reader enum: Array[untyped]?
27
30
 
31
+ # The default value, if any.
28
32
  attr_reader default: untyped
29
33
 
34
+ # Element type for a typed array (+of:+).
30
35
  attr_reader item_type: Module?
31
36
 
37
+ # Nested Params for object / array-of-object types.
32
38
  attr_reader nested_params: Riffer::Params?
33
39
 
34
- # --
35
- # Reconstructs a Param from a single JSON Schema property.
36
- #
37
- # [name] the parameter name (Symbol).
38
- # [schema] the property's JSON Schema (Symbol-keyed).
39
- # [required] whether the property appeared in the parent's +required+ list.
40
- #
41
- # Raises Riffer::ArgumentError on a type outside the Params-expressible subset.
42
- #
40
+ # Reconstructs a Param from a single JSON Schema property. Raises
41
+ # Riffer::ArgumentError on a type outside the Params-expressible subset.
43
42
  # --
44
43
  # : (Symbol, Hash[Symbol, untyped], required: bool) -> Riffer::Params::Param
45
44
  def self.from_json_schema: (Symbol, Hash[Symbol, untyped], required: bool) -> Riffer::Params::Param
46
45
 
47
- # Resolves the +[item_type, nested_params]+ pair for a reconstructed Param:
48
- # a nested Params for object / array-of-object schemas, an +item_type+ for
49
- # typed primitive arrays, and +nil+ for everything else.
50
- #
51
46
  # --
52
47
  # : (Module, Hash[Symbol, untyped]) -> [Module?, Riffer::Params?]
53
48
  def self.resolve_nesting: (Module, Hash[Symbol, untyped]) -> [ Module?, Riffer::Params? ]
54
49
 
55
- # Resolves a JSON Schema +type+ (a String, or a <tt>[type, "null"]</tt>
56
- # union) back to its Ruby type. Returns a Module because
57
- # Riffer::Params::Boolean is a Module, not a Class — the same widening the
58
- # +type+ attribute uses. Raises Riffer::ArgumentError on a type outside the
59
- # Params-expressible subset (the block runs only for an unmapped type).
60
- #
50
+ # Resolves a JSON Schema +type+ (or a <tt>[type, "null"]</tt> union) to its
51
+ # Ruby type. Returns a Module — Riffer::Params::Boolean is a Module, not a
52
+ # Class. Raises Riffer::ArgumentError on an unsupported type.
61
53
  # --
62
54
  # : (untyped) -> Module
63
55
  def self.json_type_to_ruby: (untyped) -> Module
@@ -78,21 +70,11 @@ class Riffer::Params::Param
78
70
  # : () -> String
79
71
  def type_name: () -> String
80
72
 
81
- # Converts this parameter to JSON Schema format.
82
- #
83
- # When +strict+ is true, optional parameters are made nullable
84
- # (<tt>["type", "null"]</tt>) so that strict mode providers can distinguish
85
- # "absent" from "present" without rejecting the schema.
86
- #
87
- # Optional parameters with an +enum+ use +anyOf+ to separate the enum
88
- # constraint from the null type, since providers like Anthropic reject
73
+ # Converts this parameter to JSON Schema format. When +strict+, optional
74
+ # params are made nullable (<tt>["type", "null"]</tt>) so strict providers
75
+ # distinguish absent from present; optional params with an +enum+ use +anyOf+
76
+ # instead, since providers like Anthropic reject
89
77
  # <tt>{"type": ["string", "null"], "enum": [...]}</tt>.
90
- #
91
- # In non-strict mode a +default+ is emitted when set (a standard JSON
92
- # Schema keyword), making the schema a lossless source for
93
- # +Riffer::Params.from_json_schema+. Strict mode omits it, since strict
94
- # providers reject the keyword.
95
- #
96
78
  # --
97
79
  # : (?strict: bool) -> Hash[Symbol, untyped]
98
80
  def to_json_schema: (?strict: bool) -> Hash[Symbol, untyped]
@@ -1,32 +1,23 @@
1
1
  # Generated from lib/riffer/params.rb with RBS::Inline
2
2
 
3
- # Riffer::Params provides a DSL for defining parameters.
4
- #
5
- # Used within a Tool's +params+ block to define required and optional parameters,
6
- # and by StructuredOutput to define response schemas.
3
+ # A DSL for defining tool parameters and structured-output schemas, used within
4
+ # a Tool's +params+ block.
7
5
  #
8
6
  # params do
9
7
  # required :city, String, description: "The city name"
10
8
  # optional :units, String, default: "celsius", enum: ["celsius", "fahrenheit"]
11
9
  # end
12
10
  class Riffer::Params
11
+ # The defined parameters.
13
12
  attr_reader parameters: Array[Riffer::Params::Param]
14
13
 
15
14
  # --
16
15
  # : () -> void
17
16
  def initialize: () -> void
18
17
 
19
- # Reconstructs a Params from a JSON Schema object (the inverse of
20
- # +to_json_schema(strict: false)+).
21
- #
22
- # Accepts the Symbol-keyed object schema produced by +to_json_schema+
23
- # (property-name keys may be String or Symbol — both are normalized).
24
- # Reconstructs types, +required+, +description+, +enum+, +default+,
25
- # typed-array +item_type+, and nested object/array Params recursively.
26
- #
27
- # Round-trips losslessly with +to_json_schema(strict: false)+ over the
28
- # Params-expressible subset of JSON Schema. Raises Riffer::ArgumentError
29
- # on a schema using features outside that subset.
18
+ # Reconstructs a Params from a JSON Schema object the inverse of
19
+ # +to_json_schema(strict: false)+. Raises Riffer::ArgumentError on features
20
+ # outside the Params-expressible subset of JSON Schema.
30
21
  #
31
22
  # schema = params.to_json_schema(strict: false)
32
23
  # Riffer::Params.from_json_schema(schema) # => equivalent Riffer::Params
@@ -55,12 +46,9 @@ class Riffer::Params
55
46
  # : (Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
56
47
  def validate: (Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
57
48
 
58
- # Converts all parameters to JSON Schema format.
59
- #
60
- # When +strict+ is true, every property appears in +required+ and
61
- # optional properties are made nullable instead. This satisfies
62
- # providers that enforce strict structured output schemas.
63
- #
49
+ # Converts all parameters to JSON Schema format. When +strict+ is true, every
50
+ # property is listed in +required+ and optional ones are made nullable
51
+ # instead, satisfying providers that enforce strict structured output schemas.
64
52
  # --
65
53
  # : (?strict: bool) -> Hash[Symbol, untyped]
66
54
  def to_json_schema: (?strict: bool) -> Hash[Symbol, untyped]
@@ -1,28 +1,18 @@
1
1
  # Generated from lib/riffer/providers/amazon_bedrock.rb with RBS::Inline
2
2
 
3
- # Amazon Bedrock provider for Claude and other foundation models.
4
- #
5
- # Requires the +aws-sdk-bedrockruntime+ gem to be installed.
6
- #
7
- # See https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/BedrockRuntime/Client.html
3
+ # Amazon Bedrock provider for Claude and other foundation models. Requires the
4
+ # +aws-sdk-bedrockruntime+ gem.
8
5
  class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
9
- # Matches Anthropic models on Bedrock: bare ids like
10
- # +anthropic.claude-3-5-sonnet-20241022-v2:0+ and cross-region prefixed
11
- # ids like +us.anthropic.claude-sonnet-4-6+.
6
+ # Matches Anthropic models on Bedrock bare (+anthropic.claude-...+) and
7
+ # cross-region (+us.anthropic.claude-...+) ids.
12
8
  ANTHROPIC_MODEL_PATTERN: Regexp
13
9
 
14
- # Returns the preferred skill adapter for the given Bedrock model.
15
- #
16
- # Bedrock hosts models from multiple vendors. Anthropic models prefer
17
- # XML-rendered catalogs; everything else falls back to the default
18
- # Markdown adapter.
19
- #
10
+ # Returns the skill adapter for the Bedrock model — XML for Anthropic models
11
+ # (which Bedrock hosts alongside other vendors'), else Markdown.
20
12
  # --
21
13
  # : (?String?) -> singleton(Riffer::Skills::Adapter)
22
14
  def self.skills_adapter: (?String?) -> singleton(Riffer::Skills::Adapter)
23
15
 
24
- # Initializes the Amazon Bedrock provider.
25
- #
26
16
  # --
27
17
  # : (?api_token: String?, ?region: String?, **untyped) -> void
28
18
  def initialize: (?api_token: String?, ?region: String?, **untyped) -> void
@@ -33,6 +23,17 @@ class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
33
23
  # : (Array[Riffer::Messages::Base], String?, Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
34
24
  def build_request_params: (Array[Riffer::Messages::Base], String?, Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
35
25
 
26
+ # Converse chains +tools -> system -> messages+, so a single +cachePoint+ at
27
+ # the end of the system array (or the tools array, when there is no system
28
+ # prompt) also caches the preceding sections.
29
+ # --
30
+ # : (Hash[Symbol, untyped], untyped) -> void
31
+ def apply_cache_point: (Hash[Symbol, untyped], untyped) -> void
32
+
33
+ # --
34
+ # : (untyped) -> Hash[Symbol, untyped]
35
+ def build_cache_point: (untyped) -> Hash[Symbol, untyped]
36
+
36
37
  # --
37
38
  # : (Hash[Symbol, untyped]) -> untyped
38
39
  def execute_generate: (Hash[Symbol, untyped]) -> untyped
@@ -53,15 +54,10 @@ class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
53
54
  # : (Hash[Symbol, untyped], Enumerator::Yielder) -> void
54
55
  def execute_stream: (Hash[Symbol, untyped], Enumerator::Yielder) -> void
55
56
 
56
- # Re-raises a Bedrock stream exception event as the matching
57
- # +Aws::BedrockRuntime::Errors+ service error. ConverseStream delivers API
58
- # errors on the same channel as content, so without this a mid-stream
59
- # failure would silently end the enumerator with no tokens or content.
60
- #
61
- # Detection is by class-name suffix: every Bedrock stream-exception struct
62
- # is named +*Exception+ and has a matching +Aws::BedrockRuntime::Errors+
63
- # class of the same name (generated via +DynamicErrors+ if not explicit).
64
- # Non-exception events (e.g. +MessageStartEvent+) pass through silently.
57
+ # Re-raises a Bedrock stream-exception event as the matching
58
+ # +Aws::BedrockRuntime::Errors+ class. ConverseStream delivers API errors on
59
+ # the same channel as content, so without this a mid-stream failure would
60
+ # silently end the stream with no content.
65
61
  # --
66
62
  # : (untyped) -> void
67
63
  def raise_if_stream_exception!: (untyped) -> void
@@ -1,10 +1,7 @@
1
1
  # Generated from lib/riffer/providers/anthropic.rb with RBS::Inline
2
2
 
3
- # Anthropic provider for Claude models via the Anthropic API.
4
- #
5
- # Requires the +anthropic+ gem to be installed.
6
- #
7
- # See https://github.com/anthropics/anthropic-sdk-ruby
3
+ # Anthropic provider for Claude models via the Anthropic API. Requires the
4
+ # +anthropic+ gem.
8
5
  class Riffer::Providers::Anthropic < Riffer::Providers::Base
9
6
  WEB_SEARCH_TOOL_TYPE: String
10
7
 
@@ -14,8 +11,6 @@ class Riffer::Providers::Anthropic < Riffer::Providers::Base
14
11
  # : (?String?) -> singleton(Riffer::Skills::Adapter)
15
12
  def self.skills_adapter: (?String?) -> singleton(Riffer::Skills::Adapter)
16
13
 
17
- # Initializes the Anthropic provider.
18
- #
19
14
  # --
20
15
  # : (?api_key: String?, **untyped) -> void
21
16
  def initialize: (?api_key: String?, **untyped) -> void