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,34 +1,14 @@
1
1
  # Generated from lib/riffer/agent/serializer.rb with RBS::Inline
2
2
 
3
- # Riffer::Agent::Serializer turns a resolved agent into a self-contained,
4
- # provider-neutral data hash and back into a runnable agent. A pure module
5
- # (sibling to Riffer::Agent::Run), reached most often through the
6
- # +Riffer::Agent#to_h+ / +Riffer::Agent.from_h+ delegators.
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.
7
6
  #
8
- # The hash carries only data — no Procs, no class references, no tool
9
- # runtime. The same hash serves two rehydration targets:
10
- #
11
- # - <b>In-process</b> (a monolith persisting agent definitions): pass a
12
- # +tool_resolver+ that looks tool descriptors up in a local registry and
13
- # returns the real, body-bearing classes. They run on the default runtime.
14
- # - <b>Distributed</b> (a receiver holding only the Riffer gem): the default
15
- # resolver synthesizes body-less tool shells; inject a remote
16
- # +Riffer::Tools::Runtime+ to forward each call back to the origin.
17
- #
18
- # data = Riffer::Agent::Serializer.to_h(agent: agent)
19
- # rebuilt = Riffer::Agent::Serializer.from_h(data, context: {tenant: "acme"})
20
- #
21
- # == What does not transfer
22
- #
23
- # Guardrails and the skills subsystem (backend/adapter/catalog) are not
24
- # serialized; a rebuilt agent enforces no guardrails and renders no skills
25
- # catalog (the +skill_activate+ tool, if present, crosses as an ordinary
26
- # tool). Secrets must not be placed in +provider_options+/+model_options+:
27
- # both ride on the wire as plain data.
7
+ # hash = Riffer::Agent::Serializer.to_h(agent: agent)
8
+ # rebuilt = Riffer::Agent::Serializer.from_h(hash, context: {tenant: "acme"})
28
9
  module Riffer::Agent::Serializer
29
- # The wire format version. Bumped only on an incompatible change to the
30
- # hash shape; +from_h+ refuses any other version. See +from_h+ for the
31
- # dispatch seam that carries back-compat decoders.
10
+ # The wire format version, bumped only on an incompatible change to the hash
11
+ # shape; +from_h+ refuses any other version.
32
12
  SCHEMA_VERSION: Integer
33
13
 
34
14
  # Raised by +from_h+ when the hash's +schema_version+ is unsupported.
@@ -39,59 +19,30 @@ module Riffer::Agent::Serializer
39
19
  # descriptor. Its +#call+ raises — route shells through a remote runtime.
40
20
  DEFAULT_TOOL_RESOLVER: ^(Hash[Symbol, untyped]) -> singleton(Riffer::Tool)
41
21
 
42
- # Snapshots a resolved agent into a self-contained wire hash.
43
- #
44
- # Reads the agent's resolved instance state — Proc-based settings have
45
- # already been evaluated against the agent's own context, so the hash
46
- # carries plain strings/data, never Procs. Tools are emitted as
47
- # +{name, description, parameters_schema, timeout}+ descriptors (the
48
- # resolved +agent.tools+, including MCP tools and +skill_activate+).
49
- #
50
- # [agent] a resolved Riffer::Agent instance.
51
- #
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.
52
25
  # --
53
26
  # : (agent: Riffer::Agent) -> Hash[Symbol, untyped]
54
27
  def to_h: (agent: Riffer::Agent) -> Hash[Symbol, untyped]
55
28
 
56
- # Reconstructs a runnable agent from a wire hash.
57
- #
58
- # [hash] a Symbol-keyed wire hash (parse JSON with +symbolize_names: true+).
59
- # [context] the rebuilt agent's runtime context — the same value you'd pass
60
- # to +Agent.new(context:)+. It is *not* used to re-resolve serialized
61
- # config (the hash is already resolved); it is threaded into tool dispatch
62
- # and read by tools/runtimes at call time (e.g. a remote runtime keying off
63
- # <tt>context[:tenant]</tt>). Defaults to an empty context.
64
- # [session] an optional Riffer::Agent::Session to seed conversation history,
65
- # forwarded verbatim to +Agent.new(session:)+. The hash carries the agent
66
- # *definition*, not its history (see "What does not transfer"); pass a
67
- # session here to resume a persisted conversation. Used as-is — the caller
68
- # owns its contents, including the system instruction message. When omitted,
69
- # a fresh session seeded with the hash's instructions is built.
70
- # [tool_resolver] maps a tool descriptor to a Riffer::Tool class. Defaults
71
- # to DEFAULT_TOOL_RESOLVER (body-less shells). Pass a registry lookup to
72
- # rebuild real, in-process tools.
73
- # [tool_runtime] an optional Riffer::Tools::Runtime to inject (e.g. a
74
- # remote runtime for shells). When omitted, the agent uses the configured
75
- # default (+Riffer.config.tool_runtime+).
76
- #
77
- # Raises Riffer::Agent::Serializer::VersionError on an unsupported
78
- # +schema_version+, and Riffer::ArgumentError on a malformed hash.
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+.
79
34
  #
