ruby_llm-schema 0.1.6 → 0.1.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6c0f93a31976be978ea63b955ff89a9d9fa3e2c927457396ecda8a104d5a8df
4
- data.tar.gz: fc2113a8e86d73ac532d6ab03d95ea234678196fbe400a8e2656a9da6f6930ba
3
+ metadata.gz: 4706281dcd180f4d6e2b385cc42b79d73629d8eb8a7b5723ddde3b2786a5022e
4
+ data.tar.gz: eb083d6fa029a0b107f7a728c86e9f8342a1b9d0c3d0a46d8d4d33adaacd756a
5
5
  SHA512:
6
- metadata.gz: e49c81df9deed1904351e88d1a887fa58ed321ee9a96d03ca1fc3bebb5f981bfb263634e3005286f1c774322ec12943ffc7cb3f69ac42b57839290e6e6407f6c
7
- data.tar.gz: 3bb762ef34a9cc9b36c9bf4ad8ee74d659dc3dbdf26169b3654e896fab2d33f8e82e9d5976d228b6766c139e631af1f0aea547e988138d95de5db4a3d889ab71
6
+ metadata.gz: bc52ea4b47664561909278ece104676ae5053572aa791fe6985deb1ecdf40421e49b3b02529ba2a02cbb1df068484d6d162ec0d4c8d525105111ced98451fcbf
7
+ data.tar.gz: df555cdab1fb1c786ee0425fb5a1c0dd61bd5ed6c35dfc53bb355cdad27b462c5dbd84cb5d8fb32db6fdbe2c364916f0c8d2ed32565bff87c8ca17b79915ee03
data/README.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  A Ruby DSL for creating JSON schemas with a clean, Rails-inspired API. Perfect for defining structured data schemas for LLM function calling or structured outputs.
4
4
 
5
+ ## Use Cases
6
+
7
+ Structured output is a powerful tool for LLMs to generate consistent and predictable responses.
8
+
9
+ Some ideal use cases:
10
+
11
+ - Extracting *metadata, topics, and summary* from articles or blog posts
12
+ - Organizing unstructured feedback or reviews with *sentiment and summary*
13
+ - Defining structured *actions* from user messages or emails
14
+ - Extracting *entities and relationships* from documents
15
+
5
16
  ### Simple Example
6
17
 
7
18
  ```ruby
@@ -122,29 +133,83 @@ end
122
133
  puts person_schema.to_json
123
134
  ```
124
135
 
125
- ## Field Types
136
+ ## Schema Property Types
137
+
138
+ A schema is a collection of properties, which can be of different types. Each type has its own set of properties you can set.
139
+
140
+ All property types can (along with the required `name` key) be set with a `description` and a `required` flag (default is `true`).
141
+
142
+ ```ruby
143
+ string :name, description: "Person's full name"
144
+ number :age, description: "Person's age", required: false
145
+ boolean :is_active, description: "Whether the person is active"
146
+ null :placeholder, description: "A placeholder property"
147
+ ```
148
+
149
+ ⚠️ Please consult the LLM provider documentation for any limitations or restrictions. For example, as of now, OpenAI requires all properties to be required. In that case, you can use the `any_of` method to make a property optional.
150
+
151
+ ```ruby
152
+ any_of :name, description: "Person's full name" do
153
+ string
154
+ null
155
+ end
156
+ ```
157
+
158
+ ### Strings
159
+
160
+ String types support the following properties:
161
+
162
+ - `enum`: an array of allowed values (e.g. `enum: ["on", "off"]`)
163
+ - `pattern`: a regex pattern (e.g. `pattern: "\\d+"`)
164
+ - `format`: a format string (e.g. `format: "email"`)
165
+ - `min_length`: the minimum length of the string (e.g. `min_length: 3`)
166
+ - `max_length`: the maximum length of the string (e.g. `max_length: 10`)
167
+
168
+ Please consult the LLM provider documentation for the available formats and patterns.
169
+
170
+ ```ruby
171
+ string :name, description: "Person's full name"
172
+ string :email, format: "email"
173
+ string :phone, pattern: "\\d+"
174
+ string :status, enum: ["on", "off"]
175
+ string :code, min_length: 3, max_length: 10
176
+ ```
177
+
178
+ ### Numbers
126
179
 
