riffer 0.52.1 → 0.54.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/rules/rbs-inline.md +2 -2
  3. data/.release-please-manifest.json +1 -1
  4. data/CHANGELOG.md +22 -0
  5. data/Steepfile +19 -0
  6. data/docs/AGENTS.md +81 -4
  7. data/docs/CATALOG.md +205 -0
  8. data/docs/CONFIGURATION.md +35 -23
  9. data/docs/MESSAGES.md +1 -1
  10. data/docs/OVERVIEW.md +1 -1
  11. data/docs/SERIALIZATION.md +1 -0
  12. data/docs/TOOLS.md +15 -12
  13. data/docs/TRACING.md +2 -1
  14. data/docs/providers/AMAZON_BEDROCK.md +2 -0
  15. data/docs/providers/ANTHROPIC.md +2 -0
  16. data/docs/providers/AZURE_OPENAI.md +2 -0
  17. data/docs/providers/CUSTOM_PROVIDERS.md +15 -1
  18. data/docs/providers/GEMINI.md +11 -0
  19. data/docs/providers/MOCK_PROVIDER.md +2 -0
  20. data/docs/providers/OPENAI.md +2 -0
  21. data/docs/providers/OPENROUTER.md +2 -0
  22. data/docs-site/manifest.yml +3 -0
  23. data/lib/riffer/agent/config.rb +17 -0
  24. data/lib/riffer/agent/run.rb +2 -0
  25. data/lib/riffer/agent/serializer.rb +2 -0
  26. data/lib/riffer/agent/structured_output.rb +23 -3
  27. data/lib/riffer/agent.rb +7 -0
  28. data/lib/riffer/{config/pricing → catalog}/rates.rb +21 -6
  29. data/lib/riffer/catalog.rb +225 -0
  30. data/lib/riffer/config/pricing.rb +17 -27
  31. data/lib/riffer/config.rb +29 -0
  32. data/lib/riffer/params/any_of.rb +22 -0
  33. data/lib/riffer/params/format.rb +73 -0
  34. data/lib/riffer/params/param.rb +120 -17
  35. data/lib/riffer/params.rb +135 -24
  36. data/lib/riffer/providers/amazon_bedrock.rb +14 -0
  37. data/lib/riffer/providers/anthropic.rb +8 -0
  38. data/lib/riffer/providers/base.rb +67 -15
  39. data/lib/riffer/providers/gemini.rb +7 -0
  40. data/lib/riffer/providers/mock.rb +7 -0
  41. data/lib/riffer/providers/open_ai.rb +6 -0
  42. data/lib/riffer/providers/open_router.rb +6 -0
  43. data/lib/riffer/version.rb +1 -1
  44. data/lib/riffer.rb +2 -0
  45. data/rbs_collection.lock.yaml +8 -0
  46. data/rbs_collection.yaml +2 -0
  47. data/sig/generated/riffer/agent/config.rbs +10 -1
  48. data/sig/generated/riffer/agent/structured_output.rbs +6 -0
  49. data/sig/generated/riffer/agent.rbs +4 -0
  50. data/sig/generated/riffer/{config/pricing → catalog}/rates.rbs +10 -4
  51. data/sig/generated/riffer/catalog.rbs +77 -0
  52. data/sig/generated/riffer/config/pricing.rbs +12 -11
  53. data/sig/generated/riffer/config.rbs +17 -0
  54. data/sig/generated/riffer/params/any_of.rbs +13 -0
  55. data/sig/generated/riffer/params/format.rbs +39 -0
  56. data/sig/generated/riffer/params/param.rbs +22 -4
  57. data/sig/generated/riffer/params.rbs +34 -8
  58. data/sig/generated/riffer/providers/amazon_bedrock.rbs +6 -0
  59. data/sig/generated/riffer/providers/anthropic.rbs +4 -0
  60. data/sig/generated/riffer/providers/base.rbs +22 -2
  61. data/sig/generated/riffer/providers/gemini.rbs +4 -0
  62. data/sig/generated/riffer/providers/mock.rbs +5 -0
  63. data/sig/generated/riffer/providers/open_ai.rbs +4 -0
  64. data/sig/generated/riffer/providers/open_router.rbs +4 -0
  65. data/sig/generated/riffer.rbs +1 -0
  66. data/sig/manifest.yaml +2 -1
  67. data/sig/manual/riffer/params/format.rbs +5 -0
  68. metadata +11 -3