80
35
  # --
81
36
  # : (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
82
37
  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
83
38
 
84
- # Snapshots a resolved agent to a JSON string. Convenience over
85
- # <tt>JSON.generate(to_h(agent:))</tt>.
86
- #
39
+ # Snapshots a resolved agent to a JSON string.
87
40
  # --
88
41
  # : (agent: Riffer::Agent) -> String
89
42
  def to_json: (agent: Riffer::Agent) -> String
90
43
 
91
- # Reconstructs a runnable agent from a JSON string produced by +to_json+.
92
- # Handles the JSON parse (with symbol keys) so callers don't have to. See
44
+ # Reconstructs a runnable agent from a JSON string produced by +to_json+. See
93
45
  # +from_h+ for the arguments.
94
- #
95
46
  # --
96
47
  # : (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
97
48
  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
@@ -106,18 +57,14 @@ module Riffer::Agent::Serializer
106
57
  # : (Hash[Symbol, untyped]?) -> Riffer::Params?
107
58
  def decode_structured_output: (Hash[Symbol, untyped]?) -> Riffer::Params?
108
59
 
109
- # The DSL represents unlimited steps as +nil+, but the wire encodes it as
110
- # +-1+ so the hash stays portable across transports where JSON +null+ is
111
- # awkward (e.g. proto3, which can't tell null from an absent field). The
112
- # magic value lives only on the wire — +encode_max_steps+/+decode_max_steps+
113
- # translate at the boundary so neither the DSL nor consumers see it.
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).
114
62
  # --
115
63
  # : (Numeric?) -> Numeric
116
64
  def encode_max_steps: (Numeric?) -> Numeric
117
65
 
118
- # Reverses +encode_max_steps+: +-1+ (or a literal +null+) means unlimited.
119
- # An absent key falls back to the default — a partial hash must not silently
120
- # become an unbounded loop.
66
+ # Reverses +encode_max_steps+; a missing key falls back to the default so a
67
+ # partial hash can't become an unbounded loop.
121
68
  # --
122
69
  # : (Hash[Symbol, untyped]) -> Numeric?
123
70
  def decode_max_steps: (Hash[Symbol, untyped]) -> Numeric?
@@ -126,12 +73,6 @@ module Riffer::Agent::Serializer
126
73
  # : (singleton(Riffer::Tool)) -> Hash[Symbol, untyped]
127
74
  def tool_descriptor: (singleton(Riffer::Tool)) -> Hash[Symbol, untyped]
128
75
 
129
- # Builds an anonymous, body-less Riffer::Tool subclass that advertises the
130
- # descriptor's schema to the LLM. Its +#call+ raises — a shell only has
131
- # identity, not behavior; route its calls through a remote runtime.
132
- #
133
- # Returns +untyped+: steep can't see that +Class.new(Riffer::Tool)+ is a
134
- # +singleton(Riffer::Tool)+ (cf. Riffer::Mcp::ToolFactory#build_tool_class).
135
76
  # --
136
77
  # : (Hash[Symbol, untyped]) -> untyped
137
78
  def build_tool_shell: (Hash[Symbol, untyped]) -> untyped
@@ -1,51 +1,23 @@
1
1
  # Generated from lib/riffer/agent/session/repair.rb with RBS::Inline
2
2
 