127
- ### Primitive Types
180
+ Number types support the following properties:
181
+
182
+ - `multiple_of`: a multiple of the number (e.g. `multiple_of: 0.01`)
183
+ - `minimum`: the minimum value of the number (e.g. `minimum: 0`)
184
+ - `maximum`: the maximum value of the number (e.g. `maximum: 100`)
128
185
 
129
186
  ```ruby
130
- string :name # Required string
131
- string :title, required: false # Optional string
132
- string :status, enum: ["on", "off"] # String with enum values
133
- string :email, format: "email" # String with format validation
134
- string :code, min_length: 3, max_length: 10 # String with length constraints
135
- string :pattern_field, pattern: "\\d+" # String with regex pattern
187
+ number :price, minimum: 0, maximum: 100
188
+ number :amount, multiple_of: 0.01
189
+ ```
136
190
 
137
- number :count # Required number
138
- number :price, minimum: 0, maximum: 100 # Number with range constraints
139
- number :amount, multiple_of: 0.01 # Number with precision constraints
191
+ ### Booleans
140
192
 
141
- integer :id # Required integer
142
- boolean :active # Required boolean
143
- null :placeholder # Null type
193
+ ```ruby
194
+ boolean :is_active
144
195
  ```
145
196
 
197
+ Boolean types doesn't support any additional properties.
198
+
199
+ ### Null
200
+
201
+ ```ruby
202
+ null :placeholder
203
+ ```
204
+
205
+ Null types doesn't support any additional properties.
206
+
146
207
  ### Arrays
147
208
 
209
+ An array is a list of items. You can set the type of the items in the array with the `of` option or by passing a block with the `object` method.
210
+
211
+ An array can have a `min_items` and `max_items` option to set the minimum and maximum number of items in the array.
212
+
148
213
  ```ruby
149
214
  array :tags, of: :string # Array of strings
150
215
  array :scores, of: :number # Array of numbers
@@ -160,6 +225,8 @@ end
160
225
 
161
226
  ### Objects
162
227
 
228
+ Objects types expect a block with the properties of the object.
229
+
163
230
  ```ruby
164
231
  object :user do
165
232
  string :name
@@ -174,6 +241,8 @@ end
174
241
 
175
242
  ### Union Types (anyOf)
176
243
 
244
+ Union types are a way to specify that a property can be one of several types.
245
+
177
246
  ```ruby
178
247
  any_of :value do
179
248
  string
@@ -189,6 +258,8 @@ end
189
258
 
190
259
  ### Schema Definitions and References
191
260
 
261
+ You can define sub-schemas and reference them in other schemas.
262
+
192
263
  ```ruby
193
264
  class MySchema < RubyLLM::Schema
194
265
  define :location do
data/Rakefile CHANGED
@@ -3,3 +3,10 @@
3
3
  require "bundler/gem_tasks"
4
4
  require "rspec/core/rake_task"
5
5
  require "standard/rake"