@@ -38,7 +38,8 @@ class Riffer::Providers::Base
38
38
  messages = normalize_messages(prompt: prompt, system: system, messages: messages, files: files)
39
39
  validate_normalized_messages!(messages)
40
40
  Riffer::Files::Resolver.new(provider: self).resolve!(messages)
41
- messages = merge_consecutive_messages(with_structured_output_prompt(messages, options[:structured_output]))
41
+ messages = with_structured_output_prompt(merge_consecutive_messages(messages), options[:structured_output])
42
+ options = apply_reasoning(model, options)
42
43
  params = build_request_params(messages, model, request_options(options))
43
44
 
44
45
  in_chat_span(model, messages, options) do |span|
@@ -76,7 +77,8 @@ class Riffer::Providers::Base
76
77
  messages = normalize_messages(prompt: prompt, system: system, messages: messages, files: files)
77
78
  validate_normalized_messages!(messages)
78
79
  Riffer::Files::Resolver.new(provider: self).resolve!(messages)
79
- messages = merge_consecutive_messages(with_structured_output_prompt(messages, options[:structured_output]))
80
+ messages = with_structured_output_prompt(merge_consecutive_messages(messages), options[:structured_output])
81
+ options = apply_reasoning(model, options)
80
82
  params = build_request_params(messages, model, request_options(options))
81
83
 
82
84
  # The enumerator body runs in its own fiber, where the fiber-local OTEL
@@ -188,18 +190,64 @@ class Riffer::Providers::Base
188
190
  end
189
191
 
190
192
  #--
191
- #: () -> Riffer::Config::Pricing::Rates?
193
+ #: () -> Riffer::Catalog::Rates?
192
194
  def pricing_rates
193
195
  model = @current_model
194
196
  return nil unless model
195
197
 
196
- pricing = Riffer.config.pricing
197
- return nil if pricing.empty?
198
-
199
- key = Riffer::Providers::Repository.key_for(self.class)
198
+ key = catalog_key(model)
200
199
  return nil unless key
201
200
 
202
- pricing.rates_for("#{key}/#{model}")
201
+ Riffer.config.catalog.rates_for(key) || Riffer.config.pricing.rates_for(key)
202
+ end
203
+
204
+ #--
205
+ #: (String) -> String?
206
+ def catalog_key(model)
207
+ provider_key = Riffer::Providers::Repository.key_for(self.class)
208
+ "#{provider_key}/#{model}" if provider_key
209
+ end
210
+
211
+ # A catalog fragment beats the provider default per level; the caller's
212
+ # options are merged over either, so +model_options+ always wins.
213
+ #--
214
+ #: (String?, Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
215
+ def apply_reasoning(model, options)
216
+ value = options[:riffer_reasoning_level]
217
+ return options if value.nil?
218
+
219
+ level = value.to_s.to_sym
220
+ levels = Riffer::Agent::Config::REASONING_LEVELS
221
+ unless levels.include?(level)
222
+ raise Riffer::ArgumentError, "riffer_reasoning_level must be one of #{levels.join(', ')}, got #{value.inspect}"
223
+ end
224
+
225
+ key = model && catalog_key(model)
226
+ fragment = (key && Riffer.config.catalog.reasoning_options(key, level)) || default_reasoning_options(level)
227
+ unless fragment
228
+ raise Riffer::ArgumentError,
229
+ "No reasoning mapping for #{key || model.inspect} at level #{level.inspect}. " \
230
+ "Add one in a catalog file (see docs/CATALOG.md)."
231
+ end
232
+
233
+ # A copy, since catalog fragments are frozen and providers may edit nested params.
234
+ deep_merge(Riffer::Helpers::DeepDup.call(fragment), options.merge(riffer_reasoning_level: level))
235
+ end
236
+
237
+ # Maps a level onto the provider's own reasoning params when the catalog has
238
+ # no entry; +nil+ means riffer raises before the request.
239
+ #--
240
+ #: (Symbol) -> Hash[Symbol, untyped]?
241
+ def default_reasoning_options(_level)
242
+ nil
243
+ end
244
+
245
+ #--
246
+ #: (Hash[Symbol, untyped], Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
247
+ def deep_merge(base, override)
248
+ base.merge(override) do |_key, base_value, override_value|
249
+ base_value.is_a?(Hash) && override_value.is_a?(Hash) ? deep_merge(base_value, override_value) : override_value
250
+ end
203
251
  end
