Skip to content

Releases: crmne/schematist

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 11 Aug 10:49
a57ec4f

Schematist now covers the whole Draft 2020-12 vocabulary. 1.0 emitted Draft 2020-12 documents but couldn't express every schema the spec allows. This closes the five places where it fell short.

A schema does not have to be an object

A type with a name declares a property. Without a name it declares what the schema itself is.

class Tags < Schematist::Schema
  array of: :string, unique: true       # the whole schema is an array
end

class Id < Schematist::Schema
  one_of do                             # the whole schema is a choice
    string
    integer
  end
end

class Person < Schematist::Schema
  raw({ "$ref" => "https://example.com/person.json" })
end

It works inside define too, so a definition can be a reusable string, a shared enum, an array, or a union, not just an object:

define :status do
  string enum: %w[draft sent paid]
end

Objects also take min_properties, max_properties, unevaluated_properties and unevaluated_items at the root, alongside additional_properties. Closes #59 and #61.

Conditionals hold any schema

if, then and else each hold any schema in Draft 2020-12. A branch was stuck with a required list plus nine validation keys, so it couldn't ask for a nested object, an array, a reference, or any composition. A branch is backed by a schema class now, so the whole DSL works inside one:

given kind: "business" do
  requires :vat_id

  object :tax_details do
    string :vat_number
  end

  otherwise do
    validates :vat_id, type: :string
  end
end

given still matches on property values, and takes a schema outright when the condition is something else:

given({ required: %w[tax_id] }) { requires :summary }

requires and validates stay as shorthands. A dependency that only lists fields still emits dependentRequired; one that describes a schema upgrades to dependentSchemas. Closes #60.

Open ended tuples

A tuple is exactly its prefix unless you give it somewhere to put the rest. That covers both of the usual Draft 2020-12 array shapes:

tuple :event, of: :string do              # prefixItems, then a typed tail
  string
  integer
end

tuple :pair, unevaluated_items: false do  # closed after the prefix
  string
  string
end

unevaluated_items: is on the composition builders too, alongside unevaluated_properties:. Closes #62.

Wider keywords

enum and const belong to the validation vocabulary and apply to any type, so enum works on boolean and null now. format isn't type restricted either, so integer :id, format: "int64" works. Closes #63.

const on null stays out on purpose. {"type":"null"} and {"type":"null","const":null} accept and reject the same things, so it buys you nothing, and raw covers it if you want the exact bytes.

Fixed

  • Cycle detection only walked a definition's properties, so a $ref buried in a union was invisible. It walks the whole thing now, which matters more now that definitions can be unions.
  • An object with no block and no of: schema raised wrong number of arguments (given 0, expected 1..3). It says what's wrong now.

Also

ruby_llm-schema 1.0.0 is on RubyGems. It depends on Schematist and aliases RubyLLM::Schema, so the old constant keeps resolving while you migrate. It warns on load, and it's the last release of that name.

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 10 Aug 23:30
ac1a66e

RubyLLM::Schema is now Schematist. Schematist is a general purpose JSON Schema DSL that emits Draft 2020-12 schemas. Trapping that inside another gem's namespace was a disservice to anyone looking for a great JSON Schema DSL.

gem 'schematist'                         # was: gem 'ruby_llm-schema'

class Person < Schematist::Schema        # was: RubyLLM::Schema
end

Breaking

  • to_json_schema returns a Draft 2020-12 document with string keys. The old {name:, description:, schema:} wrapper was OpenAI's response_format shape, and building that belongs in whatever talks to the provider.
  • strict is gone. It's an OpenAI request flag, not a JSON Schema keyword.
  • Errors moved up a level: Schematist::ValidationError, not RubyLLM::Schema::ValidationError.
  • RubyLLM::Helpers is now Schematist::Helpers.

A final ruby_llm-schema 1.0.0 depends on this gem and aliases the old constants, so RubyLLM::Schema keeps resolving while you migrate.

New