6
+
7
+ # Load custom tasks
8
+ Dir.glob("lib/tasks/**/*.rake").each { |r| load r }
9
+
10
+ RSpec::Core::RakeTask.new(:spec)
11
+
12
+ task default: %i[standard spec]
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLLM
4
+ class Schema
5
+ module DSL
6
+ # Primitive type methods
7
+ def string(name = nil, enum: nil, description: nil, required: true, min_length: nil, max_length: nil, pattern: nil, format: nil)
8
+ options = {
9
+ enum: enum,
10
+ description: description,
11
+ minLength: min_length,
12
+ maxLength: max_length,
13
+ pattern: pattern,
14
+ format: format
15
+ }.compact
16
+
17
+ add_property(name, build_property_schema(:string, **options), required: required)
18
+ end
19
+
20
+ def number(name = nil, description: nil, required: true, minimum: nil, maximum: nil, multiple_of: nil)
21
+ options = {
22
+ description: description,
23
+ minimum: minimum,
24
+ maximum: maximum,
25
+ multipleOf: multiple_of
26
+ }.compact
27
+
28
+ add_property(name, build_property_schema(:number, **options), required: required)
29
+ end
30
+
31
+ def integer(name = nil, description: nil, required: true)
32
+ add_property(name, build_property_schema(:integer, description: description), required: required)
33
+ end
34
+
35
+ def boolean(name = nil, description: nil, required: true)
36
+ add_property(name, build_property_schema(:boolean, description: description), required: required)
37
+ end
38
+
39
+ def null(name = nil, description: nil, required: true)
40
+ add_property(name, build_property_schema(:null, description: description), required: required)
41
+ end
42
+
43
+ # Complex type methods
44
+ def object(name = nil, description: nil, required: true, &block)
45
+ add_property(name, build_property_schema(:object, description: description, &block), required: required)
46
+ end
47
+
48
+ def array(name, of: nil, description: nil, required: true, min_items: nil, max_items: nil, &block)
49
+ items = determine_array_items(of, &block)
50
+
51
+ add_property(name, {
52
+ type: "array",
53
+ description: description,
54
+ items: items,
55
+ minItems: min_items,
56
+ maxItems: max_items
57
+ }.compact, required: required)
58
+ end
59
+
60
+ def any_of(name = nil, required: true, description: nil, &block)
61
+ schemas = collect_property_schemas_from_block(&block)
62
+
63
+ add_property(name, {
64
+ description: description,
65
+ anyOf: schemas
66
+ }.compact, required: required)
67
+ end
68
+
69
+ def optional(name, description: nil, &block)
70
+ any_of(name, description: description) do
71
+ instance_eval(&block)
72
+ null
73
+ end
74
+ end
75
+
76
+ # Schema definition and reference methods
77
+ def define(name, &)
78
+ sub_schema = Class.new(Schema)
79
+ sub_schema.class_eval(&)
80
+
81
+ definitions[name] = {
82
+ type: "object",
83
+ properties: sub_schema.properties,
84
+ required: sub_schema.required_properties
85
+ }
86
+ end
87
+
88
+ def reference(schema_name)
89
+ {"$ref" => "#/$defs/#{schema_name}"}
90
+ end
91
+
92
+ # Schema building methods
93
+ def build_property_schema(type, **options, &)
94
+ case type
95
+ when :string
96
+ {
97
+ type: "string",
98
+ enum: options[:enum],
99
+ description: options[:description],
100
+ minLength: options[:minLength],
101
+ maxLength: options[:maxLength],
102
+ pattern: options[:pattern],
103
+ format: options[:format]
104
+ }.compact
105
+ when :number
106
+ {
107
+ type: "number",
108
+ description: options[:description],
109
+ minimum: options[:minimum],
110
+ maximum: options[:maximum],
111
+ multipleOf: options[:multipleOf]
112
+ }.compact
113
+ when :integer
114
+ {
115
+ type: "integer",
116
+ description: options[:description],
117
+ minimum: options[:minimum],
118
+ maximum: options[:maximum],
119
+ multipleOf: options[:multipleOf]
120
+ }.compact
121
+ when :boolean
122
+ {type: "boolean", description: options[:description]}.compact
123
+ when :null
124
+ {type: "null", description: options[:description]}.compact
125
+ when :object
126
+ sub_schema = Class.new(Schema)
127
+ sub_schema.class_eval(&)
128
+
129
+ {
130
+ type: "object",
131
+ properties: sub_schema.properties,
132
+ required: sub_schema.required_properties,
133
+ additionalProperties: additional_properties,
134
+ description: options[:description]
135
+ }.compact
136
+ when :any_of
137
+ schemas = collect_property_schemas_from_block(&)
138
+ {
139
+ anyOf: schemas
140
+ }.compact
141
+ else
142
+ raise InvalidSchemaTypeError, type
143
+ end
144
+ end
145
+
146
+ private
147
+
148
+ def add_property(name, definition, required:)
149
+ properties[name.to_sym] = definition
150
+ required_properties << name.to_sym if required
151
+ end
152
+
153
+ def determine_array_items(of, &)
154
+ return collect_property_schemas_from_block(&).first if block_given?
155
+ return build_property_schema(of) if primitive_type?(of)
156
+ return reference(of) if of.is_a?(Symbol)
157
+
158
+ raise InvalidArrayTypeError, of
159
+ end
160
+
161
+ def collect_property_schemas_from_block(&block)
162
+ schemas = []
163
+ schema_builder = self # Capture the current context that has build_property_schema
164
+
165
+ context = Object.new
166
+ context.define_singleton_method(:string) { |name = nil, **options| schemas << schema_builder.build_property_schema(:string, **options) }
167
+ context.define_singleton_method(:number) { |name = nil, **options| schemas << schema_builder.build_property_schema(:number, **options) }
168
+ context.define_singleton_method(:integer) { |name = nil, **options| schemas << schema_builder.build_property_schema(:integer, **options) }
169
+ context.define_singleton_method(:boolean) { |name = nil, **options| schemas << schema_builder.build_property_schema(:boolean, **options) }
170
+ context.define_singleton_method(:null) { |name = nil, **options| schemas << schema_builder.build_property_schema(:null, **options) }
171
+ context.define_singleton_method(:object) { |name = nil, **options, &blk| schemas << schema_builder.build_property_schema(:object, **options, &blk) }
172
+ context.define_singleton_method(:any_of) { |name = nil, **options, &blk| schemas << schema_builder.build_property_schema(:any_of, **options, &blk) }
173
+
174
+ context.instance_eval(&block)
175
+ schemas
176
+ end
177
+
178
+ def primitive_type?(type)
179
+ type.is_a?(Symbol) && PRIMITIVE_TYPES.include?(type)
180
+ end
181
+ end
182
+ end
183
+ end
@@ -7,4 +7,4 @@ module RubyLLM
7
7
  schema_class.new(name, description: description)
