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.
Files changed (258) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/rules/comments.md +2 -4
  3. data/.claude/rules/rbs-inline.md +2 -12
  4. data/.release-please-manifest.json +1 -1
  5. data/.rubocop.yml +5 -0
  6. data/CHANGELOG.md +19 -0
  7. data/docs/AGENTS.md +3 -5
  8. data/docs/AGENT_LIFECYCLE.md +13 -16
  9. data/docs/CONFIGURATION.md +22 -33
  10. data/docs/TOOL_ADVANCED.md +1 -3
  11. data/docs/TRACING.md +1 -1
  12. data/docs/providers/AMAZON_BEDROCK.md +31 -0
  13. data/docs/providers/OPENROUTER.md +18 -1
  14. data/docs-site/build.rb +0 -6
  15. data/docs-site/check.rb +1 -5
  16. data/lib/riffer/agent/config.rb +4 -45
  17. data/lib/riffer/agent/context.rb +2 -26
  18. data/lib/riffer/agent/outcome.rb +0 -20
  19. data/lib/riffer/agent/response.rb +0 -38
  20. data/lib/riffer/agent/run.rb +11 -43
  21. data/lib/riffer/agent/serializer.rb +10 -39
  22. data/lib/riffer/agent/session/repair.rb +3 -15
  23. data/lib/riffer/agent/session.rb +25 -38
  24. data/lib/riffer/agent/structured_output/result.rb +0 -8
  25. data/lib/riffer/agent/structured_output.rb +0 -7
  26. data/lib/riffer/agent.rb +10 -130
  27. data/lib/riffer/config/amazon_bedrock.rb +30 -0
  28. data/lib/riffer/config/anthropic.rb +21 -0
  29. data/lib/riffer/config/azure_open_ai.rb +30 -0
  30. data/lib/riffer/config/evals.rb +18 -0
  31. data/lib/riffer/config/files.rb +61 -0
  32. data/lib/riffer/config/gemini.rb +21 -0
  33. data/lib/riffer/config/mcp.rb +31 -0
  34. data/lib/riffer/config/open_ai.rb +30 -0
  35. data/lib/riffer/config/open_router.rb +21 -0
  36. data/lib/riffer/config/pricing/rates.rb +36 -0
  37. data/lib/riffer/config/pricing.rb +64 -0
  38. data/lib/riffer/config/skills.rb +38 -0
  39. data/lib/riffer/config/tracing.rb +43 -0
  40. data/lib/riffer/config.rb +3 -362
  41. data/lib/riffer/evals/evaluator.rb +1 -29
  42. data/lib/riffer/evals/evaluator_runner.rb +0 -15
  43. data/lib/riffer/evals/judge.rb +0 -8
  44. data/lib/riffer/evals/result.rb +1 -11
  45. data/lib/riffer/evals/run_result.rb +0 -12
  46. data/lib/riffer/evals/scenario_result.rb +0 -19
  47. data/lib/riffer/files/downloader.rb +2 -3
  48. data/lib/riffer/files/resolver.rb +2 -7
  49. data/lib/riffer/guardrail.rb +2 -22
  50. data/lib/riffer/guardrails/modification.rb +0 -8
  51. data/lib/riffer/guardrails/result.rb +0 -17
  52. data/lib/riffer/guardrails/runner.rb +2 -11
  53. data/lib/riffer/guardrails/tripwire.rb +0 -8
  54. data/lib/riffer/guardrails.rb +0 -2
  55. data/lib/riffer/helpers/boolean.rb +0 -4
  56. data/lib/riffer/helpers/call_or_value.rb +0 -3
  57. data/lib/riffer/helpers/deep_dup.rb +3 -8
  58. data/lib/riffer/helpers/dependencies.rb +0 -4
  59. data/lib/riffer/helpers/identifier.rb +3 -12
  60. data/lib/riffer/helpers/validate.rb +42 -0
  61. data/lib/riffer/mcp/authenticated_tool.rb +4 -12
  62. data/lib/riffer/mcp/client.rb +0 -7
  63. data/lib/riffer/mcp/manifest.rb +3 -7
  64. data/lib/riffer/mcp/registration.rb +0 -10
  65. data/lib/riffer/mcp/registry.rb +0 -9
  66. data/lib/riffer/mcp/search_tool.rb +0 -4
  67. data/lib/riffer/mcp/tool.rb +1 -4
  68. data/lib/riffer/mcp/tool_factory.rb +3 -6
  69. data/lib/riffer/mcp.rb +2 -23
  70. data/lib/riffer/messages/assistant/reasoning_part.rb +4 -21
  71. data/lib/riffer/messages/assistant/tool_call.rb +1 -9
  72. data/lib/riffer/messages/assistant.rb +1 -21
  73. data/lib/riffer/messages/base.rb +0 -12
  74. data/lib/riffer/messages/system.rb +0 -3
  75. data/lib/riffer/messages/tool.rb +0 -15
  76. data/lib/riffer/messages/user/file_part.rb +2 -30
  77. data/lib/riffer/messages/user.rb +0 -4
  78. data/lib/riffer/params/boolean.rb +1 -5
  79. data/lib/riffer/params/param.rb +3 -31
  80. data/lib/riffer/params.rb +8 -41
  81. data/lib/riffer/providers/amazon_bedrock.rb +101 -42
  82. data/lib/riffer/providers/anthropic.rb +9 -24
  83. data/lib/riffer/providers/azure_open_ai.rb +3 -8
  84. data/lib/riffer/providers/base.rb +7 -28
  85. data/lib/riffer/providers/finish_reason.rb +0 -6
  86. data/lib/riffer/providers/gemini/client.rb +4 -17
  87. data/lib/riffer/providers/gemini.rb +4 -10
  88. data/lib/riffer/providers/mock.rb +1 -26
  89. data/lib/riffer/providers/open_ai.rb +7 -17
  90. data/lib/riffer/providers/open_router.rb +105 -30
  91. data/lib/riffer/providers/repository.rb +2 -14
  92. data/lib/riffer/providers/token_usage.rb +5 -14
  93. data/lib/riffer/registrable.rb +11 -45
  94. data/lib/riffer/runner/fibers.rb +1 -6
  95. data/lib/riffer/runner/sequential.rb +0 -1
  96. data/lib/riffer/runner/threaded.rb +0 -3
  97. data/lib/riffer/runner.rb +0 -3
  98. data/lib/riffer/skills/activate_tool.rb +0 -3
  99. data/lib/riffer/skills/adapter.rb +0 -8
  100. data/lib/riffer/skills/backend.rb +2 -7
  101. data/lib/riffer/skills/config.rb +4 -20
  102. data/lib/riffer/skills/context.rb +0 -29
  103. data/lib/riffer/skills/filesystem_backend.rb +0 -7
  104. data/lib/riffer/skills/frontmatter.rb +2 -16
  105. data/lib/riffer/skills/markdown_adapter.rb +3 -6
  106. data/lib/riffer/skills/xml_adapter.rb +0 -3
  107. data/lib/riffer/stream_events/base.rb +0 -3
  108. data/lib/riffer/stream_events/finish_reason_done.rb +1 -6
  109. data/lib/riffer/stream_events/guardrail_modification.rb +0 -10
  110. data/lib/riffer/stream_events/guardrail_tripwire.rb +0 -10
  111. data/lib/riffer/stream_events/interrupt.rb +2 -12
  112. data/lib/riffer/stream_events/reasoning_delta.rb +0 -3
  113. data/lib/riffer/stream_events/reasoning_done.rb +1 -5
  114. data/lib/riffer/stream_events/skill_activation.rb +0 -3
  115. data/lib/riffer/stream_events/text_delta.rb +0 -2
  116. data/lib/riffer/stream_events/text_done.rb +0 -2
  117. data/lib/riffer/stream_events/token_usage_done.rb +0 -2
  118. data/lib/riffer/stream_events/tool_call_delta.rb +1 -5
  119. data/lib/riffer/stream_events/tool_call_done.rb +0 -5
  120. data/lib/riffer/stream_events/web_search_done.rb +0 -3
  121. data/lib/riffer/stream_events/web_search_status.rb +1 -5
  122. data/lib/riffer/testing/minitest.rb +4 -5
  123. data/lib/riffer/testing.rb +5 -38
  124. data/lib/riffer/tool.rb +2 -28
  125. data/lib/riffer/tools/response.rb +3 -32
  126. data/lib/riffer/tools/runtime/fibers.rb +0 -6
  127. data/lib/riffer/tools/runtime/inline.rb +0 -1
  128. data/lib/riffer/tools/runtime/threaded.rb +0 -6
  129. data/lib/riffer/tools/runtime.rb +5 -26
  130. data/lib/riffer/tools/toolable.rb +0 -37
  131. data/lib/riffer/tracing/capture.rb +3 -5
  132. data/lib/riffer/tracing/no_op.rb +0 -7
  133. data/lib/riffer/tracing/otel.rb +7 -16
  134. data/lib/riffer/tracing/stream_recorder.rb +0 -7
  135. data/lib/riffer/tracing.rb +4 -27
  136. data/lib/riffer/version.rb +1 -1
  137. data/lib/riffer.rb +2 -30
  138. data/sig/generated/riffer/agent/config.rbs +12 -48
  139. data/sig/generated/riffer/agent/context.rbs +2 -26
  140. data/sig/generated/riffer/agent/outcome.rbs +0 -20
  141. data/sig/generated/riffer/agent/response.rbs +1 -29
  142. data/sig/generated/riffer/agent/run.rbs +1 -27
  143. data/sig/generated/riffer/agent/serializer.rbs +2 -27
  144. data/sig/generated/riffer/agent/session/repair.rbs +2 -10
  145. data/sig/generated/riffer/agent/session.rbs +10 -36
  146. data/sig/generated/riffer/agent/structured_output/result.rbs +0 -7
  147. data/sig/generated/riffer/agent/structured_output.rbs +0 -7
  148. data/sig/generated/riffer/agent.rbs +5 -121
  149. data/sig/generated/riffer/config/amazon_bedrock.rbs +21 -0
  150. data/sig/generated/riffer/config/anthropic.rbs +15 -0
  151. data/sig/generated/riffer/config/azure_open_ai.rbs +21 -0
  152. data/sig/generated/riffer/config/evals.rbs +13 -0
  153. data/sig/generated/riffer/config/files.rbs +43 -0
  154. data/sig/generated/riffer/config/gemini.rbs +15 -0
  155. data/sig/generated/riffer/config/mcp.rbs +19 -0
  156. data/sig/generated/riffer/config/open_ai.rbs +21 -0
  157. data/sig/generated/riffer/config/open_router.rbs +15 -0
  158. data/sig/generated/riffer/config/pricing/rates.rbs +19 -0
  159. data/sig/generated/riffer/config/pricing.rbs +31 -0
  160. data/sig/generated/riffer/config/skills.rbs +19 -0
  161. data/sig/generated/riffer/config/tracing.rbs +25 -0
  162. data/sig/generated/riffer/config.rbs +2 -307
  163. data/sig/generated/riffer/evals/evaluator.rbs +0 -28
  164. data/sig/generated/riffer/evals/evaluator_runner.rbs +0 -14
  165. data/sig/generated/riffer/evals/judge.rbs +0 -7
  166. data/sig/generated/riffer/evals/result.rbs +1 -11
  167. data/sig/generated/riffer/evals/run_result.rbs +0 -12
  168. data/sig/generated/riffer/evals/scenario_result.rbs +0 -14
  169. data/sig/generated/riffer/files/resolver.rbs +0 -7
  170. data/sig/generated/riffer/guardrail.rbs +2 -22
  171. data/sig/generated/riffer/guardrails/modification.rbs +0 -6
  172. data/sig/generated/riffer/guardrails/result.rbs +0 -15
  173. data/sig/generated/riffer/guardrails/runner.rbs +0 -11
  174. data/sig/generated/riffer/guardrails/tripwire.rbs +0 -8
  175. data/sig/generated/riffer/guardrails.rbs +0 -2
  176. data/sig/generated/riffer/helpers/boolean.rbs +0 -4
  177. data/sig/generated/riffer/helpers/call_or_value.rbs +0 -3
  178. data/sig/generated/riffer/helpers/deep_dup.rbs +0 -8
  179. data/sig/generated/riffer/helpers/dependencies.rbs +0 -4
  180. data/sig/generated/riffer/helpers/identifier.rbs +0 -12
  181. data/sig/generated/riffer/helpers/validate.rbs +21 -0
  182. data/sig/generated/riffer/mcp/authenticated_tool.rbs +0 -5
  183. data/sig/generated/riffer/mcp/client.rbs +0 -7
  184. data/sig/generated/riffer/mcp/manifest.rbs +3 -7
  185. data/sig/generated/riffer/mcp/registration.rbs +0 -10
  186. data/sig/generated/riffer/mcp/registry.rbs +0 -9
  187. data/sig/generated/riffer/mcp/search_tool.rbs +0 -4
  188. data/sig/generated/riffer/mcp/tool.rbs +0 -4
  189. data/sig/generated/riffer/mcp/tool_factory.rbs +0 -6
  190. data/sig/generated/riffer/mcp.rbs +2 -22
  191. data/sig/generated/riffer/messages/assistant/reasoning_part.rbs +4 -17
  192. data/sig/generated/riffer/messages/assistant/tool_call.rbs +1 -9
  193. data/sig/generated/riffer/messages/assistant.rbs +10 -30
  194. data/sig/generated/riffer/messages/base.rbs +0 -12
  195. data/sig/generated/riffer/messages/system.rbs +0 -3
  196. data/sig/generated/riffer/messages/tool.rbs +0 -12
  197. data/sig/generated/riffer/messages/user/file_part.rbs +0 -30
  198. data/sig/generated/riffer/messages/user.rbs +0 -4
  199. data/sig/generated/riffer/params/boolean.rbs +1 -4
  200. data/sig/generated/riffer/params/param.rbs +0 -31
  201. data/sig/generated/riffer/params.rbs +4 -40
  202. data/sig/generated/riffer/providers/amazon_bedrock.rbs +29 -25
  203. data/sig/generated/riffer/providers/anthropic.rbs +0 -10
  204. data/sig/generated/riffer/providers/azure_open_ai.rbs +0 -8
  205. data/sig/generated/riffer/providers/base.rbs +0 -28
  206. data/sig/generated/riffer/providers/finish_reason.rbs +0 -6
  207. data/sig/generated/riffer/providers/gemini/client.rbs +4 -17
  208. data/sig/generated/riffer/providers/gemini.rbs +0 -6
  209. data/sig/generated/riffer/providers/mock.rbs +0 -26
  210. data/sig/generated/riffer/providers/open_ai.rbs +2 -9
  211. data/sig/generated/riffer/providers/open_router.rbs +33 -14
  212. data/sig/generated/riffer/providers/repository.rbs +2 -14
  213. data/sig/generated/riffer/providers/token_usage.rbs +5 -14
  214. data/sig/generated/riffer/registrable.rbs +0 -45
  215. data/sig/generated/riffer/runner/fibers.rbs +0 -6
  216. data/sig/generated/riffer/runner/sequential.rbs +0 -1
  217. data/sig/generated/riffer/runner/threaded.rbs +0 -3
  218. data/sig/generated/riffer/runner.rbs +0 -3
  219. data/sig/generated/riffer/skills/activate_tool.rbs +0 -3
  220. data/sig/generated/riffer/skills/adapter.rbs +0 -8
  221. data/sig/generated/riffer/skills/backend.rbs +2 -7
  222. data/sig/generated/riffer/skills/config.rbs +0 -20
  223. data/sig/generated/riffer/skills/context.rbs +0 -29
  224. data/sig/generated/riffer/skills/filesystem_backend.rbs +0 -7
  225. data/sig/generated/riffer/skills/frontmatter.rbs +2 -16
  226. data/sig/generated/riffer/skills/markdown_adapter.rbs +0 -6
  227. data/sig/generated/riffer/skills/xml_adapter.rbs +0 -3
  228. data/sig/generated/riffer/stream_events/base.rbs +0 -3
  229. data/sig/generated/riffer/stream_events/finish_reason_done.rbs +1 -6
  230. data/sig/generated/riffer/stream_events/guardrail_modification.rbs +0 -10
  231. data/sig/generated/riffer/stream_events/guardrail_tripwire.rbs +0 -10
  232. data/sig/generated/riffer/stream_events/interrupt.rbs +2 -10
  233. data/sig/generated/riffer/stream_events/reasoning_delta.rbs +0 -3
  234. data/sig/generated/riffer/stream_events/reasoning_done.rbs +1 -5
  235. data/sig/generated/riffer/stream_events/skill_activation.rbs +0 -3
  236. data/sig/generated/riffer/stream_events/text_delta.rbs +0 -2
  237. data/sig/generated/riffer/stream_events/text_done.rbs +0 -2
  238. data/sig/generated/riffer/stream_events/token_usage_done.rbs +0 -2
  239. data/sig/generated/riffer/stream_events/tool_call_delta.rbs +1 -5
  240. data/sig/generated/riffer/stream_events/tool_call_done.rbs +0 -5
  241. data/sig/generated/riffer/stream_events/web_search_done.rbs +0 -3
  242. data/sig/generated/riffer/stream_events/web_search_status.rbs +1 -5
  243. data/sig/generated/riffer/testing.rbs +0 -38
  244. data/sig/generated/riffer/tool.rbs +0 -27
  245. data/sig/generated/riffer/tools/response.rbs +3 -29
  246. data/sig/generated/riffer/tools/runtime/fibers.rbs +0 -5
  247. data/sig/generated/riffer/tools/runtime/inline.rbs +0 -1
  248. data/sig/generated/riffer/tools/runtime/threaded.rbs +0 -5
  249. data/sig/generated/riffer/tools/runtime.rbs +2 -24
  250. data/sig/generated/riffer/tools/toolable.rbs +0 -37
  251. data/sig/generated/riffer/tracing/capture.rbs +2 -5
  252. data/sig/generated/riffer/tracing/no_op.rbs +0 -7
  253. data/sig/generated/riffer/tracing/otel.rbs +7 -16
  254. data/sig/generated/riffer/tracing/stream_recorder.rbs +0 -2
  255. data/sig/generated/riffer/tracing.rbs +4 -23
  256. data/sig/generated/riffer.rbs +2 -29
  257. data/sig/manual/riffer/helpers/validate.rbs +5 -0
  258. metadata +30 -1
