riffer 0.47.2 → 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 (267) 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 +42 -0
  7. data/docs/AGENTS.md +39 -7
  8. data/docs/AGENT_LIFECYCLE.md +14 -16
  9. data/docs/CONFIGURATION.md +23 -34
  10. data/docs/EVALS.md +2 -1
  11. data/docs/MCP.md +0 -4
  12. data/docs/MESSAGES.md +85 -17
  13. data/docs/STREAM_EVENTS.md +8 -4
  14. data/docs/TOOL_ADVANCED.md +1 -3
  15. data/docs/TRACING.md +2 -2
  16. data/docs/providers/AMAZON_BEDROCK.md +32 -1
  17. data/docs/providers/CUSTOM_PROVIDERS.md +56 -4
  18. data/docs/providers/GEMINI.md +1 -1
  19. data/docs/providers/MOCK_PROVIDER.md +17 -0
  20. data/docs/providers/OPENROUTER.md +18 -1
  21. data/docs-site/build.rb +0 -6
  22. data/docs-site/check.rb +1 -5
  23. data/lib/riffer/agent/config.rb +27 -44
  24. data/lib/riffer/agent/context.rb +2 -26
  25. data/lib/riffer/agent/outcome.rb +0 -20
  26. data/lib/riffer/agent/response.rb +4 -35
  27. data/lib/riffer/agent/run.rb +32 -48
  28. data/lib/riffer/agent/serializer.rb +10 -39
  29. data/lib/riffer/agent/session/repair.rb +3 -15
  30. data/lib/riffer/agent/session.rb +26 -38
  31. data/lib/riffer/agent/structured_output/result.rb +0 -8
  32. data/lib/riffer/agent/structured_output.rb +0 -7
  33. data/lib/riffer/agent.rb +31 -127
  34. data/lib/riffer/config/amazon_bedrock.rb +30 -0
  35. data/lib/riffer/config/anthropic.rb +21 -0
  36. data/lib/riffer/config/azure_open_ai.rb +30 -0
  37. data/lib/riffer/config/evals.rb +18 -0
  38. data/lib/riffer/config/files.rb +61 -0
  39. data/lib/riffer/config/gemini.rb +21 -0
  40. data/lib/riffer/config/mcp.rb +31 -0
  41. data/lib/riffer/config/open_ai.rb +30 -0
  42. data/lib/riffer/config/open_router.rb +21 -0
  43. data/lib/riffer/config/pricing/rates.rb +36 -0
  44. data/lib/riffer/config/pricing.rb +64 -0
  45. data/lib/riffer/config/skills.rb +38 -0
  46. data/lib/riffer/config/tracing.rb +43 -0
  47. data/lib/riffer/config.rb +3 -362
  48. data/lib/riffer/evals/evaluator.rb +22 -23
  49. data/lib/riffer/evals/evaluator_runner.rb +0 -15
  50. data/lib/riffer/evals/judge.rb +9 -11
  51. data/lib/riffer/evals/result.rb +1 -11
  52. data/lib/riffer/evals/run_result.rb +0 -12
  53. data/lib/riffer/evals/scenario_result.rb +0 -19
  54. data/lib/riffer/files/downloader.rb +2 -3
  55. data/lib/riffer/files/resolver.rb +5 -10
  56. data/lib/riffer/guardrail.rb +2 -22
  57. data/lib/riffer/guardrails/modification.rb +0 -8
  58. data/lib/riffer/guardrails/result.rb +0 -17
  59. data/lib/riffer/guardrails/runner.rb +2 -11
  60. data/lib/riffer/guardrails/tripwire.rb +0 -8
  61. data/lib/riffer/guardrails.rb +0 -2
  62. data/lib/riffer/helpers/boolean.rb +0 -4
  63. data/lib/riffer/helpers/call_or_value.rb +0 -3
  64. data/lib/riffer/helpers/deep_dup.rb +37 -0
  65. data/lib/riffer/helpers/dependencies.rb +0 -4
  66. data/lib/riffer/helpers/identifier.rb +3 -12
  67. data/lib/riffer/helpers/validate.rb +42 -0
  68. data/lib/riffer/mcp/authenticated_tool.rb +4 -12
  69. data/lib/riffer/mcp/client.rb +0 -7
  70. data/lib/riffer/mcp/manifest.rb +3 -7
  71. data/lib/riffer/mcp/registration.rb +0 -10
  72. data/lib/riffer/mcp/registry.rb +0 -9
  73. data/lib/riffer/mcp/search_tool.rb +0 -4
  74. data/lib/riffer/mcp/tool.rb +1 -4
  75. data/lib/riffer/mcp/tool_factory.rb +3 -6
  76. data/lib/riffer/mcp.rb +2 -23
  77. data/lib/riffer/messages/assistant/reasoning_part.rb +73 -0
  78. data/lib/riffer/messages/assistant/tool_call.rb +55 -0
  79. data/lib/riffer/messages/assistant.rb +43 -15
  80. data/lib/riffer/messages/base.rb +5 -33
  81. data/lib/riffer/messages/system.rb +8 -1
  82. data/lib/riffer/messages/tool.rb +15 -13
  83. data/lib/riffer/messages/{file_part.rb → user/file_part.rb} +16 -40
  84. data/lib/riffer/messages/user.rb +11 -4
  85. data/lib/riffer/params/boolean.rb +1 -5
  86. data/lib/riffer/params/param.rb +15 -31
  87. data/lib/riffer/params.rb +15 -39
  88. data/lib/riffer/providers/amazon_bedrock.rb +104 -44
  89. data/lib/riffer/providers/anthropic.rb +11 -26
  90. data/lib/riffer/providers/azure_open_ai.rb +3 -8
  91. data/lib/riffer/providers/base.rb +30 -32
  92. data/lib/riffer/providers/finish_reason.rb +0 -6
  93. data/lib/riffer/providers/gemini/client.rb +4 -17
  94. data/lib/riffer/providers/gemini.rb +6 -12
  95. data/lib/riffer/providers/mock.rb +18 -27
  96. data/lib/riffer/providers/open_ai.rb +12 -21
  97. data/lib/riffer/providers/open_router.rb +109 -33
  98. data/lib/riffer/providers/repository.rb +2 -14
  99. data/lib/riffer/providers/token_usage.rb +19 -12
  100. data/lib/riffer/registrable.rb +11 -45
  101. data/lib/riffer/runner/fibers.rb +1 -6
  102. data/lib/riffer/runner/sequential.rb +0 -1
  103. data/lib/riffer/runner/threaded.rb +0 -3
  104. data/lib/riffer/runner.rb +0 -3
  105. data/lib/riffer/skills/activate_tool.rb +0 -3
  106. data/lib/riffer/skills/adapter.rb +0 -8
  107. data/lib/riffer/skills/backend.rb +2 -7
  108. data/lib/riffer/skills/config.rb +13 -17
  109. data/lib/riffer/skills/context.rb +0 -29
  110. data/lib/riffer/skills/filesystem_backend.rb +0 -7
  111. data/lib/riffer/skills/frontmatter.rb +2 -16
  112. data/lib/riffer/skills/markdown_adapter.rb +3 -6
  113. data/lib/riffer/skills/xml_adapter.rb +0 -3
  114. data/lib/riffer/stream_events/base.rb +0 -3
  115. data/lib/riffer/stream_events/finish_reason_done.rb +1 -6
  116. data/lib/riffer/stream_events/guardrail_modification.rb +0 -10
  117. data/lib/riffer/stream_events/guardrail_tripwire.rb +0 -10
  118. data/lib/riffer/stream_events/interrupt.rb +2 -12
  119. data/lib/riffer/stream_events/reasoning_delta.rb +0 -3
  120. data/lib/riffer/stream_events/reasoning_done.rb +6 -8
  121. data/lib/riffer/stream_events/skill_activation.rb +0 -3
  122. data/lib/riffer/stream_events/text_delta.rb +0 -2
  123. data/lib/riffer/stream_events/text_done.rb +0 -2
  124. data/lib/riffer/stream_events/token_usage_done.rb +0 -2
  125. data/lib/riffer/stream_events/tool_call_delta.rb +1 -5
  126. data/lib/riffer/stream_events/tool_call_done.rb +0 -5
  127. data/lib/riffer/stream_events/web_search_done.rb +0 -3
  128. data/lib/riffer/stream_events/web_search_status.rb +1 -5
  129. data/lib/riffer/testing/minitest.rb +4 -5
  130. data/lib/riffer/testing.rb +5 -38
  131. data/lib/riffer/tool.rb +2 -28
  132. data/lib/riffer/tools/response.rb +3 -32
  133. data/lib/riffer/tools/runtime/fibers.rb +0 -6
  134. data/lib/riffer/tools/runtime/inline.rb +0 -1
  135. data/lib/riffer/tools/runtime/threaded.rb +0 -6
  136. data/lib/riffer/tools/runtime.rb +8 -30
  137. data/lib/riffer/tools/toolable.rb +0 -37
  138. data/lib/riffer/tracing/capture.rb +5 -9
  139. data/lib/riffer/tracing/no_op.rb +0 -7
  140. data/lib/riffer/tracing/otel.rb +7 -16
  141. data/lib/riffer/tracing/stream_recorder.rb +0 -7
  142. data/lib/riffer/tracing.rb +4 -27
  143. data/lib/riffer/version.rb +1 -1
  144. data/lib/riffer.rb +2 -30
  145. data/sig/generated/riffer/agent/config.rbs +24 -46
  146. data/sig/generated/riffer/agent/context.rbs +2 -26
  147. data/sig/generated/riffer/agent/outcome.rbs +0 -20
  148. data/sig/generated/riffer/agent/response.rbs +4 -27
  149. data/sig/generated/riffer/agent/run.rbs +12 -31
  150. data/sig/generated/riffer/agent/serializer.rbs +2 -27
  151. data/sig/generated/riffer/agent/session/repair.rbs +2 -10
  152. data/sig/generated/riffer/agent/session.rbs +10 -36
  153. data/sig/generated/riffer/agent/structured_output/result.rbs +0 -7
  154. data/sig/generated/riffer/agent/structured_output.rbs +0 -7
  155. data/sig/generated/riffer/agent.rbs +25 -125
  156. data/sig/generated/riffer/config/amazon_bedrock.rbs +21 -0
  157. data/sig/generated/riffer/config/anthropic.rbs +15 -0
  158. data/sig/generated/riffer/config/azure_open_ai.rbs +21 -0
  159. data/sig/generated/riffer/config/evals.rbs +13 -0
  160. data/sig/generated/riffer/config/files.rbs +43 -0
  161. data/sig/generated/riffer/config/gemini.rbs +15 -0
  162. data/sig/generated/riffer/config/mcp.rbs +19 -0
  163. data/sig/generated/riffer/config/open_ai.rbs +21 -0
  164. data/sig/generated/riffer/config/open_router.rbs +15 -0
  165. data/sig/generated/riffer/config/pricing/rates.rbs +19 -0
  166. data/sig/generated/riffer/config/pricing.rbs +31 -0
  167. data/sig/generated/riffer/config/skills.rbs +19 -0
  168. data/sig/generated/riffer/config/tracing.rbs +25 -0
  169. data/sig/generated/riffer/config.rbs +2 -307
  170. data/sig/generated/riffer/evals/evaluator.rbs +12 -21
  171. data/sig/generated/riffer/evals/evaluator_runner.rbs +0 -14
  172. data/sig/generated/riffer/evals/judge.rbs +4 -8
  173. data/sig/generated/riffer/evals/result.rbs +1 -11
  174. data/sig/generated/riffer/evals/run_result.rbs +0 -12
  175. data/sig/generated/riffer/evals/scenario_result.rbs +0 -14
  176. data/sig/generated/riffer/files/resolver.rbs +6 -13
  177. data/sig/generated/riffer/guardrail.rbs +2 -22
  178. data/sig/generated/riffer/guardrails/modification.rbs +0 -6
  179. data/sig/generated/riffer/guardrails/result.rbs +0 -15
  180. data/sig/generated/riffer/guardrails/runner.rbs +0 -11
  181. data/sig/generated/riffer/guardrails/tripwire.rbs +0 -8
  182. data/sig/generated/riffer/guardrails.rbs +0 -2
  183. data/sig/generated/riffer/helpers/boolean.rbs +0 -4
  184. data/sig/generated/riffer/helpers/call_or_value.rbs +0 -3
  185. data/sig/generated/riffer/helpers/deep_dup.rbs +13 -0
  186. data/sig/generated/riffer/helpers/dependencies.rbs +0 -4
  187. data/sig/generated/riffer/helpers/identifier.rbs +0 -12
  188. data/sig/generated/riffer/helpers/validate.rbs +21 -0
  189. data/sig/generated/riffer/mcp/authenticated_tool.rbs +0 -5
  190. data/sig/generated/riffer/mcp/client.rbs +0 -7
  191. data/sig/generated/riffer/mcp/manifest.rbs +3 -7
  192. data/sig/generated/riffer/mcp/registration.rbs +0 -10
  193. data/sig/generated/riffer/mcp/registry.rbs +0 -9
  194. data/sig/generated/riffer/mcp/search_tool.rbs +0 -4
  195. data/sig/generated/riffer/mcp/tool.rbs +0 -4
  196. data/sig/generated/riffer/mcp/tool_factory.rbs +0 -6
  197. data/sig/generated/riffer/mcp.rbs +2 -22
  198. data/sig/generated/riffer/messages/assistant/reasoning_part.rbs +45 -0
  199. data/sig/generated/riffer/messages/assistant/tool_call.rbs +34 -0
  200. data/sig/generated/riffer/messages/assistant.rbs +25 -31
  201. data/sig/generated/riffer/messages/base.rbs +0 -12
  202. data/sig/generated/riffer/messages/system.rbs +4 -1
  203. data/sig/generated/riffer/messages/tool.rbs +4 -10
  204. data/sig/generated/riffer/messages/user/file_part.rbs +76 -0
  205. data/sig/generated/riffer/messages/user.rbs +7 -5
  206. data/sig/generated/riffer/params/boolean.rbs +1 -4
  207. data/sig/generated/riffer/params/param.rbs +7 -31
  208. data/sig/generated/riffer/params.rbs +8 -38
  209. data/sig/generated/riffer/providers/amazon_bedrock.rbs +33 -29
  210. data/sig/generated/riffer/providers/anthropic.rbs +2 -12
  211. data/sig/generated/riffer/providers/azure_open_ai.rbs +0 -8
  212. data/sig/generated/riffer/providers/base.rbs +18 -34
  213. data/sig/generated/riffer/providers/finish_reason.rbs +0 -6
  214. data/sig/generated/riffer/providers/gemini/client.rbs +4 -17
  215. data/sig/generated/riffer/providers/gemini.rbs +4 -10
  216. data/sig/generated/riffer/providers/mock.rbs +6 -27
  217. data/sig/generated/riffer/providers/open_ai.rbs +6 -13
  218. data/sig/generated/riffer/providers/open_router.rbs +37 -18
  219. data/sig/generated/riffer/providers/repository.rbs +2 -14
  220. data/sig/generated/riffer/providers/token_usage.rbs +9 -12
  221. data/sig/generated/riffer/registrable.rbs +0 -45
  222. data/sig/generated/riffer/runner/fibers.rbs +0 -6
  223. data/sig/generated/riffer/runner/sequential.rbs +0 -1
  224. data/sig/generated/riffer/runner/threaded.rbs +0 -3
  225. data/sig/generated/riffer/runner.rbs +0 -3
  226. data/sig/generated/riffer/skills/activate_tool.rbs +0 -3
  227. data/sig/generated/riffer/skills/adapter.rbs +0 -8
  228. data/sig/generated/riffer/skills/backend.rbs +2 -7
  229. data/sig/generated/riffer/skills/config.rbs +6 -17
  230. data/sig/generated/riffer/skills/context.rbs +0 -29
  231. data/sig/generated/riffer/skills/filesystem_backend.rbs +0 -7
  232. data/sig/generated/riffer/skills/frontmatter.rbs +2 -16
  233. data/sig/generated/riffer/skills/markdown_adapter.rbs +0 -6
  234. data/sig/generated/riffer/skills/xml_adapter.rbs +0 -3
  235. data/sig/generated/riffer/stream_events/base.rbs +0 -3
  236. data/sig/generated/riffer/stream_events/finish_reason_done.rbs +1 -6
  237. data/sig/generated/riffer/stream_events/guardrail_modification.rbs +0 -10
  238. data/sig/generated/riffer/stream_events/guardrail_tripwire.rbs +0 -10
  239. data/sig/generated/riffer/stream_events/interrupt.rbs +2 -10
  240. data/sig/generated/riffer/stream_events/reasoning_delta.rbs +0 -3
  241. data/sig/generated/riffer/stream_events/reasoning_done.rbs +4 -6
  242. data/sig/generated/riffer/stream_events/skill_activation.rbs +0 -3
  243. data/sig/generated/riffer/stream_events/text_delta.rbs +0 -2
  244. data/sig/generated/riffer/stream_events/text_done.rbs +0 -2
  245. data/sig/generated/riffer/stream_events/token_usage_done.rbs +0 -2
  246. data/sig/generated/riffer/stream_events/tool_call_delta.rbs +1 -5
  247. data/sig/generated/riffer/stream_events/tool_call_done.rbs +0 -5
  248. data/sig/generated/riffer/stream_events/web_search_done.rbs +0 -3
  249. data/sig/generated/riffer/stream_events/web_search_status.rbs +1 -5
  250. data/sig/generated/riffer/testing.rbs +0 -38
  251. data/sig/generated/riffer/tool.rbs +0 -27
  252. data/sig/generated/riffer/tools/response.rbs +3 -29
  253. data/sig/generated/riffer/tools/runtime/fibers.rbs +0 -5
  254. data/sig/generated/riffer/tools/runtime/inline.rbs +0 -1
  255. data/sig/generated/riffer/tools/runtime/threaded.rbs +0 -5
  256. data/sig/generated/riffer/tools/runtime.rbs +4 -26
  257. data/sig/generated/riffer/tools/toolable.rbs +0 -37
  258. data/sig/generated/riffer/tracing/capture.rbs +6 -9
  259. data/sig/generated/riffer/tracing/no_op.rbs +0 -7
  260. data/sig/generated/riffer/tracing/otel.rbs +7 -16
  261. data/sig/generated/riffer/tracing/stream_recorder.rbs +0 -2
  262. data/sig/generated/riffer/tracing.rbs +4 -23
  263. data/sig/generated/riffer.rbs +2 -29
  264. data/sig/manual/riffer/helpers/deep_dup.rbs +5 -0
  265. data/sig/manual/riffer/helpers/validate.rbs +5 -0
  266. metadata +39 -3
  267. data/sig/generated/riffer/messages/file_part.rbs +0 -101
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ class Riffer::Config::Files
5
+ attr_reader :allow_downloads #: bool # @dynamic allow_downloads
6
+ attr_reader :max_bytes #: Integer # @dynamic max_bytes
7
+ attr_reader :timeout #: Integer # @dynamic timeout
8
+ attr_reader :max_per_message #: Integer? # @dynamic max_per_message
9
+ attr_reader :runner #: Riffer::Runner # @dynamic runner
10
+ attr_reader :downloader #: untyped # @dynamic downloader
11
+
12
+ #--
13
+ #: () -> void
14
+ def initialize
15
+ @allow_downloads = false
16
+ @max_bytes = 3_500_000
17
+ @timeout = 60
18
+ @max_per_message = nil
19
+ @runner = Riffer::Runner::Sequential.new
20
+ @downloader = Riffer::Files::Downloader.new
21
+ end
22
+
23
+ #--
24
+ #: (untyped) -> void
25
+ def allow_downloads=(value)
26
+ @allow_downloads = Riffer::Helpers::Boolean.coerce(value, attribute: "allow_downloads")
27
+ end
28
+
29
+ #--
30
+ #: (untyped) -> void
31
+ def max_bytes=(value)
32
+ @max_bytes = Riffer::Helpers::Validate.positive_integer(value, attribute: "max_bytes")
33
+ end
34
+
35
+ #--
36
+ #: (untyped) -> void
37
+ def timeout=(value)
38
+ @timeout = Riffer::Helpers::Validate.positive_integer(value, attribute: "timeout")
39
+ end
40
+
41
+ #--
42
+ #: (untyped) -> void
43
+ def max_per_message=(value)
44
+ @max_per_message =
45
+ value.nil? ? nil : Riffer::Helpers::Validate.positive_integer(value, attribute: "max_per_message")
46
+ end
47
+
48
+ #--
49
+ #: (untyped) -> void
50
+ def runner=(value)
51
+ @runner = Riffer::Helpers::Validate.runner(value, attribute: "runner")
52
+ end
53
+
54
+ #--
55
+ #: (untyped) -> void
56
+ def downloader=(value)
57
+ raise Riffer::ArgumentError, "downloader must respond to #call" unless value.respond_to?(:call)
58
+
59
+ @downloader = value
60
+ end
61
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ class Riffer::Config::Gemini
5
+ attr_reader :api_key #: String? # @dynamic api_key
6
+
7
+ attr_accessor :client #: untyped # @dynamic client, client=
8
+
9
+ #--
10
+ #: () -> void
11
+ def initialize
12
+ @api_key = nil
13
+ @client = nil
14
+ end
15
+
16
+ #--
17
+ #: (untyped) -> void
18
+ def api_key=(value)
19
+ @api_key = Riffer::Helpers::Validate.optional_string(value, attribute: "api_key")
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ class Riffer::Config::Mcp
5
+ attr_reader :credentials #: untyped # @dynamic credentials
6
+
7
+ attr_reader :discovery_runner #: Riffer::Runner # @dynamic discovery_runner
8
+
9
+ #--
10
+ #: () -> void
11
+ def initialize
12
+ @credentials = nil
13
+ @discovery_runner = Riffer::Runner::Sequential.new
14
+ end
15
+
16
+ #--
17
+ #: (untyped) -> void
18
+ def credentials=(value)
19
+ unless value.nil? || value.respond_to?(:call)
20
+ raise Riffer::ArgumentError, "credentials must respond to #call or be nil"
21
+ end
22
+
23
+ @credentials = value
24
+ end
25
+
26
+ #--
27
+ #: (untyped) -> void
28
+ def discovery_runner=(value)
29
+ @discovery_runner = Riffer::Helpers::Validate.runner(value, attribute: "discovery_runner")
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ class Riffer::Config::OpenAI
5
+ attr_reader :api_key #: String? # @dynamic api_key
6
+
7
+ attr_reader :base_url #: String? # @dynamic base_url
8
+
9
+ attr_accessor :client #: untyped # @dynamic client, client=
10
+
11
+ #--
12
+ #: () -> void
13
+ def initialize
14
+ @api_key = nil
15
+ @base_url = nil
16
+ @client = nil
17
+ end
18
+
19
+ #--
20
+ #: (untyped) -> void
21
+ def api_key=(value)
22
+ @api_key = Riffer::Helpers::Validate.optional_string(value, attribute: "api_key")
23
+ end
24
+
25
+ #--
26
+ #: (untyped) -> void
27
+ def base_url=(value)
28
+ @base_url = Riffer::Helpers::Validate.optional_string(value, attribute: "base_url")
29
+ end
30
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ class Riffer::Config::OpenRouter
5
+ attr_reader :api_key #: String? # @dynamic api_key
6
+
7
+ attr_accessor :client #: untyped # @dynamic client, client=
8
+
9
+ #--
10
+ #: () -> void
11
+ def initialize
12
+ @api_key = nil
13
+ @client = nil
14
+ end
15
+
16
+ #--
17
+ #: (untyped) -> void
18
+ def api_key=(value)
19
+ @api_key = Riffer::Helpers::Validate.optional_string(value, attribute: "api_key")
20
+ end
21
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ class Riffer::Config::Pricing::Rates
5
+ attr_reader :input #: Float # @dynamic input
6
+
7
+ attr_reader :output #: Float # @dynamic output
8
+
9
+ attr_reader :cache_read #: Float? # @dynamic cache_read
10
+
11
+ attr_reader :cache_write #: Float? # @dynamic cache_write
12
+
13
+ #--
14
+ #: (input: Float, output: Float, ?cache_read: Float?, ?cache_write: Float?) -> void
15
+ def initialize(input:, output:, cache_read: nil, cache_write: nil)
16
+ @input = input
17
+ @output = output
18
+ @cache_read = cache_read
19
+ @cache_write = cache_write
20
+ end
21
+
22
+ #--
23
+ #: (input_tokens: Integer, output_tokens: Integer, ?cache_read_tokens: Integer?, ?cache_write_tokens: Integer?) -> Float
24
+ def cost_for(input_tokens:, output_tokens:, cache_read_tokens: nil, cache_write_tokens: nil)
25
+ read = cache_read_tokens || 0
26
+ write = cache_write_tokens || 0
27
+ uncached = input_tokens - read - write
28
+ uncached = 0 if uncached.negative?
29
+
30
+ per_million = (uncached * input) +
31
+ (read * (cache_read || input)) +
32
+ (write * (cache_write || input)) +
33
+ (output_tokens * output)
34
+ per_million / 1_000_000.0
35
+ end
36
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ class Riffer::Config::Pricing
5
+ # @rbs @rates: Hash[String, Riffer::Config::Pricing::Rates]
6
+
7
+ #--
8
+ #: () -> void
9
+ def initialize
10
+ @rates = {}
11
+ end
12
+
13
+ #--
14
+ #: ((String | Array[String]), input: Numeric, output: Numeric, ?cache_read: Numeric?, ?cache_write: Numeric?) -> void
15
+ def set(models, input:, output:, cache_read: nil, cache_write: nil)
16
+ ids = models.is_a?(Array) ? models : [models]
17
+ raise Riffer::ArgumentError, "at least one model id is required" if ids.empty?
18
+
19
+ ids.each { |id| Riffer::Helpers::Validate.model_id(id, attribute: "pricing model id") }
20
+
21
+ rates = Rates.new(
22
+ input: coerce_rate(input, "input"),
23
+ output: coerce_rate(output, "output"),
24
+ cache_read: coerce_optional_rate(cache_read, "cache_read"),
25
+ cache_write: coerce_optional_rate(cache_write, "cache_write"),
26
+ )
27
+ ids.each { |id| @rates[id] = rates }
28
+ end
29
+
30
+ #--
31
+ #: (String) -> Riffer::Config::Pricing::Rates?
32
+ def rates_for(model)
33
+ @rates[model]
34
+ end
35
+
36
+ #--
37
+ #: () -> bool
38
+ def empty?
39
+ @rates.empty?
40
+ end
41
+
42
+ private
43
+
44
+ #--
45
+ #: (untyped, String) -> Float
46
+ def coerce_rate(value, attribute)
47
+ number = value
48
+ float = value.is_a?(Numeric) ? number.to_f : nil #: Float?
49
+ unless float&.finite? && float >= 0
50
+ raise Riffer::ArgumentError,
51
+ "#{attribute} rate must be a non-negative number, got #{value.inspect}"
52
+ end
53
+
54
+ float
55
+ end
56
+
57
+ #--
58
+ #: (untyped, String) -> Float?
59
+ def coerce_optional_rate(value, attribute)
60
+ return nil if value.nil?
61
+
62
+ coerce_rate(value, attribute)
63
+ end
64
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ class Riffer::Config::Skills
5
+ attr_reader :default_activate_tool #: singleton(Riffer::Tool) # @dynamic default_activate_tool
6
+
7
+ attr_reader :default_backend #: (Riffer::Skills::Backend | Proc)? # @dynamic default_backend
8
+
9
+ #--
10
+ #: () -> void
11
+ def initialize
12
+ @default_activate_tool = Riffer::Skills::ActivateTool
13
+ @default_backend = nil
14
+ end
15
+
16
+ #--
17
+ #: (singleton(Riffer::Tool)) -> void
18
+ def default_activate_tool=(value)
19
+ unless value.is_a?(Class) && value < Riffer::Tool
20
+ raise Riffer::ArgumentError,
21
+ "default_activate_tool must be a Riffer::Tool subclass"
22
+ end
23
+
24
+ @default_activate_tool = value
25
+ end
26
+
27
+ #--
28
+ #: ((Riffer::Skills::Backend | Proc)?) -> void
29
+ def default_backend=(value)
30
+ valid = value.nil? || value.is_a?(Riffer::Skills::Backend) || value.is_a?(Proc)
31
+ unless valid
32
+ raise Riffer::ArgumentError,
33
+ "default_backend must be a Riffer::Skills::Backend instance, Proc, or nil"
34
+ end
35
+
36
+ @default_backend = value
37
+ end
38
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ # rbs_inline: enabled
3
+
4
+ class Riffer::Config::Tracing
5
+ attr_reader :enabled #: bool # @dynamic enabled
6
+
7
+ attr_reader :capture_messages #: bool # @dynamic capture_messages
8
+
9
+ attr_reader :backend #: untyped # @dynamic backend
10
+
11
+ #--
12
+ #: () -> void
13
+ def initialize
14
+ # Spans are a no-op until a host wires an OTEL SDK.
15
+ @enabled = true
16
+ # Message content routinely carries sensitive data.
17
+ @capture_messages = false
18
+ @backend = nil
19
+ end
20
+
21
+ #--
22
+ #: (untyped) -> void
23
+ def enabled=(value)
24
+ @enabled = Riffer::Helpers::Boolean.coerce(value, attribute: "enabled")
25
+ end
26
+
27
+ #--
28
+ #: (untyped) -> void
29
+ def capture_messages=(value)
30
+ @capture_messages = Riffer::Helpers::Boolean.coerce(value, attribute: "capture_messages")
31
+ end
32
+
33
+ #--
34
+ #: (untyped) -> void
35
+ def backend=(value)
36
+ contract = %i[in_span current_context with_context]
37
+ unless value.nil? || contract.all? { |method| value.respond_to?(method) }
38
+ raise Riffer::ArgumentError, "tracing backend must respond to #in_span, #current_context, and #with_context"
39
+ end
40
+
41
+ @backend = value
42
+ end
43
+ end