8
8
  end
9
9
  end
10
- end
10
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLLM
4
+ class Schema
5
+ module JsonOutput
6
+ def to_json_schema
7
+ validate! # Validate schema before generating JSON
8
+
9
+ {
10
+ name: @name,
11
+ description: @description || self.class.description,
12
+ schema: {
13
+ :type => "object",
14
+ :properties => self.class.properties,
15
+ :required => self.class.required_properties,
16
+ :additionalProperties => self.class.additional_properties,
17
+ :strict => self.class.strict,
18
+ "$defs" => self.class.definitions
19
+ }
20
+ }
21
+ end
22
+
23
+ def to_json(*_args)
24
+ validate! # Validate schema before generating JSON string
25
+ JSON.pretty_generate(to_json_schema)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -32,7 +32,7 @@ module RubyLLM
32
32
 
33
33
  # Initialize all nodes as WHITE (no mark)
34
34
  marks = Hash.new { WHITE }
35
-
35
+
36
36
  # Visit each unmarked node
37
37
  definitions.each_key do |node|
38
38
  visit(node, definitions, marks) if marks[node] == WHITE
@@ -43,7 +43,7 @@ module RubyLLM
43
43
  def visit(node, definitions, marks)
44
44
  # If node has a permanent mark, return
45
45
  return if marks[node] == BLACK
46
-
46
+
47
47
  # If node has a temporary mark, we found a cycle
48
48
  if marks[node] == GRAY
49
49
  raise ValidationError, "Circular reference detected involving '#{node}'"
