Class: Riffer::Params
- Inherits:
-
Object
- Object
- Riffer::Params
- Defined in:
- lib/riffer/params.rb,
sig/generated/riffer/params.rbs
Overview
A DSL for defining tool parameters and structured-output schemas, used within
a Tool's params block.
params do
required :city, String, description: "The city name"
optional :units, String, default: "celsius", enum: ["celsius", "fahrenheit"]
end
Defined Under Namespace
Modules: Boolean Classes: Param
Instance Attribute Summary collapse
-
#parameters ⇒ Array[Riffer::Params::Param]
readonly
The defined parameters.
Class Method Summary collapse
-
.from_json_schema(schema) ⇒ Riffer::Params
Reconstructs a Params from a JSON Schema object — the inverse of
to_json_schema(strict: false).
Instance Method Summary collapse
-
#build_nested(type, of, &block) ⇒ void
-- : (Module, Module?) ?{ (Riffer::Params) [self: Riffer::Params] -> void } -> Riffer::Params?.
-
#initialize ⇒ Params
constructor
-- : () -> void.
-
#optional(name, type, description: nil, enum: nil, default: nil, of: nil, &block) ⇒ void
Defines an optional parameter.
-
#required(name, type, description: nil, enum: nil, of: nil, &block) ⇒ void
Defines a required parameter.
-
#to_json_schema(strict: false) ⇒ Hash[Symbol, untyped]
Converts all parameters to JSON Schema format.
-
#validate(arguments) ⇒ Hash[Symbol, untyped]
Validates arguments against parameter definitions.
-
#validate_nested(param, value, errors) ⇒ Object
-- : (Riffer::Params::Param, untyped, Array) -> untyped.
- #validate_nested_array_of_objects(param, value, errors) ⇒ Array[untyped]
-
#validate_nested_hash(param, value, errors) ⇒ Hash[Symbol, untyped]
-- : (Riffer::Params::Param, Hash[Symbol, untyped], Array) -> Hash[Symbol, untyped].
- #validate_typed_array(param, value, errors) ⇒ void
Constructor Details
#initialize ⇒ Params
-- : () -> void
18 19 20 |
# File 'lib/riffer/params.rb', line 18 def initialize @parameters = [] end |
Instance Attribute Details
#parameters ⇒ Array[Riffer::Params::Param] (readonly)
The defined parameters.
14 15 16 |
# File 'lib/riffer/params.rb', line 14 def parameters @parameters end |
Class Method Details
.from_json_schema(schema) ⇒ Riffer::Params
Reconstructs a Params from a JSON Schema object — the inverse of
to_json_schema(strict: false). Raises Riffer::ArgumentError on features
outside the Params-expressible subset of JSON Schema.
schema = params.to_json_schema(strict: false)
Riffer::Params.from_json_schema(schema) # => equivalent Riffer::Params
-- : (Hash[Symbol, untyped]) -> Riffer::Params
31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/riffer/params.rb', line 31 def self.from_json_schema(schema) params = new properties = schema[:properties] || {} required = (schema[:required] || []).map { |key| key.to_s } properties.each do |name, property_schema| params.parameters << Riffer::Params::Param.from_json_schema( name.to_sym, property_schema, required: required.include?(name.to_s) ) end params end |
Instance Method Details
#build_nested(type, of, &block) ⇒ void
This method returns an undefined value.
-- : (Module, Module?) ?{ (Riffer::Params) [self: Riffer::Params] -> void } -> Riffer::Params?
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/riffer/params.rb', line 149 def build_nested(type, of, &block) if of && block raise Riffer::ArgumentError, "cannot use both of: and a block" end if of unless type == Array raise Riffer::ArgumentError, "of: can only be used with Array type, got #{type}" end unless Riffer::Params::Param::PRIMITIVE_TYPES.include?(of) raise Riffer::ArgumentError, "of: must be a primitive type (#{Riffer::Params::Param::PRIMITIVE_TYPES.map(&:name).join(", ")}), got #{of}" end return nil end if block unless type == Hash || type == Array raise Riffer::ArgumentError, "block can only be used with Hash or Array type, got #{type}" end nested = Riffer::Params.new nested.instance_eval(&block) nested end end |
#optional(name, type, description: nil, enum: nil, default: nil, of: nil, &block) ⇒ void
This method returns an undefined value.
Defines an optional parameter.
-- : (Symbol, Module, ?description: String?, ?enum: Array?, ?default: untyped, ?of: Module?) ?{ (Riffer::Params) [self: Riffer::Params] -> void } -> void
66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/riffer/params.rb', line 66 def optional(name, type, description: nil, enum: nil, default: nil, of: nil, &block) nested = build_nested(type, of, &block) @parameters << Riffer::Params::Param.new( name: name, type: type, required: false, description: description, enum: enum, default: default, item_type: of, nested_params: nested ) end |
#required(name, type, description: nil, enum: nil, of: nil, &block) ⇒ void
This method returns an undefined value.
Defines a required parameter.
-- : (Symbol, Module, ?description: String?, ?enum: Array?, ?of: Module?) ?{ (Riffer::Params) [self: Riffer::Params] -> void } -> void
49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/riffer/params.rb', line 49 def required(name, type, description: nil, enum: nil, of: nil, &block) nested = build_nested(type, of, &block) @parameters << Riffer::Params::Param.new( name: name, type: type, required: true, description: description, enum: enum, item_type: of, nested_params: nested ) end |
#to_json_schema(strict: false) ⇒ Hash[Symbol, untyped]
Converts all parameters to JSON Schema format. When strict is true, every
property is listed in required and optional ones are made nullable
instead, satisfying providers that enforce strict structured output schemas.
: (?strict: bool) -> Hash[Symbol, untyped]
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/riffer/params.rb', line 128 def to_json_schema(strict: false) properties = {} #: Hash[String, untyped] required_params = [] #: Array[String] @parameters.each do |param| properties[param.name.to_s] = param.to_json_schema(strict: strict) required_params << param.name.to_s if strict || param.required end { type: "object", properties: properties, required: required_params, additionalProperties: false } end |
#validate(arguments) ⇒ Hash[Symbol, untyped]
Validates arguments against parameter definitions.
Raises Riffer::ValidationError if validation fails.
-- : (Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/riffer/params.rb', line 86 def validate(arguments) validated = {} #: Hash[Symbol, untyped] errors = [] #: Array[String] @parameters.each do |param| value = arguments[param.name] if value.nil? && param.required errors << "#{param.name} is required" next end if value.nil? validated[param.name] = param.default next end unless param.valid_type?(value) errors << "#{param.name} must be a #{param.type_name}" next end if param.enum && !param.enum.include?(value) errors << "#{param.name} must be one of: #{param.enum.join(", ")}" next end value = validate_nested(param, value, errors) validated[param.name] = value end raise Riffer::ValidationError, errors.join("; ") if errors.any? validated end |
#validate_nested(param, value, errors) ⇒ Object
-- : (Riffer::Params::Param, untyped, Array) -> untyped
177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/riffer/params.rb', line 177 def validate_nested(param, value, errors) if param.type == Hash && param.nested_params validate_nested_hash(param, value, errors) elsif param.type == Array && param.nested_params validate_nested_array_of_objects(param, value, errors) elsif param.type == Array && param.item_type validate_typed_array(param, value, errors) value else value end end |
#validate_nested_array_of_objects(param, value, errors) ⇒ Array[untyped]
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/riffer/params.rb', line 205 def validate_nested_array_of_objects(param, value, errors) nested = param.nested_params return value unless nested value.map.with_index do |item, i| unless item.is_a?(Hash) errors << "#{param.name}[#{i}] must be an object" next item end nested.validate(item) rescue Riffer::ValidationError => e e..split("; ").each do |msg| errors << "#{param.name}[#{i}].#{msg}" end item end end |
#validate_nested_hash(param, value, errors) ⇒ Hash[Symbol, untyped]
-- : (Riffer::Params::Param, Hash[Symbol, untyped], Array) -> Hash[Symbol, untyped]
192 193 194 195 196 197 198 199 200 201 |
# File 'lib/riffer/params.rb', line 192 def validate_nested_hash(param, value, errors) nested = param.nested_params return value unless nested nested.validate(value) rescue Riffer::ValidationError => e e..split("; ").each do |msg| errors << "#{param.name}.#{msg}" end value end |
#validate_typed_array(param, value, errors) ⇒ void
224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/riffer/params.rb', line 224 def validate_typed_array(param, value, errors) item_type = param.item_type return unless item_type type_name = Riffer::Params::Param::TYPE_MAPPINGS[item_type] value.each_with_index do |item, i| valid = if item_type == Riffer::Params::Boolean || item_type == TrueClass || item_type == FalseClass item == true || item == false else item.is_a?(item_type) end errors << "#{param.name}[#{i}] must be a #{type_name}" unless valid end end |