204
252
 
205
253
  #--
@@ -274,6 +322,9 @@ class Riffer::Providers::Base
274
322
  attributes[attribute] = value if value
275
323
  end
276
324
 
325
+ reasoning_level = options[:riffer_reasoning_level]
326
+ attributes["riffer.request.reasoning_level"] = reasoning_level.to_s if reasoning_level
327
+
277
328
  attributes.merge(tag_attributes(options[:tags] || {}))
278
329
  end
279
330
 
@@ -376,18 +427,19 @@ class Riffer::Providers::Base
376
427
  def with_structured_output_prompt(messages, structured_output)
377
428
  return messages unless structured_output&.prompted?
378
429
 
379
- # After the leading system messages, so merge_consecutive_messages folds it into the system prompt.
380
- leading_system = messages.take_while { |m| m.is_a?(Riffer::Messages::System) }
381
- [
382
- *leading_system,
383
- Riffer::Messages::System.new(structured_output.prompt_instructions),
384
- *messages.drop(leading_system.length),
385
- ]
430
+ # Models follow the schema more reliably at the end of each user turn than in the system prompt.
431
+ instructions = structured_output.prompt_instructions
432
+ messages.map do |message|
433
+ next message unless message.is_a?(Riffer::Messages::User)
434
+
435
+ Riffer::Messages::User.new("#{message.content}\n\n#{instructions}", id: message.id, files: message.files)
436
+ end
386
437
  end
387
438
 
388
439
  #--
389
440
  #: (Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
390
441
  def request_options(options)
442
+ options = options.except(:riffer_reasoning_level)
391
443
  options[:structured_output]&.prompted? ? options.except(:structured_output) : options
392
444
  end
393
445
 
@@ -54,6 +54,12 @@ class Riffer::Providers::Gemini < Riffer::Providers::Base
54
54
  Riffer::Providers::Gemini::Client.new(**{ api_key: Riffer.config.gemini.api_key }.compact)
55
55
  end
56
56
 
57
+ #--
58
+ #: (Symbol) -> Hash[Symbol, untyped]
59
+ def default_reasoning_options(level)
60
+ { thinkingConfig: { thinkingLevel: level.to_s } }
61
+ end
62
+
57
63
  #--
58
64
  #: (Array[Riffer::Messages::Base], String?, Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
59
65
  def build_request_params(messages, model, options)
@@ -334,6 +340,7 @@ class Riffer::Providers::Gemini < Riffer::Providers::Base
334
340
  end
335
341
 
336
342
  schema[:items] = strip_additional_properties(schema[:items]) if schema[:items].is_a?(Hash)
343
+ schema[:anyOf] = schema[:anyOf].map { |branch| strip_additional_properties(branch) } if schema[:anyOf]
337
344
 
338
345
  schema
339
346
  end
@@ -75,6 +75,13 @@ class Riffer::Providers::Mock < Riffer::Providers::Base
75
75
  }
76
76
  end
77
77
 
78
+ # Never raises, so test suites can set +reasoning+ without catalog entries.
79
+ #--
80
+ #: (Symbol) -> Hash[Symbol, untyped]
81
+ def default_reasoning_options(_level)
82
+ {}
83
+ end
84
+
78
85
  #--
79
86
  #: (Array[Riffer::Messages::Base], String?, Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
80
87
  def build_request_params(messages, model, options)
@@ -56,6 +56,12 @@ class Riffer::Providers::OpenAI < Riffer::Providers::Base
56
56
  }.compact)
57
57
  end
58
58
 