@@ -1,40 +1,20 @@
1
1
  # Generated from lib/riffer/agent/outcome.rb with RBS::Inline
2
2
 
3
- # How a run ended — the single place to read whether the agent completed
4
- # normally and, if not, why. +detail+ carries the specifics when there are any:
5
- # the tripwire reason, the interrupt reason, the provider's raw finish value,
6
- # or the structured output parse/validation error.
7
- #
8
- # response = agent.generate("Analyze this")
9
- # case response.outcome.reason
10
- # when :completed then puts response.structured_output
11
- # when :invalid_structured_output then warn response.outcome.detail
12
- # end
13
3
  class Riffer::Agent::Outcome
14
- # Finish reasons that end a turn normally; every other finish reason means the
15
- # provider cut the turn short and surfaces as the run's outcome verbatim.
16
4
  NORMAL_FINISH_REASONS: Array[Symbol]
17
5
 
18
- # Derived from the provider vocabulary so a new finish reason becomes an
19
- # outcome without a second list to update.
20
6
  PROVIDER_STOP_REASONS: Array[Symbol]
21
7
 
22
- # The vocabulary every run ends in.
23
8
  VALUES: Array[Symbol]
24
9
 
25
- # Why the run ended.
26
10
  attr_reader reason: Symbol
27
11
 