@@ -51,7 +51,7 @@ module RubyLLM
51
51
 
52
52
  # Mark node with temporary mark
53
53
  marks[node] = GRAY
54
-
54
+
55
55
  # Visit all adjacent nodes (dependencies)
56
56
  definition = definitions[node]
57
57
  if definition && definition[:properties]
@@ -62,14 +62,14 @@ module RubyLLM
62
62
  end
63
63
  end
64
64
  end
65
-
65
+
66
66
  # Mark node with permanent mark
67
67
  marks[node] = BLACK
68
68
  end
69
69
 
70
70
  def extract_references(property)
71
71
  references = []
72
-
72
+
73
73
  case property
74
74
  when Hash
75
75
  if property["$ref"]
@@ -92,4 +92,4 @@ module RubyLLM
92
92
  end
93
93
  end
94
94
  end
95
- end
95
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RubyLlm
4
4
  class Schema
5
- VERSION = "0.1.6"
5
+ VERSION = "0.1.7"
6
6
  end
7
7
  end
@@ -1,15 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "schema/version"
4
- require_relative "schema/property_schema_collector"
5
4
  require_relative "schema/errors"
6
5
  require_relative "schema/helpers"
7
6
  require_relative "schema/validator"
7
+ require_relative "schema/dsl"
8
+ require_relative "schema/json_output"
8
9
  require "json"
9
- require "set"
10
10
 
11
11
  module RubyLLM
12
12
  class Schema
13
+ extend DSL
14
+ include JsonOutput
15
+
13
16
  PRIMITIVE_TYPES = %i[string number integer boolean null].freeze
14
17
 
15
18
  class << self
@@ -19,6 +22,18 @@ module RubyLLM
19
22
  schema_class
20
23
  end
21
24
 
25
+ def properties
26
+ @properties ||= {}
27
+ end
28
+
29
+ def required_properties
30
+ @required_properties ||= []
31
+ end
32
+
33
+ def definitions
34
+ @definitions ||= {}
35
+ end
36
+
22
37
  def description(description = nil)
23
38
  @description = description if description
24
39
  @description
@@ -36,149 +51,6 @@ module RubyLLM
36
51
  @strict = value
37
52
  end
38
53
 