59
+ #--
60
+ #: (Symbol) -> Hash[Symbol, untyped]
61
+ def default_reasoning_options(level)
62
+ { reasoning: level == :off ? "none" : level.to_s }
63
+ end
64
+
59
65
  #--
60
66
  #: (Array[Riffer::Messages::Base], String?, Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
61
67
  def build_request_params(messages, model, options)
@@ -72,6 +72,12 @@ class Riffer::Providers::OpenRouter < Riffer::Providers::Base
72
72
  ::OpenAI::Client.new(api_key: api_key, base_url: BASE_URL)
73
73
  end
74
74
 
75
+ #--
76
+ #: (Symbol) -> Hash[Symbol, untyped]
77
+ def default_reasoning_options(level)
78
+ { reasoning: level == :off ? "none" : level.to_s }
79
+ end
80
+
75
81
  #--
76
82
  #: (Array[Riffer::Messages::Base], String?, Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
77
83
  def build_request_params(messages, model, options)
@@ -2,5 +2,5 @@
2
2
  # rbs_inline: enabled
3
3
 
4
4
  module Riffer
5
- VERSION = "0.52.1" #: String
5
+ VERSION = "0.54.0" #: String
6
6
  end
data/lib/riffer.rb CHANGED
@@ -62,10 +62,12 @@ module Riffer
62
62
  @config ||= Config.new
63
63
  end
64
64
 
65
+ # Builds the catalog after the block, so a bad catalog file fails boot.
65
66
  #--
66
67
  #: () ?{ (Riffer::Config) -> void } -> void
67
68
  def configure(&)
68
69
  yield config if block_given?
70
+ config.reload_catalog
69
71
  end
70
72
 
71
73
  #--
@@ -77,6 +77,10 @@ gems:
77
77
  revision: 3913b7dffb65bdffdfe5cb9095108f932e85433b
78
78
  remote: https://github.com/ruby/gem_rbs_collection.git
79
79
  repo_dir: gems
80
+ - name: date
81
+ version: '0'
82
+ source:
83
+ type: stdlib
80
84
  - name: dbm
81
85
  version: '0'
82
86
  source:
@@ -125,6 +129,10 @@ gems:
125
129
  version: '0'
126
130
  source:
127
131
  type: stdlib
132
+ - name: ipaddr
133
+ version: '0'
134
+ source:
135
+ type: stdlib
128
136
  - name: json
129
137
  version: '0'
130
138
  source:
data/rbs_collection.yaml CHANGED
@@ -10,3 +10,5 @@ path: .gem_rbs_collection
10
10
  gems:
11
11
  - name: yaml
12
12
  - name: cgi
13
+ - name: date
14
+ - name: ipaddr
@@ -5,6 +5,8 @@ class Riffer::Agent::Config
5
5
 
6
6
  STRUCTURED_OUTPUT_STRATEGIES: Array[Symbol]
7
7
 
8
+ REASONING_LEVELS: Array[Symbol]
9
+
8
10
  @tool_runtime: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?
9
11
 
10
12
  attr_reader identifier: String?
@@ -21,6 +23,8 @@ class Riffer::Agent::Config
21
23
 
22
24
  attr_accessor max_steps: Numeric?
23
25
 
26
+ attr_reader reasoning: Symbol?
27
+
24
28
  attr_accessor tools_config: (Array[singleton(Riffer::Tool)] | Proc)?
25
29
 
26
30
  attr_reader mcp_configs: Array[Hash[Symbol, untyped]]
@@ -38,13 +42,14 @@ class Riffer::Agent::Config
38
42
  # ?structured_output: Riffer::Params?,
39
43
  # ?structured_output_strategy: Symbol,
40
44
  # ?max_steps: Numeric?,
45
+ # ?reasoning: (Symbol | String)?,
41
46
  # ?tools_config: (Array[singleton(Riffer::Tool)] | Proc)?,
42
47
  # ?mcp_configs: Array[Hash[Symbol, untyped]],
43
48
  # ?tool_runtime: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?,
44
49
  # ?skills_config: Riffer::Skills::Config?,
45
50
  # ?guardrails: Hash[Symbol, Array[Hash[Symbol, untyped]]]