28
- # Human-readable specifics for +reason+, when there are any.
29
12
  attr_reader detail: String?
30
13
 
31
- # Raises Riffer::ArgumentError when +reason+ is outside VALUES.
32
14
  # --
33
15
  # : (reason: Symbol, ?detail: String?) -> void
34
16
  def initialize: (reason: Symbol, ?detail: String?) -> void
35
17
 
36
- # Returns true when the run completed normally.
37
- #
38
18
  # --
39
19
  # : () -> bool
40
20
  def success?: () -> bool
@@ -1,49 +1,24 @@
1
1
  # Generated from lib/riffer/agent/response.rb with RBS::Inline
2
2
 
3
- # Wraps an agent generation response. +outcome+ says how the run ended; when a
4
- # guardrail blocks execution, +content+ is empty and +tripwire+ carries the
5
- # block details.
6
- #
7
- # response = agent.generate("Hello")
8
- # if response.outcome.success?
9
- # puts response.content
10
- # else
11
- # puts "#{response.outcome.reason}: #{response.outcome.detail}"
12
- # end
13
3
  class Riffer::Agent::Response
14
- # The response content.
15
4
  attr_reader content: String
16
5
 
17
- # How the run ended.
18
6
  attr_reader outcome: Riffer::Agent::Outcome