3
- # Riffer::Agent::Session::Repair holds the pure transformations that keep the
4
- # +tool_use+ ↔ +tool_result+ invariant on a message array. No state, no
5
- # instance — module-level functions only. Each entry point is gated by
6
- # +Riffer.config.experimental_history_healing+: when the flag is off the
7
- # function returns its input unchanged.
8
- #
9
- # Two seams:
10
- #
11
- # - +fill_orphans+ — fills orphan +tool_use+ blocks with placeholder
12
- # results. Used on interrupt (caller-issued or +max_steps+).
13
- # - +prune_orphans+ — drops orphan +tool_use+ blocks and parentless Tool
14
- # messages from a caller-provided seed so it is well-formed before the
15
- # next inference call. Used at construction time when
16
- # +Riffer::Agent.new(session:)+ receives a session.
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.
17
6
  module Riffer::Agent::Session::Repair
18
- # Placeholder used to fill orphan +tool_use+ blocks. Emitted as the
19
- # +Riffer::Tools::Response+ body for each filled call_id.
7
+ # Placeholder response filled in for an orphaned +tool_use+ on interrupt.
20
8
  ORPHAN_PLACEHOLDER: ^(Riffer::Messages::Assistant::ToolCall) -> Riffer::Tools::Response
21
9
 
22
- # Fills any orphaned +tool_use+ in +messages+ with the
23
- # +ORPHAN_PLACEHOLDER+ response. Each placeholder Tool message is
24
- # inserted immediately after its parent assistant message. Returns
25
- # +[new_messages, filled_call_ids]+; +filled_call_ids+ is empty when
26
- # there are no orphans.
27
- #
28
- # No-op when +Riffer.config.experimental_history_healing+ is off:
29
- # returns +[messages, []]+ with the same array reference.
30
- #
10
+ # Fills each orphaned +tool_use+ in +messages+ with an +ORPHAN_PLACEHOLDER+
11
+ # result inserted after its parent. Returns +[new_messages, filled_call_ids]+.
31
12
  # --
32
13
  # : (Array[Riffer::Messages::Base]) -> [Array[Riffer::Messages::Base], Array[String]]
33
- def self.fill_orphans: (Array[Riffer::Messages::Base]) -> [ Array[Riffer::Messages::Base], Array[String] ]
14
+ def fill_orphans: (Array[Riffer::Messages::Base]) -> [ Array[Riffer::Messages::Base], Array[String] ]
34
15
 
35
- # Prunes a seeded message array so the +tool_use+ +tool_result+
36
- # invariant holds. Drops orphaned tool exchanges (assistant +tool_call+
37
- # with no matching Tool result) and parentless Tool messages. Returns a
38
- # new array; the input is not mutated.
39
- #
40
- # Pending tool_calls on the resume boundary — the last assistant whose
41
- # tail is purely Tool results (or empty) — are preserved. They get
42
- # swept up by +execute_pending_tool_calls+ at the start of the next
43
- # generate/stream call.
44
- #
45
- # No-op when +Riffer.config.experimental_history_healing+ is off:
46
- # returns +messages+ unchanged.
47
- #
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.
48
20
  # --
49
21
  # : (Array[Riffer::Messages::Base]) -> Array[Riffer::Messages::Base]
50
- def self.prune_orphans: (Array[Riffer::Messages::Base]) -> Array[Riffer::Messages::Base]
22
+ def prune_orphans: (Array[Riffer::Messages::Base]) -> Array[Riffer::Messages::Base]
51
23
  end
@@ -1,11 +1,8 @@
1
1
  # Generated from lib/riffer/agent/session.rb with RBS::Inline
2
2
 
3
- # Riffer::Agent::Session owns the conversation handle for an agent: the message
4
- # array, the +on_message+ callback list, and the +tool_use+ ↔ +tool_result+
5
- # invariant that keeps tool calls and their results consistent.
6
- #
7
- # Access via +agent.session+. Sessions are constructed by +Riffer::Agent+
8
- # and live for the lifetime of the agent.
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.
9
6
  #
10
7
  # agent.session.add(msg) # append + fire callbacks
11
8
  # agent.session.set([msg1, msg2]) # bulk replace (silent)
@@ -26,106 +23,65 @@ class Riffer::Agent::Session
26
23
  def initialize: (?messages: Array[Riffer::Messages::Base]) -> void
27
24
 
28
25
  # Registers a callback invoked once per message appended via +#add+.