46
51
  # ) -> void
47
- def initialize: (?identifier: String?, ?model: (String | Proc)?, ?instructions: (String | Proc)?, ?model_options: Hash[Symbol, untyped], ?structured_output: Riffer::Params?, ?structured_output_strategy: Symbol, ?max_steps: Numeric?, ?tools_config: (Array[singleton(Riffer::Tool)] | Proc)?, ?mcp_configs: Array[Hash[Symbol, untyped]], ?tool_runtime: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?, ?skills_config: Riffer::Skills::Config?, ?guardrails: Hash[Symbol, Array[Hash[Symbol, untyped]]]) -> void
52
+ def initialize: (?identifier: String?, ?model: (String | Proc)?, ?instructions: (String | Proc)?, ?model_options: Hash[Symbol, untyped], ?structured_output: Riffer::Params?, ?structured_output_strategy: Symbol, ?max_steps: Numeric?, ?reasoning: (Symbol | String)?, ?tools_config: (Array[singleton(Riffer::Tool)] | Proc)?, ?mcp_configs: Array[Hash[Symbol, untyped]], ?tool_runtime: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?, ?skills_config: Riffer::Skills::Config?, ?guardrails: Hash[Symbol, Array[Hash[Symbol, untyped]]]) -> void
48
53
 
49
54
  # --
50
55
  # : (untyped) -> String?
@@ -58,6 +63,10 @@ class Riffer::Agent::Config
58
63
  # : (Symbol) -> Symbol
59
64
  def structured_output_strategy=: (Symbol) -> Symbol
60
65
 
66
+ # --
67
+ # : ((Symbol | String)?) -> Symbol?
68
+ def reasoning=: ((Symbol | String)?) -> Symbol?
69
+
61
70
  # --
62
71
  # : () -> (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)
63
72
  def tool_runtime: () -> (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)
@@ -25,4 +25,10 @@ class Riffer::Agent::StructuredOutput
25
25
  # --
26
26
  # : (String) -> Riffer::Agent::StructuredOutput::Result
27
27
  def parse_and_validate: (String) -> Riffer::Agent::StructuredOutput::Result
28
+
29
+ private
30
+
31
+ # --
32
+ # : (Hash[Symbol, untyped]) -> untyped
33
+ def placeholder: (Hash[Symbol, untyped]) -> untyped
28
34
  end
@@ -39,6 +39,10 @@ class Riffer::Agent
39
39
  # : (*Numeric?) -> Numeric?
40
40
  def self.max_steps: (*Numeric?) -> Numeric?
41
41
 
42
+ # --
43
+ # : (?(Symbol | String)?) -> Symbol?
44
+ def self.reasoning: (?(Symbol | String)?) -> Symbol?
45
+
42
46
  # --
43
47
  # : (?(Array[singleton(Riffer::Tool)] | Proc)?) -> (Array[singleton(Riffer::Tool)] | Proc)?
44
48
  def self.uses_tools: (?(Array[singleton(Riffer::Tool)] | Proc)?) -> (Array[singleton(Riffer::Tool)] | Proc)?
@@ -1,6 +1,6 @@
1
- # Generated from lib/riffer/config/pricing/rates.rb with RBS::Inline
1
+ # Generated from lib/riffer/catalog/rates.rb with RBS::Inline
2
2
 
3
- class Riffer::Config::Pricing::Rates
3
+ class Riffer::Catalog::Rates
4
4
  attr_reader input: Float
5
5
 
6
6
  attr_reader output: Float
@@ -10,10 +10,16 @@ class Riffer::Config::Pricing::Rates
10
10
  attr_reader cache_write: Float?
11
11
 
12
12
  # --
13
- # : (input: Float, output: Float, ?cache_read: Float?, ?cache_write: Float?) -> void
14
- def initialize: (input: Float, output: Float, ?cache_read: Float?, ?cache_write: Float?) -> void
13
+ # : (input: untyped, output: untyped, ?cache_read: untyped, ?cache_write: untyped) -> void
14
+ def initialize: (input: untyped, output: untyped, ?cache_read: untyped, ?cache_write: untyped) -> void
15
15
 