19
7
 
20
- # The tripwire if execution was blocked.
21
8
  attr_reader tripwire: Riffer::Guardrails::Tripwire?
22
9
 
23
- # The modifications made by guardrails during processing.
24
10
  attr_reader modifications: Array[Riffer::Guardrails::Modification]
25
11
 
26
- # The reasoning parts on the final assistant message, if the provider
27
- # produced any.
28
12
  attr_reader reasoning: Array[Riffer::Messages::Assistant::ReasoningPart]
29
13
 
30
- # The parsed structured output, if structured output was configured.
31
14
  attr_reader structured_output: Hash[Symbol, untyped]?
32
15
 
33
- # The aggregate token usage across this run's LLM calls, if any was reported.
34
16
  attr_reader token_usage: Riffer::Providers::TokenUsage?
35
17
 
36
- # The number of LLM calls made during this run (0 when a before-guardrail
37
- # blocks before any call). Distinct from the session's cumulative step count.
38
18
  attr_reader steps: Integer
39
19
 
40
- # The full message history from the agent conversation.
41
20
  attr_reader messages: Array[Riffer::Messages::Base]
42
21
 
43
- # Call ids of tool_use blocks riffer filled with placeholder results this
44
- # turn (when an interrupt left them unanswered and history healing is on).
45
- attr_reader healed_tool_call_ids: Array[String]
46
-
47
22
  # --