39
- def string(name = nil, enum: nil, description: nil, required: true, min_length: nil, max_length: nil, pattern: nil, format: nil)
40
- options = {
41
- enum: enum,
42
- description: description,
43
- minLength: min_length,
44
- maxLength: max_length,
45
- pattern: pattern,
46
- format: format
47
- }.compact
48
-
49
- add_property(name, build_property_schema(:string, **options), required: required)
50
- end
51
-
52
- def number(name = nil, description: nil, required: true, minimum: nil, maximum: nil, multiple_of: nil)
53
- options = {
54
- description: description,
55
- minimum: minimum,
56
- maximum: maximum,
57
- multipleOf: multiple_of
58
- }.compact
59
-
60
- add_property(name, build_property_schema(:number, **options), required: required)
61
- end
62
-
63
- def integer(name = nil, description: nil, required: true)
64
- add_property(name, build_property_schema(:integer, description: description), required: required)
65
- end
66
-
67
- def boolean(name = nil, description: nil, required: true)
68
- add_property(name, build_property_schema(:boolean, description: description), required: required)
69
- end
70
-
71
- def null(name = nil, description: nil, required: true)
72
- add_property(name, build_property_schema(:null, description: description), required: required)
73
- end
74
-
75
- def object(name = nil, description: nil, required: true, &block)
76
- add_property(name, build_property_schema(:object, description: description, &block), required: required)
77
- end
78
-
79
- def array(name, of: nil, description: nil, required: true, min_items: nil, max_items: nil, &block)
80
- items = determine_array_items(of, &block)
81
-
82
- add_property(name, {
83
- type: "array",
84
- description: description,
85
- items: items,
86
- minItems: min_items,
87
- maxItems: max_items
88
- }.compact, required: required)
89
- end
90
-
91
- def any_of(name, required: true, description: nil, &block)
92
- schemas = collect_property_schemas_from_block(&block)
93
-
94
- add_property(name, {
95
- description: description,
96
- anyOf: schemas
97
- }.compact, required: required)
98
- end
99
-
100
- def optional(name, description: nil, &block)
101
- any_of(name, description: description) do
102
- instance_eval(&block)
103
- null
104
- end
105
- end
106
-
107
- def define(name, &)
108
- sub_schema = Class.new(Schema)
109
- sub_schema.class_eval(&)
110
-
111
- definitions[name] = {
112
- type: "object",
113
- properties: sub_schema.properties,
114
- required: sub_schema.required_properties
115
- }
116
- end
117
-
118
- def reference(schema_name)
119
- {"$ref" => "#/$defs/#{schema_name}"}
120
- end
121
-
122
- def properties
123
- @properties ||= {}
124
- end
125
-
126
- def required_properties
127
- @required_properties ||= []
128
- end
129
-
130
- def definitions
131
- @definitions ||= {}
132
- end
133
-
134
- def build_property_schema(type, **options, &)
135
- case type
136
- when :string
137
- {
138
- type: "string",
139
- enum: options[:enum],
140
- description: options[:description],
141
- minLength: options[:minLength],
142
- maxLength: options[:maxLength],
143
- pattern: options[:pattern],
144
- format: options[:format]
145
- }.compact
146
- when :number
147
- {
148
- type: "number",
149
- description: options[:description],
150
- minimum: options[:minimum],
151
- maximum: options[:maximum],
152
- multipleOf: options[:multipleOf]
153
- }.compact
154
- when :integer
155
- {
156
- type: "integer",
157
- description: options[:description],
158
- minimum: options[:minimum],
159
- maximum: options[:maximum],
160
- multipleOf: options[:multipleOf]
161
- }.compact
162
- when :boolean
163
- {type: "boolean", description: options[:description]}.compact
164
- when :null
165
- {type: "null", description: options[:description]}.compact
166
- when :object
167
- sub_schema = Class.new(Schema)
168
- sub_schema.class_eval(&)
169
-
170
- {
171
- type: "object",
172
- properties: sub_schema.properties,
173
- required: sub_schema.required_properties,
174
- additionalProperties: additional_properties,
175
- description: options[:description]
176
- }.compact
177
- else
178
- raise InvalidSchemaTypeError, type
179
- end
180
- end
181
-
182
54
  def validate!
183
55
  validator = Validator.new(self)
184
56
  validator.validate!
@@ -188,31 +60,6 @@ module RubyLLM
188
60
  validator = Validator.new(self)
189
61
  validator.valid?
190
62
  end
191
-
192
- private
193
-
194
- def add_property(name, definition, required:)
195
- properties[name.to_sym] = definition
196
- required_properties << name.to_sym if required
197
- end
198
-
199
- def determine_array_items(of, &)
200
- return collect_property_schemas_from_block(&).first if block_given?
201
- return build_property_schema(of) if primitive_type?(of)
202
- return reference(of) if of.is_a?(Symbol)
203
-
204
- raise InvalidArrayTypeError, of
205
- end
206
-
207
- def collect_property_schemas_from_block(&)
208
- collector = PropertySchemaCollector.new
209
- collector.collect(&)
210
- collector.schemas
211
- end
212
-
213
- def primitive_type?(type)
214
- type.is_a?(Symbol) && PRIMITIVE_TYPES.include?(type)
215
- end
216
63
  end
217
64
 
218
65
  def initialize(name = nil, description: nil)
@@ -220,28 +67,6 @@ module RubyLLM
220
67
  @description = description
221
68
  end
222
69
 