29
- #
30
- # Callbacks do NOT fire for +#set+, +#unset+, +#remove+, or +#update+.
31
- # Returns +self+ to allow chaining.
32
- #
33
- # Raises Riffer::ArgumentError if no block is given.
34
- #
35
26
  # --
36
27
  # : () { (Riffer::Messages::Base) -> void } -> self
37
28
  def on_message: () { (Riffer::Messages::Base) -> void } -> self
38
29
 
39
- # Appends +message+ and fires every registered callback once with it.
40
- #
41
- # Pass +silent: true+ to skip +on_message+ callbacks used for
42
- # non-inference inputs like user messages, which subscribers don't
43
- # expect to observe through the callback channel. Inference-produced
44
- # messages (Assistant, Tool) always go through +add+ without +silent+.
45
- #
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.
46
33
  # --
47
34
  # : (Riffer::Messages::Base, ?silent: bool) -> Riffer::Messages::Base
48
35
  def add: (Riffer::Messages::Base, ?silent: bool) -> Riffer::Messages::Base
49
36
 
50
- # Replaces the message history wholesale. Does NOT fire +on_message+
51
- # callbacks; registered callbacks persist across the swap.
52
- #
53
- # Used for seeding, guardrail rewrites, and history healing — cases
54
- # where firing callbacks would double-emit messages that subscribers
55
- # have already observed (or never produced).
56
- #
37
+ # Replaces the message history wholesale
57
38
  # --
58
39
  # : (Array[Riffer::Messages::Base]) -> self
59
40
  def set: (Array[Riffer::Messages::Base]) -> self
60
41
 
61
- # Clears the session. Does NOT fire +on_message+ callbacks; registered
62
- # callbacks persist.
63
- #
42
+ # Clears the session.
64
43
  # --
65
44
  # : () -> self
66
45
  def unset: () -> self
67
46
 
68
- # Removes a message by id. When the target is an assistant message that
69
- # carries +tool_calls+, every +Riffer::Messages::Tool+ result whose
70
- # +tool_call_id+ matches one of those calls is removed atomically — keeping
71
- # the +tool_use+ +tool_result+ invariant intact.
72
- #
73
- # Raises Riffer::ArgumentError when called on a +Riffer::Messages::Tool+
74
- # message — that would orphan the parent's +tool_use+. Use
75
- # +#update+ to rewrite a tool result instead.
76
- #
77
- # Returns the removed message, or +nil+ when no message has the given id
78
- # (idempotent).
79
- #
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.
80
51
  # --
81
52
  # : (id: String) -> Riffer::Messages::Base?
82
53
  def remove: (id: String) -> Riffer::Messages::Base?
83
54
 
84
- # Partial in-place update. Looks up a message by either +id:+ or
85
- # +tool_call_id:+ (exactly one required), constructs a replacement of the
86
- # same concrete type with +attrs+ overlaid on the existing fields, and
87
- # swaps it in place.
88
- #
89
- # When the target is an assistant message and the update drops one or more
90
- # entries from +tool_calls+, every +Riffer::Messages::Tool+ result whose
91
- # +tool_call_id+ matches a dropped call is removed atomically — keeping the
92
- # +tool_use+ ↔ +tool_result+ invariant intact.
93
- #
94
- # Raises Riffer::ArgumentError when neither or both lookup keys are
95
- # provided, or when no message matches.
96
- #
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.
97
59
  # --
98
60
  # : (?id: String?, ?tool_call_id: String?, **untyped) -> Riffer::Messages::Base
99
61
  def update: (?id: String?, ?tool_call_id: String?, **untyped) -> Riffer::Messages::Base
100
62
 
101
- # Returns the call_ids of every +tool_call+ on any assistant message that
102
- # has no matching +Riffer::Messages::Tool+ result anywhere in history.
103
- #
104
- # Zero-cost validation hook for callers that want to check the
105
- # +tool_use+ ↔ +tool_result+ invariant before mutating or persisting.
106
- #
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.
107
66
  # --
108
67
  # : () -> Array[String]
109
68
  def orphaned_tool_call_ids: () -> Array[String]
110
69
 
111
- # Returns +[assistant, pending_tool_calls]+ for the last assistant message.
112
- # When there is no assistant message or no pending calls, the second
113
- # element is an empty array.
114
- #
70
+ # Returns +[last_assistant, pending_tool_calls]+; the second element is empty
71
+ # when there's no assistant message or no pending calls.
115
72
  # --