48
23
  # : (
49
24
  # String,
@@ -53,14 +28,11 @@ class Riffer::Agent::Response
53
28
  # ?reasoning: Array[Riffer::Messages::Assistant::ReasoningPart],
54
29
  # ?structured_output: Hash[Symbol, untyped]?,
55
30
  # ?messages: Array[Riffer::Messages::Base],
56
- # ?healed_tool_call_ids: Array[String],
57
31
  # ?token_usage: Riffer::Providers::TokenUsage?,
58
32
  # ?steps: Integer
59
33
  # ) -> void
60
- def initialize: (String, outcome: Riffer::Agent::Outcome, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?reasoning: Array[Riffer::Messages::Assistant::ReasoningPart], ?structured_output: Hash[Symbol, untyped]?, ?messages: Array[Riffer::Messages::Base], ?healed_tool_call_ids: Array[String], ?token_usage: Riffer::Providers::TokenUsage?, ?steps: Integer) -> void
34
+ def initialize: (String, outcome: Riffer::Agent::Outcome, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?reasoning: Array[Riffer::Messages::Assistant::ReasoningPart], ?structured_output: Hash[Symbol, untyped]?, ?messages: Array[Riffer::Messages::Base], ?token_usage: Riffer::Providers::TokenUsage?, ?steps: Integer) -> void
61
35
 
62
- # Returns true if any guardrail modified data during processing.
63
- #
64
36
  # --
65
37
  # : () -> bool
66
38
  def modified?: () -> bool
@@ -1,30 +1,16 @@
1
1
  # Generated from lib/riffer/agent/run.rb with RBS::Inline
2
2
 
3
- # The generation loop — a pure module of functions over an +agent+, which owns
4
- # every per-call value; Run just orchestrates.
5
3
  module Riffer::Agent::Run
6
- # Runs the generate loop for the given agent. See Riffer::Agent#generate
7
- # for prompt/files semantics.
8
- #
9
4
  # --
10
5
  # : (agent: Riffer::Agent, ?prompt: String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?tags: Hash[(String | Symbol), untyped]) -> Riffer::Agent::Response
11
6
  def generate: (agent: Riffer::Agent, ?prompt: String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?tags: Hash[String | Symbol, untyped]) -> Riffer::Agent::Response
12
7
 
13
- # Runs the streaming loop for the given agent. See Riffer::Agent#stream
14
- # for prompt/files semantics.
15
- #
16
8
  # --
17
9
  # : (agent: Riffer::Agent, ?prompt: String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?tags: Hash[(String | Symbol), untyped]) -> Enumerator[Riffer::StreamEvents::Base, Riffer::Agent::Response]
18
10
  def stream: (agent: Riffer::Agent, ?prompt: String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?, ?tags: Hash[String | Symbol, untyped]) -> Enumerator[Riffer::StreamEvents::Base, Riffer::Agent::Response]
19
11
 
20
12
  private
21
13
 
22
- # Both +generate+ and +stream+ funnel here, so this is the single place raw
23
- # +tags+ are normalized and merged over the default tags (a caller tag wins
24
- # on a shared key). The clean <tt>String => String</tt> map is then
25
- # threaded to every span builder in the run as +riffer.tag.*+ and to each
26
- # provider call (via +merged_model_options+) for native request-metadata
27
- # mapping.
28
14
  # --
29
15
  # : (Riffer::Agent, ?tags: Hash[(String | Symbol), untyped]?, ?stream_yielder: Enumerator::Yielder?) -> Riffer::Agent::Response
30
16
  def run_loop: (Riffer::Agent, ?tags: Hash[String | Symbol, untyped]?, ?stream_yielder: Enumerator::Yielder?) -> Riffer::Agent::Response
@@ -49,10 +35,6 @@ module Riffer::Agent::Run
49
35
  # : (Riffer::Agent, Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, **untyped) -> Riffer::Agent::Response
50
36
  def final_response: (Riffer::Agent, Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, **untyped) -> Riffer::Agent::Response
51
37
 
52
- # Checked in the order things happened. The loop being stopped (max_steps or
53
- # an interrupt) beats the provider's finish reason, which beats riffer's own
54
- # validation of the content. A truncated response that also fails the schema
55
- # therefore reports :length, not :invalid_structured_output.
56
38
  # --
57
39
  # : (Riffer::Messages::Assistant?, Riffer::Agent::StructuredOutput::Result?, interrupted: bool, interrupt_reason: (String | Symbol)?) -> Riffer::Agent::Outcome