223
- def to_json_schema
224
- validate! # Validate schema before generating JSON
225
-
226
- {
227
- name: @name,
228
- description: @description || self.class.description,
229
- schema: {
230
- :type => "object",
231
- :properties => self.class.properties,
232
- :required => self.class.required_properties,
233
- :additionalProperties => self.class.additional_properties,
234
- :strict => self.class.strict,
235
- "$defs" => self.class.definitions
236
- }
237
- }
238
- end
239
-
240
- def to_json(*_args)
241
- validate! # Validate schema before generating JSON string
242
- JSON.pretty_generate(to_json_schema)
243
- end
244
-
245
70
  def validate!
246
71
  self.class.validate!
247
72
  end
@@ -252,7 +77,7 @@ module RubyLLM
252
77
 
253
78
  def method_missing(method_name, ...)
254
79
  if respond_to_missing?(method_name)
255
- send(method_name, ...)
80
+ self.class.send(method_name, ...)
256
81
  else
257
82
  super
258
83
  end
@@ -1,23 +1,22 @@
1
1
  namespace :release do
2
2
  desc "Release a new version of the gem"
3
- task :version do
3
+ task :version, [:message] do |t, args|
4
4
  # Load the current version from version.rb
5
- require_relative '../../lib/ruby_llm/schema/version'
5
+ require_relative "../../lib/ruby_llm/schema/version"
6
6
  version = RubyLlm::Schema::VERSION
7
-
7
+
8
8
  puts "Releasing version #{version}..."
9
-
10
- # Prompt for release message
11
- print "Enter release message (optional): "
12
- release_message = STDIN.gets.chomp
13
-
14
- # Create git tag with message
15
- if release_message.empty?
16
- system "git tag v#{version}"
9
+
10
+ # Create git tag with optional message
11
+ # rake release:version["Fix critical bug in schema validation"]
12
+ if args[:message]
13
+ system "git tag -a v#{version} -m \"#{args[:message]}\""
14
+ puts "Created annotated tag v#{version} with message: #{args[:message]}"
17
15
  else
18
- system "git tag -a v#{version} -m \"#{release_message}\""
16
+ system "git tag v#{version}"
17
+ puts "Created lightweight tag v#{version}"
19
18
  end
20
-
19
+
21
20
  system "git push origin main"
22
21
  system "git push origin v#{version}"
23
22
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_llm-schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Friis
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-08-08 00:00:00.000000000 Z
10
+ date: 2025-08-22 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rspec
@@ -48,9 +48,10 @@ files:
48
48
  - README.md
49
49
  - Rakefile
50
50
  - lib/ruby_llm/schema.rb
51
+ - lib/ruby_llm/schema/dsl.rb
51
52
  - lib/ruby_llm/schema/errors.rb
52
53
  - lib/ruby_llm/schema/helpers.rb
53
- - lib/ruby_llm/schema/property_schema_collector.rb
54
+ - lib/ruby_llm/schema/json_output.rb
54
55
  - lib/ruby_llm/schema/validator.rb
55
56
  - lib/ruby_llm/schema/version.rb
56
57
  - lib/tasks/release.rake
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyLLM
4
- class Schema
5
- class PropertySchemaCollector
6
- attr_reader :schemas
7
-
8
- def initialize
9
- @schemas = []
10
- end
11
-
12
- def collect(&)
13
- instance_eval(&)
14
- end
15
-
16
- def string(**options)
17
- @schemas << Schema.build_property_schema(:string, **options)
18
- end
19
-
20
- def number(**options)
21
- @schemas << Schema.build_property_schema(:number, **options)
22
- end
23
-
24
- def integer(**options)
25
- @schemas << Schema.build_property_schema(:integer, **options)
26
- end
27
-
28
- def boolean(**options)
29
- @schemas << Schema.build_property_schema(:boolean, **options)
30
- end
31
-
32
- def null(**options)
33
- @schemas << Schema.build_property_schema(:null, **options)
34
- end
35
-
36
- def object(...)
37
- @schemas << Schema.build_property_schema(:object, ...)
38
- end
39
- end
40
- end
41
- end