16
16
  # --
17
17
  # : (input_tokens: Integer, output_tokens: Integer, ?cache_read_tokens: Integer?, ?cache_write_tokens: Integer?) -> Float
18
18
  def cost_for: (input_tokens: Integer, output_tokens: Integer, ?cache_read_tokens: Integer?, ?cache_write_tokens: Integer?) -> Float
19
+
20
+ private
21
+
22
+ # --
23
+ # : (untyped, String) -> Float
24
+ def coerce_rate: (untyped, String) -> Float
19
25
  end
@@ -0,0 +1,77 @@
1
+ # Generated from lib/riffer/catalog.rb with RBS::Inline
2
+
3
+ class Riffer::Catalog
4
+ SUPPORTED_VERSIONS: Array[Integer]
5
+
6
+ FILE_KEYS: Array[String]
7
+
8
+ ENTRY_KEYS: Array[String]
9
+
10
+ PRICING_KEYS: Array[String]
11
+
12
+ @aliases: Hash[String, String]
13
+
14
+ @models: Hash[String, Hash[Symbol, untyped]]
15
+
16
+ # --
17
+ # : (Array[String]) -> Riffer::Catalog
18
+ def self.load: (Array[String]) -> Riffer::Catalog
19
+
20
+ # --
21
+ # : (models: Hash[String, Hash[Symbol, untyped]], aliases: Hash[String, String]) -> void
22
+ def initialize: (models: Hash[String, Hash[Symbol, untyped]], aliases: Hash[String, String]) -> void
23
+
24
+ # --
25
+ # : (String, Symbol) -> Hash[Symbol, untyped]?
26
+ def reasoning_options: (String, Symbol) -> Hash[Symbol, untyped]?
27
+
28
+ # --
29
+ # : (String) -> Riffer::Catalog::Rates?
30
+ def rates_for: (String) -> Riffer::Catalog::Rates?
31
+
32
+ # --
33
+ # : () -> bool
34
+ def empty?: () -> bool
35
+
36
+ # --
37
+ # : (String) -> Hash[String, Hash[Symbol, untyped]]
38
+ def self.parse_file: (String) -> Hash[String, Hash[Symbol, untyped]]
39
+
40
+ # --
41
+ # : (String, String, untyped) -> Hash[Symbol, untyped]
42
+ def self.parse_entry: (String, String, untyped) -> Hash[Symbol, untyped]
43
+
44
+ # --
45
+ # : (String, String, untyped) -> Array[String]
46
+ def self.parse_aliases: (String, String, untyped) -> Array[String]
47
+
48
+ # --
49
+ # : (String, String, untyped) -> Riffer::Catalog::Rates
50
+ def self.parse_pricing: (String, String, untyped) -> Riffer::Catalog::Rates
51
+
52
+ # --
53
+ # : (String, String, untyped) -> Hash[Symbol, Hash[Symbol, untyped]]
54
+ def self.parse_reasoning: (String, String, untyped) -> Hash[Symbol, Hash[Symbol, untyped]]
55
+
56
+ # --
57
+ # : (String, untyped, String) -> void
58
+ def self.validate_model_key!: (String, untyped, String) -> void
59
+
60
+ # --
61
+ # : (untyped) -> untyped
62
+ def self.symbolize_keys: (untyped) -> untyped
63
+
64
+ # --
65
+ # : (String, String) -> bot
66
+ def self.fail_load!: (String, String) -> bot
67
+
68
+ private
69
+
70
+ # --
71
+ # : (String) -> Hash[Symbol, untyped]?
72
+ def entry: (String) -> Hash[Symbol, untyped]?
73
+
74
+ # --
75
+ # : (untyped) -> untyped
76
+ def deep_freeze: (untyped) -> untyped
77
+ end
@@ -1,7 +1,13 @@
1
1
  # Generated from lib/riffer/config/pricing.rb with RBS::Inline
2
2
 
3
+ # @deprecated Set pricing in a catalog file instead (see docs/CATALOG.md).
4
+ # A catalog entry's pricing wins over rates registered here.
3
5
  class Riffer::Config::Pricing