58
40
  def final_outcome: (Riffer::Messages::Assistant?, Riffer::Agent::StructuredOutput::Result?, interrupted: bool, interrupt_reason: (String | Symbol)?) -> Riffer::Agent::Outcome
@@ -93,15 +75,10 @@ module Riffer::Agent::Run
93
75
  # : (Riffer::Agent) -> Array[singleton(Riffer::Tool)]
94
76
  def effective_tools: (Riffer::Agent) -> Array[singleton(Riffer::Tool)]
95
77
 
96
- # +tags+ rides in the options hash as a curated key the providers extract for
97
- # native request-metadata mapping (alongside +:structured_output+); it never
98
- # reaches an SDK call verbatim. Span tagging is threaded separately to each
99
- # builder.
100
78
  # --
101
79
  # : (Riffer::Agent, ?Hash[String, String]) -> Hash[Symbol, untyped]
102
80
  def merged_model_options: (Riffer::Agent, ?Hash[String, String]) -> Hash[Symbol, untyped]
103
81
 
104
- # The tags riffer adds to every run, identifying the agent it's on behalf of.
105
82
  # --
106
83
  # : (Riffer::Agent) -> Hash[String, String]
107
84
  def default_tags: (Riffer::Agent) -> Hash[String, String]
@@ -115,14 +92,11 @@ module Riffer::Agent::Run
115
92
  # ?modifications: Array[Riffer::Guardrails::Modification],
116
93
  # ?reasoning: Array[Riffer::Messages::Assistant::ReasoningPart],
117
94
  # ?structured_output: Hash[Symbol, untyped]?,
118
- # ?healed_tool_call_ids: Array[String],
119
95
  # ?token_usage: Riffer::Providers::TokenUsage?,
120
96
  # ?steps: Integer
121
97
  # ) -> Riffer::Agent::Response
122
- def build_response: (Riffer::Agent, String, outcome: Riffer::Agent::Outcome, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?reasoning: Array[Riffer::Messages::Assistant::ReasoningPart], ?structured_output: Hash[Symbol, untyped]?, ?healed_tool_call_ids: Array[String], ?token_usage: Riffer::Providers::TokenUsage?, ?steps: Integer) -> Riffer::Agent::Response
98
+ def build_response: (Riffer::Agent, String, outcome: Riffer::Agent::Outcome, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?reasoning: Array[Riffer::Messages::Assistant::ReasoningPart], ?structured_output: Hash[Symbol, untyped]?, ?token_usage: Riffer::Providers::TokenUsage?, ?steps: Integer) -> Riffer::Agent::Response
123
99
 
124
- # Raises when +files+ are supplied without a +prompt+ — the provider needs
125
- # text to anchor the attachments.
126
100
  # --
127
101
  # : (Riffer::Agent, String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?) -> void
128
102
  def append_user_message: (Riffer::Agent, String?, ?files: Array[Hash[Symbol, untyped] | Riffer::Messages::User::FilePart]?) -> void
@@ -1,48 +1,27 @@
1
1
  # Generated from lib/riffer/agent/serializer.rb with RBS::Inline
2
2
 
3
- # Turns a resolved agent into a self-contained, provider-neutral data hash and
4
- # back into a runnable agent, behind the +Riffer::Agent#to_h+ /
5
- # +Riffer::Agent.from_h+ delegators.
6
- #
7
- # hash = Riffer::Agent::Serializer.to_h(agent: agent)
8
- # rebuilt = Riffer::Agent::Serializer.from_h(hash, context: {tenant: "acme"})
9
3
  module Riffer::Agent::Serializer
10
- # The wire format version, bumped only on an incompatible change to the hash
11
- # shape; +from_h+ refuses any other version.
4
+ # Bump only on an incompatible change to the hash shape.
12
5
  SCHEMA_VERSION: Integer
13
6
 
14
- # Raised by +from_h+ when the hash's +schema_version+ is unsupported.
15
7
  class VersionError < Riffer::ArgumentError
16
8
  end
17
9
 
18
- # The default +tool_resolver+: synthesizes a body-less tool shell from a
19
- # descriptor. Its +#call+ raises — route shells through a remote runtime.
20
10
  DEFAULT_TOOL_RESOLVER: ^(Hash[Symbol, untyped]) -> singleton(Riffer::Tool)
21
11
 
22
- # Snapshots a resolved agent into a self-contained wire hash. Proc-based
23
- # settings are already evaluated against the agent's context, so the hash
24
- # carries plain data, never Procs.
25
12
  # --
26
13
  # : (agent: Riffer::Agent) -> Hash[Symbol, untyped]
27
14
  def to_h: (agent: Riffer::Agent) -> Hash[Symbol, untyped]
28
15
 
29
- # Reconstructs a runnable agent from a wire hash. +context+ is threaded into
30
- # tool dispatch (not used to re-resolve the already-resolved config);
31
- # +session+ seeds conversation history (the hash carries the agent definition,
32
- # not its history). Raises Riffer::Agent::Serializer::VersionError on an
33
- # unsupported +schema_version+.
34
- #
16
+ # Raises Riffer::Agent::Serializer::VersionError on an unsupported +schema_version+.
35
17
  # --
36
18
  # : (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
37
19
  def 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
38
20
 
39
- # Snapshots a resolved agent to a JSON string.
40
21
  # --
41
22
  # : (agent: Riffer::Agent) -> String
42
23
  def to_json: (agent: Riffer::Agent) -> String
43
24
 
