structify 0.1.0 → 0.3.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.
data/lib/structify.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "structify/version"
4
+ require_relative "structify/schema_serializer"
4
5
  require_relative "structify/model"
5
6
 
6
7
  # Structify is a DSL for defining extraction schemas for LLM-powered models.
7
8
  # It provides a simple way to integrate with Rails models for LLM extraction,
8
- # including versioning, assistant prompts, and more.
9
+ # allowing for schema versioning and evolution.
9
10
  #
10
11
  # @example
11
12
  # class Article < ApplicationRecord
@@ -15,8 +16,6 @@ require_relative "structify/model"
15
16
  # title "Article Extraction"
16
17
  # description "Extract article metadata"
17
18
  # version 1
18
- # assistant_prompt "Extract the following fields from the article"
19
- # llm_model "gpt-4"
20
19
  #
21
20
  # field :title, :string, required: true
22
21
  # field :summary, :text, description: "A brief summary of the article"
@@ -24,6 +23,93 @@ require_relative "structify/model"
24
23
  # end
25
24
  # end
26
25
  module Structify
26
+ # Configuration class for Structify
27
+ class Configuration
28
+ # @return [Symbol] The default container attribute for JSON fields
29
+ attr_accessor :default_container_attribute
30
+
31
+ def initialize
32
+ @default_container_attribute = :json_attributes
33
+ end
34
+ end
35
+
36
+ # @return [Structify::Configuration] The current configuration
37
+ def self.configuration
38
+ @configuration ||= Configuration.new
39
+ end
40
+
41
+ # Configure Structify
42
+ # @yield [config] The configuration block
43
+ # @yieldparam config [Structify::Configuration] The configuration object
44
+ # @return [Structify::Configuration] The updated configuration
45
+ def self.configure
46
+ yield(configuration) if block_given?
47
+ configuration
48
+ end
49
+ # Base error class for Structify
27
50
  class Error < StandardError; end
28
- # Your code goes here...
51
+
52
+ # Error raised when trying to access a field that doesn't exist in the record's version
53
+ class MissingFieldError < Error
54
+ attr_reader :field_name, :record_version, :schema_version
55
+
56
+ def initialize(field_name, record_version, schema_version)
57
+ @field_name = field_name
58
+ @record_version = record_version
59
+ @schema_version = schema_version
60
+
61
+ message = "Field '#{field_name}' does not exist in version #{record_version}. " \
62
+ "It was introduced in version #{schema_version}. " \
63
+ "To access this field, upgrade the record by setting new field values and saving."
64
+
65
+ super(message)
66
+ end
67
+ end
68
+
69
+ # Error raised when trying to access a field that has been removed in the current schema version
70
+ class RemovedFieldError < Error
71
+ attr_reader :field_name, :removed_in_version
72
+
73
+ def initialize(field_name, removed_in_version)
74
+ @field_name = field_name
75
+ @removed_in_version = removed_in_version
76
+
77
+ message = "Field '#{field_name}' has been removed in version #{removed_in_version}. " \
78
+ "This field is no longer available in the current schema."
79
+
80
+ super(message)
81
+ end
82
+ end
83
+
84
+ # Error raised when trying to access a field outside its specified version range
85
+ class VersionRangeError < Error
86
+ attr_reader :field_name, :record_version, :valid_versions
87
+
88
+ def initialize(field_name, record_version, valid_versions)
89
+ @field_name = field_name
90
+ @record_version = record_version
91
+ @valid_versions = valid_versions
92
+
93
+ message = "Field '#{field_name}' is not available in version #{record_version}. " \
94
+ "This field is only available in versions: #{format_versions(valid_versions)}."
95
+
96
+ super(message)
97
+ end
98
+
99
+ private
100
+
101
+ def format_versions(versions)
102
+ if versions.is_a?(Range)
103
+ if versions.end.nil?
104
+ "#{versions.begin} and above"
105
+ else
106
+ "#{versions.begin} to #{versions.end}#{versions.exclude_end? ? ' (exclusive)' : ''}"
107
+ end
108
+ elsif versions.is_a?(Array)
109
+ versions.join(", ")
110
+ else
111
+ "#{versions} and above" # Single integer means this version and onwards
112
+ end
113
+ end
114
+ end
29
115
  end
data/structify.gemspec CHANGED
@@ -19,13 +19,13 @@ Gem::Specification.new do |spec|
19
19
  # Specify which files should be added to the gem when it is released.
20
20
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
21
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
22
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) || f.end_with?('.gem') }
23
23
  end
24
24
  spec.bindir = "exe"
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ["lib"]
27
27
 
28
28
  # Runtime dependencies
29
- spec.add_dependency "activesupport", "~> 7.1"
29
+ spec.add_dependency "activesupport", "~> 8"
30
30
  spec.add_dependency "attr_json", "~> 2.1"
31
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: structify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kieran Klaassen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-02-03 00:00:00.000000000 Z
11
+ date: 2025-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '7.1'
19
+ version: '8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '7.1'
26
+ version: '8'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: attr_json
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -49,6 +49,8 @@ files:
49
49
  - ".gitignore"
50
50
  - ".rspec"
51
51
  - ".travis.yml"
52
+ - CHANGELOG.md
53
+ - CLAUDE.md
52
54
  - CODE_OF_CONDUCT.md
53
55
  - Gemfile
54
56
  - Gemfile.lock
@@ -59,6 +61,7 @@ files:
59
61
  - bin/setup
60
62
  - lib/structify.rb
61
63
  - lib/structify/model.rb
64
+ - lib/structify/schema_serializer.rb
62
65
  - lib/structify/version.rb
63
66
  - structify.gemspec
64
67
  homepage: https://github.com/kieranklaassen/structify