4
- @rates: Hash[String, Riffer::Config::Pricing::Rates]
6
+ DEPRECATION_MESSAGE: String
7
+
8
+ @rates: Hash[String, Riffer::Catalog::Rates]
9
+
10
+ self.@warned: bool
5
11
 
6
12
  # --
7
13
  # : () -> void
@@ -12,20 +18,15 @@ class Riffer::Config::Pricing
12
18
  def set: (String | Array[String], input: Numeric, output: Numeric, ?cache_read: Numeric?, ?cache_write: Numeric?) -> void
13
19
 
14
20
  # --
15
- # : (String) -> Riffer::Config::Pricing::Rates?
16
- def rates_for: (String) -> Riffer::Config::Pricing::Rates?
21
+ # : (String) -> Riffer::Catalog::Rates?
22
+ def rates_for: (String) -> Riffer::Catalog::Rates?
17
23
 
18
24
  # --
19
25
  # : () -> bool
20
26
  def empty?: () -> bool
21
27
 
22
- private
23
-
28
+ # Once per process, so a boot that sets many models logs one line.
24
29
  # --
25
- # : (untyped, String) -> Float
26
- def coerce_rate: (untyped, String) -> Float
27
-
28
- # --
29
- # : (untyped, String) -> Float?
30
- def coerce_optional_rate: (untyped, String) -> Float?
30
+ # : () -> void
31
+ def self.warn_deprecated: () -> void
31
32
  end
@@ -3,6 +3,8 @@
3
3
  class Riffer::Config
4
4
  VALID_MESSAGE_ID_STRATEGIES: untyped
5
5
 
6
+ @catalog: Riffer::Catalog?
7
+
6
8
  attr_reader amazon_bedrock: Riffer::Config::AmazonBedrock
7
9
 
8
10
  attr_reader anthropic: Riffer::Config::Anthropic
@@ -31,8 +33,23 @@ class Riffer::Config
31
33
 
32
34
  attr_reader files: Riffer::Config::Files
33
35
 
36
+ # @deprecated Use +catalog_files+.
34
37
  attr_reader pricing: Riffer::Config::Pricing
35
38
 
39
+ attr_reader catalog_files: Array[String]
40
+
41
+ # --
42
+ # : (Array[untyped]) -> void
43
+ def catalog_files=: (Array[untyped]) -> void
44
+
45
+ # --
46
+ # : () -> Riffer::Catalog
47
+ def catalog: () -> Riffer::Catalog
48
+
49
+ # --
50
+ # : () -> Riffer::Catalog
51
+ def reload_catalog: () -> Riffer::Catalog
52
+
36
53
  # When not +:none+, seeded messages passed to +Riffer::Agent#generate+ must
37
54
  # carry their own +id+.
38
55
  attr_reader message_id_strategy: Symbol
@@ -0,0 +1,13 @@
1
+ # Generated from lib/riffer/params/any_of.rb with RBS::Inline
2
+
3
+ class Riffer::Params::AnyOf
4
+ attr_reader variants: Array[Riffer::Params]
5
+
6
+ # --
7
+ # : () -> void
8
+ def initialize: () -> void
9
+
10
+ # --
11
+ # : () ?{ (Riffer::Params) [self: Riffer::Params] -> void } -> void
12
+ def variant: () ?{ (Riffer::Params) [self: Riffer::Params] -> void } -> void
13
+ end
@@ -0,0 +1,39 @@
1
+ # Generated from lib/riffer/params/format.rb with RBS::Inline
2
+
3
+ module Riffer::Params::Format
4
+ DATE: Regexp
5
+
6
+ DATE_TIME: Regexp
7
+
8
+ # The offset is optional: Anthropic's grammar emits times without one.
9
+ TIME: Regexp
10
+
11
+ DURATION: Regexp
12
+
13
+ UUID: Regexp
14
+
15
+ # The WHATWG HTML pattern: no single pattern matches RFC 5322 exactly, so
16
+ # this one only rules out values that are clearly not an address.
17
+ EMAIL: Regexp
18
+
19
+ HOSTNAME: Regexp
20
+
21
+ # The formats OpenAI, Anthropic and Bedrock all accept. OpenAI rejects uri.
22
+ CHECKS: Hash[String, ^(String) -> bool]
23
+
24
+ NAMES: Array[String]
25
+
26
+ # --
27
+ # : (String, String) -> bool
28
+ def valid?: (String, String) -> bool
29
+
30
+ private
31
+
32
+ # --
33
+ # : (Regexp, String) -> bool
34
+ def calendar_date?: (Regexp, String) -> bool
35
+
36
+ # --
37
+ # : (String) { (IPAddr) -> bool } -> bool
38
+ def ip_address?: (String) { (IPAddr) -> bool } -> bool
39
+ end
@@ -17,27 +17,41 @@ class Riffer::Params::Param
17
17
 