Schematist now speaks most of Draft 2020-12:

  • Composition: all_of, one_of, none_of join any_of
  • Unevaluated: unevaluated_properties: and unevaluated_items:
  • Object keys: min_properties:, max_properties:, keys for propertyNames, keys_matching for patternProperties
  • Arrays: unique: for uniqueItems, tuple for prefixItems, contains with min: / max:
  • Annotations: title, description, default, examples, deprecated, read_only, write_only, as keywords or inside the block
  • Encoded content: content_encoding:, content_media_type:, content_schema
  • Core keywords: $id, $anchor, $comment, $dynamicAnchor, $dynamicRef, $vocabulary
  • Boolean and raw schemas: any_schema, no_schema, and raw for anything the DSL doesn't model
  • const on every primitive, and greater_than: / less_than: for the exclusive bounds

Runtime values. Any value can be a proc, resolved when the document is rendered, so one schema class gives you a different document per instance:

string :role, enum: -> { @account.roles.pluck(:name) }

No runtime dependencies.

Fixed

number, integer, boolean and null didn't accept a block, so integer(:a) { title "A" } dropped the annotation silently instead of raising.

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 21 May 10:32
1e2608c

Support for Dependencies and Conditionals

Adds given, dependent, and inline requires: DSL methods for expressing JSON Schema conditionals and dependencies.

requires: inline property dependencies

Maps to dependentRequired. The simplest form for "if this property is present, require those":

class PaymentSchema < RubyLLM::Schema
  number :credit_card, required: false, requires: %i[billing_address cvv]
  string :billing_address, required: false
  string :cvv, required: false
end

dependent property dependencies with validations

Use a block when you need validates, upgrades output to dependentSchemas:

dependent :credit_card do
  requires :billing_address
  validates :billing_address, type: :string, min_length: 1
end

given if/then/else

Condition values are auto-coerced: strings → const, arrays → enum, regexps → pattern, hashes → raw schema.

class ShippingSchema < RubyLLM::Schema
  boolean :domestic
  string :state, required: false
  string :country, required: false

  given domestic: true do
    requires :state

    otherwise do
      requires :country
    end
  end
end

All three propagate through nested schemas via of: and define/$defs.

Thanks to @marcoroth for his PR #31

Changelog

Full Changelog: v0.3.1...v0.4.0

v0.3.1

Choose a tag to compare

@github-actions github-actions released this 19 May 10:50
5956c00

Changelog

  • e27c009 Standardize project tooling and workflows
  • f8c0f6b Add Java platform to lockfile
  • 0b51172 Stop tracking Bundler lockfile
  • 2a42247 Document RubyLLM tool parameter schemas
  • 4013e15 Fix duplicate required properties
  • 32bdc82 Return nil from schema property declarations
  • 148bfd0 Add irb development dependency
  • 7a72a07 Add Flay and Codecov coverage checks
  • d210a9c Bump version to 0.3.1
  • 5956c00 Create GitHub release automatically

Full Changelog: v0.3.0...v0.3.1

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 08 Jan 07:40

What's Changed

  • Enable support for structured outputs with Anthropic by allowing omission of strict, by @vojto in #28
  • Update readme with simple example integration with RubyLLM

New Contributors

  • @vojto made their first contribution in #28

Full Changelog: v0.2.5...v0.3.0

v0.2.5

Choose a tag to compare

@github-actions github-actions released this 12 Nov 07:42
  • Add support for schema naming via DSL #23

Full Changelog: v0.2.4...v0.2.5

v0.2.4

Choose a tag to compare

@github-actions github-actions released this 11 Nov 13:42

What's Changed

Full Changelog: v0.2.3...v0.2.4

v0.2.3

Choose a tag to compare

@github-actions github-actions released this 11 Nov 10:16

What's Changed

New Contributors

Full Changelog: v0.2.1...v0.2.3

v0.2.1

Choose a tag to compare

@danielfriis danielfriis released this 26 Aug 08:43

What's Changed

🚀 New Features

🔧 Other improvements

Full Changelog: v0.1.9...v0.2.1