44
- # Reconstructs a runnable agent from a JSON string produced by +to_json+. See
45
- # +from_h+ for the arguments.
46
25
  # --
47
26
  # : (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
48
27
  def 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
@@ -57,14 +36,10 @@ module Riffer::Agent::Serializer
57
36
  # : (Hash[Symbol, untyped]?) -> Riffer::Params?
58
37
  def decode_structured_output: (Hash[Symbol, untyped]?) -> Riffer::Params?
59
38
 
60
- # Encodes unlimited steps (+nil+ in the DSL) as +-1+ on the wire, where a
61
- # JSON +null+ is awkward across transports (e.g. proto3).
62
39
  # --
63
40
  # : (Numeric?) -> Numeric
64
41
  def encode_max_steps: (Numeric?) -> Numeric
65
42
 
66
- # Reverses +encode_max_steps+; a missing key falls back to the default so a
67
- # partial hash can't become an unbounded loop.
68
43
  # --
69
44
  # : (Hash[Symbol, untyped]) -> Numeric?
70
45
  def decode_max_steps: (Hash[Symbol, untyped]) -> Numeric?
@@ -1,22 +1,14 @@
1
1
  # Generated from lib/riffer/agent/session/repair.rb with RBS::Inline
2
2
 
3
- # Pure, stateless transformations keeping the +tool_use+ ↔ +tool_result+
4
- # invariant on a message array. Each entry point no-ops when
5
- # +Riffer.config.experimental_history_healing+ is off.
3
+ # Maintains the invariant that every +tool_use+ has a matching +tool_result+
4
+ # and every +tool_result+ has a parent +tool_use+.
6
5
  module Riffer::Agent::Session::Repair
7
- # Placeholder response filled in for an orphaned +tool_use+ on interrupt.
8
6
  ORPHAN_PLACEHOLDER: ^(Riffer::Messages::Assistant::ToolCall) -> Riffer::Tools::Response
9
7
 
10
- # Fills each orphaned +tool_use+ in +messages+ with an +ORPHAN_PLACEHOLDER+
11
- # result inserted after its parent. Returns +[new_messages, filled_call_ids]+.
12
8
  # --
13
9
  # : (Array[Riffer::Messages::Base]) -> [Array[Riffer::Messages::Base], Array[String]]
14
10
  def fill_orphans: (Array[Riffer::Messages::Base]) -> [ Array[Riffer::Messages::Base], Array[String] ]
15
11
 
16
- # Prunes a seeded message array to the invariant — dropping orphaned tool
17
- # exchanges and parentless Tool messages, but preserving the pending
18
- # tool_calls on the resume boundary (the last assistant) for
19
- # +execute_pending_tool_calls+. Returns a new array.
20
12
  # --
21
13
  # : (Array[Riffer::Messages::Base]) -> Array[Riffer::Messages::Base]
22
14
  def prune_orphans: (Array[Riffer::Messages::Base]) -> Array[Riffer::Messages::Base]
@@ -1,100 +1,74 @@
1
1
  # Generated from lib/riffer/agent/session.rb with RBS::Inline
2
2
 
3
- # Owns the conversation handle for an agent: the message array, the
4
- # +on_message+ callbacks, and the +tool_use+ ↔ +tool_result+ invariant that
5
- # keeps tool calls and their results consistent.
6
- #
7
- # agent.session.add(msg) # append + fire callbacks
8
- # agent.session.set([msg1, msg2]) # bulk replace (silent)
9
- # agent.session.unset # clear (silent)
10
- # agent.session.remove(id: "a_1")
11
- # agent.session.update(id: "a_1", content: "...")
12
- # agent.session.find { |m| m.id == "a_1" }
13
3
  class Riffer::Agent::Session
14
4
  include Enumerable[Riffer::Messages::Base]
15
5
 
16
6
  @callbacks: Array[^(Riffer::Messages::Base) -> void]
17
7
 
18
- # The message history.
19
8
  attr_reader messages: Array[Riffer::Messages::Base]
20
9
 
21
10
  # --
22
11
  # : (?messages: Array[Riffer::Messages::Base]) -> void
23
12
  def initialize: (?messages: Array[Riffer::Messages::Base]) -> void
24
13
 
25
- # Registers a callback invoked once per message appended via +#add+.
26
14
  # --
27
15
  # : () { (Riffer::Messages::Base) -> void } -> self
28
16
  def on_message: () { (Riffer::Messages::Base) -> void } -> self
29
17
 
30
- # Appends +message+ and fires every registered callback once with it. Pass
31
- # +silent: true+ to skip callbacks — used for non-inference inputs like user
32
- # messages that subscribers don't expect on the callback channel.
33
18
  # --
34
19
  # : (Riffer::Messages::Base, ?silent: bool) -> Riffer::Messages::Base
35
20
  def add: (Riffer::Messages::Base, ?silent: bool) -> Riffer::Messages::Base
36
21
 
37
- # Replaces the message history wholesale
38
22
  # --
39
23
  # : (Array[Riffer::Messages::Base]) -> self
40
24
  def set: (Array[Riffer::Messages::Base]) -> self
41
25
 
42
- # Clears the session.
43
26
  # --
44
27
  # : () -> self
45
28
  def unset: () -> self
46
29
 
47
- # Removes a message by id, cascading to drop the +Tool+ results of a removed
48
- # assistant's +tool_calls+ so the +tool_use+ ↔ +tool_result+ invariant holds.
49
- # Raises on a +Tool+ message — that would orphan its parent; use +#update+
50
- # instead. Returns +nil+ if no message matches.
51
30
  # --