18
18
  attr_reader enum: Array[untyped]?
19
19
 
20
+ attr_reader format: String?
21
+
20
22
  attr_reader default: untyped
21
23
 
22
24
  attr_reader item_type: Module?
23
25
 
26
+ attr_reader dimensions: Integer
27
+
24
28
  attr_reader nested_params: Riffer::Params?
25
29
 
30
+ attr_reader variants: Array[Riffer::Params]?
31
+
26
32
  # --
27
33
  # : (Symbol, Hash[Symbol, untyped], required: bool) -> Riffer::Params::Param
28
34
  def self.from_json_schema: (Symbol, Hash[Symbol, untyped], required: bool) -> Riffer::Params::Param
29
35
 
30
36
  # --
31
- # : (Module, Hash[Symbol, untyped]) -> [Module?, Riffer::Params?]
32
- def self.resolve_nesting: (Module, Hash[Symbol, untyped]) -> [ Module?, Riffer::Params? ]
37
+ # : (Array[Hash[Symbol, untyped]]) -> Array[Riffer::Params]
38
+ def self.resolve_variants: (Array[Hash[Symbol, untyped]]) -> Array[Riffer::Params]
39
+
40
+ # --
41
+ # : (Module, Hash[Symbol, untyped]) -> Riffer::Params?
42
+ def self.resolve_nested_params: (Module, Hash[Symbol, untyped]) -> Riffer::Params?
43
+
44
+ # --
45
+ # : (Hash[Symbol, untyped]) -> [Module, Integer, Hash[Symbol, untyped]]?
46
+ def self.resolve_typed_items: (Hash[Symbol, untyped]) -> [ Module, Integer, Hash[Symbol, untyped] ]?
33
47
 
34
48
  # --
35
49
  # : (untyped) -> Module
36
50
  def self.json_type_to_ruby: (untyped) -> Module
37
51
 
38
52
  # --
39
- # : (name: Symbol, type: Module, required: bool, ?description: String?, ?enum: Array[untyped]?, ?default: untyped, ?item_type: Module?, ?nested_params: Riffer::Params?) -> void
40
- def initialize: (name: Symbol, type: Module, required: bool, ?description: String?, ?enum: Array[untyped]?, ?default: untyped, ?item_type: Module?, ?nested_params: Riffer::Params?) -> void
53
+ # : (name: Symbol, type: Module, required: bool, ?description: String?, ?enum: Array[untyped]?, ?format: String?, ?default: untyped, ?item_type: Module?, ?dimensions: Integer, ?nested_params: Riffer::Params?, ?variants: Array[Riffer::Params]?) -> void
54
+ def initialize: (name: Symbol, type: Module, required: bool, ?description: String?, ?enum: Array[untyped]?, ?format: String?, ?default: untyped, ?item_type: Module?, ?dimensions: Integer, ?nested_params: Riffer::Params?, ?variants: Array[Riffer::Params]?) -> void
41
55
 
42
56
  # --
43
57
  # : (untyped) -> bool
@@ -60,6 +74,10 @@ class Riffer::Params::Param
60
74
  # : (Riffer::Params::Param) -> void
61
75
  def initialize_copy: (Riffer::Params::Param) -> void
62
76
 
77
+ # --
78
+ # : () -> void
79
+ def validate_format!: () -> void
80
+
63
81
  # --
64
82
  # : () -> void
65
83
  def validate_strict_shape!: () -> void