116
73
  # : () -> [Riffer::Messages::Assistant?, Array[Riffer::Messages::Assistant::ToolCall]]
117
74
  def pending_tool_calls: () -> [ Riffer::Messages::Assistant?, Array[Riffer::Messages::Assistant::ToolCall] ]
118
75
 
76
+ # Yields each message in order, or returns an Enumerator without a block.
119
77
  # --
120
78
  # : () -> Enumerator[Riffer::Messages::Base, self]
121
79
  # : () { (Riffer::Messages::Base) -> void } -> untyped
122
80
  def each: () -> Enumerator[Riffer::Messages::Base, self]
123
81
  | () { (Riffer::Messages::Base) -> void } -> untyped
124
82
 
125
- # The number of LLM steps completed in this session, derived from the
126
- # count of assistant messages. Used by the agent loop to enforce
83
+ # The number of LLM steps completed, used by the agent loop to enforce
127
84
  # +max_steps+ on resume.
128
- #
129
85
  # --
130
86
  # : () -> Integer
131
87
  def steps: () -> Integer
@@ -139,9 +95,11 @@ class Riffer::Agent::Session
139
95
 
140
96
  private
141
97
 
98
+ # --
142
99
  # : (Riffer::Messages::Base, Riffer::Messages::Base) -> void
143
100
  def cascade_dropped_tool_calls: (Riffer::Messages::Base, Riffer::Messages::Base) -> void
144
101
 
102
+ # --
145
103
  # : (Riffer::Messages::Base, Hash[Symbol, untyped]) -> Riffer::Messages::Base
146
104
  def rebuild_message: (Riffer::Messages::Base, Hash[Symbol, untyped]) -> Riffer::Messages::Base
147
105
  end
@@ -1,19 +1,11 @@
1
1
  # Generated from lib/riffer/agent/structured_output/result.rb with RBS::Inline
2
2
 
3
3
  # Wraps the result of structured output parsing and validation.
4
- #
5
- # On success, +object+ contains the validated Hash and +error+ is nil.
6
- # On failure, +error+ contains the error message and +object+ is nil.
7
- #
8
- # result = structured_output.parse_and_validate(json_string)
9
- # if result.success?
10
- # result.object #=> {sentiment: "positive", score: 0.9}
11
- # else
12
- # result.error #=> "JSON parse error: ..."
13
- # end
14
4
  class Riffer::Agent::StructuredOutput::Result
5
+ # The validated object, or +nil+ on failure.
15
6
  attr_reader object: Hash[Symbol, untyped]?
16
7
 
8
+ # The error message, or +nil+ on success.
17
9
  attr_reader error: String?
18
10
 
19
11
  # --
@@ -1,14 +1,9 @@
1
1
  # Generated from lib/riffer/agent/structured_output.rb with RBS::Inline
2
2
 
3
- # Riffer::Agent::StructuredOutput provides parse/validate for structured JSON
4
- # responses from LLM providers.
5
- #
6
- # params = Riffer::Params.new
7
- # params.required(:sentiment, String)
8
- # so = Riffer::Agent::StructuredOutput.new(params)
9
- # result = so.parse_and_validate('{"sentiment":"positive","score":0.9}')
10
- # result.object #=> {sentiment: "positive", score: 0.9}
3
+ # Parses and validates structured JSON responses against a Riffer::Params
4
+ # schema.
11
5
  class Riffer::Agent::StructuredOutput
6
+ # The schema parameters.
12
7
  attr_reader params: Riffer::Params
13
8
 
14
9
  # --
@@ -21,10 +16,8 @@ class Riffer::Agent::StructuredOutput
21
16
  # : (?strict: bool) -> Hash[Symbol, untyped]
22
17
  def json_schema: (?strict: bool) -> Hash[Symbol, untyped]
23
18
 
24
- # Parses a JSON string and validates it against the schema.
25
- #
26
- # Returns a Result with the validated object on success, or an error message on failure.
27
- #
19
+ # Parses a JSON string and validates it against the schema, returning a
20
+ # Result carrying either the validated object or an error message.
28
21
  # --
29
22
  # : (String) -> Riffer::Agent::StructuredOutput::Result
30
23
  def parse_and_validate: (String) -> Riffer::Agent::StructuredOutput::Result