ruby_llm-schema 0.4.0 → 1.0.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.
- checksums.yaml +4 -4
- data/README.md +17 -517
- data/lib/ruby_llm/schema.rb +23 -91
- metadata +30 -24
- data/LICENSE +0 -21
- data/lib/ruby_llm/schema/dsl/complex_types.rb +0 -32
- data/lib/ruby_llm/schema/dsl/conditionals.rb +0 -169
- data/lib/ruby_llm/schema/dsl/primitive_types.rb +0 -29
- data/lib/ruby_llm/schema/dsl/schema_builders.rb +0 -194
- data/lib/ruby_llm/schema/dsl/utilities.rb +0 -63
- data/lib/ruby_llm/schema/dsl.rb +0 -19
- data/lib/ruby_llm/schema/errors.rb +0 -30
- data/lib/ruby_llm/schema/helpers.rb +0 -10
- data/lib/ruby_llm/schema/json_output.rb +0 -36
- data/lib/ruby_llm/schema/validator.rb +0 -93
- data/lib/ruby_llm/schema/version.rb +0 -7
- data/lib/tasks/release.rake +0 -8
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RubyLLM
|
|
4
|
-
class Schema
|
|
5
|
-
class Validator
|
|
6
|
-
# Node states for DFS-based topological sort
|
|
7
|
-
WHITE = :white # No mark (unvisited)
|
|
8
|
-
GRAY = :gray # Temporary mark (currently being processed)
|
|
9
|
-
BLACK = :black # Permanent mark (completely processed)
|
|
10
|
-
|
|
11
|
-
def initialize(schema_class)
|
|
12
|
-
@schema_class = schema_class
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def validate!
|
|
16
|
-
validate_circular_references!
|
|
17
|
-
# Future validations can be added here
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def valid?
|
|
21
|
-
validate!
|
|
22
|
-
true
|
|
23
|
-
rescue ValidationError
|
|
24
|
-
false
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
private
|
|
28
|
-
|
|
29
|
-
def validate_circular_references!
|
|
30
|
-
definitions = @schema_class.definitions
|
|
31
|
-
return if definitions.empty?
|
|
32
|
-
|
|
33
|
-
# Initialize all nodes as WHITE (no mark)
|
|
34
|
-
marks = Hash.new { WHITE }
|
|
35
|
-
|
|
36
|
-
# Visit each unmarked node
|
|
37
|
-
definitions.each_key do |node|
|
|
38
|
-
visit(node, definitions, marks) if marks[node] == WHITE
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# DFS visit function
|
|
43
|
-
def visit(node, definitions, marks)
|
|
44
|
-
# If node has a permanent mark, return
|
|
45
|
-
return if marks[node] == BLACK
|
|
46
|
-
|
|
47
|
-
# If node has a temporary mark, we found a cycle
|
|
48
|
-
raise ValidationError, "Circular reference detected involving '#{node}'" if marks[node] == GRAY
|
|
49
|
-
|
|
50
|
-
# Mark node with temporary mark
|
|
51
|
-
marks[node] = GRAY
|
|
52
|
-
|
|
53
|
-
# Visit all adjacent nodes (dependencies)
|
|
54
|
-
definition = definitions[node]
|
|
55
|
-
if definition && definition[:properties]
|
|
56
|
-
definition[:properties].each_value do |property|
|
|
57
|
-
references = extract_references(property)
|
|
58
|
-
references.each do |adjacent_node|
|
|
59
|
-
visit(adjacent_node, definitions, marks)
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# Mark node with permanent mark
|
|
65
|
-
marks[node] = BLACK
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def extract_references(property)
|
|
69
|
-
references = []
|
|
70
|
-
|
|
71
|
-
case property
|
|
72
|
-
when Hash
|
|
73
|
-
if property["$ref"]
|
|
74
|
-
# Extract definition name from reference like "#/$defs/user"
|
|
75
|
-
ref_name = property["$ref"].split("/").last&.to_sym
|
|
76
|
-
references << ref_name if ref_name
|
|
77
|
-
else
|
|
78
|
-
# Recursively check nested properties
|
|
79
|
-
property.each_value do |value|
|
|
80
|
-
references.concat(extract_references(value))
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
when Array
|
|
84
|
-
property.each do |item|
|
|
85
|
-
references.concat(extract_references(item))
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
references
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|