52
31
  # : (id: String) -> Riffer::Messages::Base?
53
32
  def remove: (id: String) -> Riffer::Messages::Base?
54
33
 
55
- # Partial in-place update: looks up a message by +id:+ or +tool_call_id:+
56
- # (exactly one), overlays +attrs+ onto a same-type replacement, and swaps it
57
- # in. Dropping +tool_calls+ from an assistant cascades to remove their +Tool+
58
- # results, preserving the invariant. Raises on neither/both keys or no match.
59
34
  # --
60
35
  # : (?id: String?, ?tool_call_id: String?, **untyped) -> Riffer::Messages::Base
61
36
  def update: (?id: String?, ?tool_call_id: String?, **untyped) -> Riffer::Messages::Base
62
37
 
63
- # Returns the call_ids of every +tool_call+ with no matching
64
- # +Riffer::Messages::Tool+ result anywhere in history — a hook for checking
65
- # the +tool_use+ ↔ +tool_result+ invariant before mutating or persisting.
66
38
  # --
67
39
  # : () -> Array[String]
68
40
  def orphaned_tool_call_ids: () -> Array[String]
69
41
 
70
- # Returns +[last_assistant, pending_tool_calls]+; the second element is empty
71
- # when there's no assistant message or no pending calls.
72
42
  # --
73
43
  # : () -> [Riffer::Messages::Assistant?, Array[Riffer::Messages::Assistant::ToolCall]]
74
44
  def pending_tool_calls: () -> [ Riffer::Messages::Assistant?, Array[Riffer::Messages::Assistant::ToolCall] ]
75
45
 
76
- # Yields each message in order, or returns an Enumerator without a block.
46
+ # --
47
+ # : () -> Array[String]
48
+ def discard_pending_tool_calls: () -> Array[String]
49
+
77
50
  # --
78
51
  # : () -> Enumerator[Riffer::Messages::Base, self]
79
52
  # : () { (Riffer::Messages::Base) -> void } -> untyped
80
53
  def each: () -> Enumerator[Riffer::Messages::Base, self]
81
54
  | () { (Riffer::Messages::Base) -> void } -> untyped
82
55
 
83
- # The number of LLM steps completed, used by the agent loop to enforce
84
- # +max_steps+ on resume.
85
56
  # --
86
57
  # : () -> Integer
87
58
  def steps: () -> Integer
88
59
 
89
- # The most recent +Riffer::Messages::Assistant+ in the session, or +nil+
90
- # when none exists.
91
- #
92
60
  # --
93
61
  # : () -> Riffer::Messages::Assistant?
94
62
  def final_assistant_message: () -> Riffer::Messages::Assistant?
95
63
 
96
64
  private
97
65
 
66
+ # Providers require tool results to directly follow their tool_use, but a
67
+ # resumed turn appends the new user message before pending calls execute.
68
+ # --
69
+ # : (Riffer::Messages::Base) -> Integer
70
+ def insertion_index: (Riffer::Messages::Base) -> Integer
71
+
98
72
  # --
99
73
  # : (Riffer::Messages::Base, Riffer::Messages::Base) -> void
100
74
  def cascade_dropped_tool_calls: (Riffer::Messages::Base, Riffer::Messages::Base) -> void
@@ -1,25 +1,18 @@
1
1
  # Generated from lib/riffer/agent/structured_output/result.rb with RBS::Inline
2
2
 
3
- # Wraps the result of structured output parsing and validation.
4
3
  class Riffer::Agent::StructuredOutput::Result
5
- # The validated object, or +nil+ on failure.
6
4
  attr_reader object: Hash[Symbol, untyped]?
7
5
 
8
- # The error message, or +nil+ on success.
9
6
  attr_reader error: String?
10
7
 
11
8
  # --
12
9
  # : (?object: Hash[Symbol, untyped]?, ?error: String?) -> void
13
10
  def initialize: (?object: Hash[Symbol, untyped]?, ?error: String?) -> void
14
11
 
15
- # Returns true when parsing and validation succeeded.
16
- #
17
12
  # --
18
13
  # : () -> bool
19
14
  def success?: () -> bool
20
15
 
21
- # Returns true when parsing or validation failed.
22
- #
23
16
  # --
24
17
  # : () -> bool
25
18
  def failure?: () -> bool
@@ -1,23 +1,16 @@
1
1
  # Generated from lib/riffer/agent/structured_output.rb with RBS::Inline
2
2
 
3
- # Parses and validates structured JSON responses against a Riffer::Params
4
- # schema.
5
3
  class Riffer::Agent::StructuredOutput
6
- # The schema parameters.
7
4
  attr_reader params: Riffer::Params
8
5
 
9
6
  # --
10
7
  # : (Riffer::Params) -> void
11
8
  def initialize: (Riffer::Params) -> void
12
9
 
13
- # Returns the JSON Schema for this structured output.
14
- #
15
10
  # --
16
11
  # : (?strict: bool) -> Hash[Symbol, untyped]
17
12
  def json_schema: (?strict: bool) -> Hash[Symbol, untyped]
18
13
 
19
- # Parses a JSON string and validates it against the schema, returning a
20
- # Result carrying either the validated object or an error message.
21
14
  # --
22
15
  # : (String) -> Riffer::Agent::StructuredOutput::Result
23
16
  def parse_and_validate: (String) -> Riffer::Agent::StructuredOutput::Result