Class: AgUi::Protocol::JsonSchema::Definition
- Inherits:
-
Object
- Object
- AgUi::Protocol::JsonSchema::Definition
- Defined in:
- lib/ag_ui/protocol/json_schema/definition.rb
Overview
Base class for schema-validated AG-UI protocol objects. Ported from a2a's Protocol::JsonSchema::Definition.
Each AG-UI definition (RunAgentInput, TextMessageContentEvent, …) gets a dynamically-generated subclass of Definition with:
- A JSONSchemer sub-schema attached (.schema)
- Reader methods for each property (snake_case)
- Validation via .valid? / .valid!
NOTE: #to_h deep-compacts nil values (matching pydantic's exclude_none on the wire). Inbound payloads that carry explicit nulls (e.g. RunAgentInput.state) should be validated as raw hashes via JsonSchema.schemer, not round-tripped through here.
Class Method Summary collapse
-
.camel_to_snake_map ⇒ Object
Reverse of snake_to_camel_map.
- .definition_name ⇒ Object
- .property_refs ⇒ Object
-
.schema ⇒ Object
--- class methods overridden by the factory -----------------------.
- .schema_properties ⇒ Object
- .snake_to_camel_map ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#deconstruct_keys(keys) ⇒ Object
Supports Ruby hash pattern matching with snake_case (or camelCase) keys.
-
#initialize(hash = {}) ⇒ Definition
constructor
A new instance of Definition.
- #inspect ⇒ Object
-
#to_h ⇒ Object
Returns the data as a plain Hash with camelCase string keys, matching the JSON wire format.
- #valid! ⇒ Object
-
#valid? ⇒ Boolean
--- validation ----------------------------------------------------.
Constructor Details
#initialize(hash = {}) ⇒ Definition
Returns a new instance of Definition.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 23 def initialize(hash = {}) props = self.class.schema_properties snake = self.class.snake_to_camel_map refs = self.class.property_refs @data = {} hash.each do |key, value| k = key.to_s # Resolve snake_case input to camelCase storage key camel = snake[k] || k if props.include?(camel) @data[camel] = if value.is_a?(Definition) value.to_h elsif (ref_info = refs[camel]) wrap_ref(value, ref_info) else value end end end end |
Class Method Details
.camel_to_snake_map ⇒ Object
Reverse of snake_to_camel_map. Built first-entry-wins: the factory inserts the snake_case key before the camelCase identity key, so camelCase storage keys map back to their snake_case reader names.
73 74 75 76 77 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 73 def self.camel_to_snake_map @camel_to_snake_map ||= snake_to_camel_map.each_with_object({}) do |(key, camel), map| map[camel] ||= key end end |
.definition_name ⇒ Object
53 54 55 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 53 def self.definition_name raise "AgUi::Protocol::JsonSchema::Definition should NOT be instantiated directly" end |
.property_refs ⇒ Object
65 66 67 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 65 def self.property_refs raise "AgUi::Protocol::JsonSchema::Definition should NOT be instantiated directly" end |
.schema ⇒ Object
--- class methods overridden by the factory -----------------------
49 50 51 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 49 def self.schema raise "AgUi::Protocol::JsonSchema::Definition should NOT be instantiated directly" end |
.schema_properties ⇒ Object
57 58 59 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 57 def self.schema_properties raise "AgUi::Protocol::JsonSchema::Definition should NOT be instantiated directly" end |
.snake_to_camel_map ⇒ Object
61 62 63 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 61 def self.snake_to_camel_map raise "AgUi::Protocol::JsonSchema::Definition should NOT be instantiated directly" end |
Instance Method Details
#==(other) ⇒ Object
108 109 110 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 108 def ==(other) other.is_a?(Definition) && to_h == other.to_h end |
#deconstruct_keys(keys) ⇒ Object
Supports Ruby hash pattern matching with snake_case (or camelCase) keys. Absent properties are omitted so patterns requiring them fail to match; nested Definitions destructure recursively.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 117 def deconstruct_keys(keys) snake = self.class.snake_to_camel_map if keys keys.each_with_object({}) do |key, result| camel = snake[key.to_s] || key.to_s if @data.key?(camel) result[key] = @data[camel] end end else camel_to_snake = self.class.camel_to_snake_map @data.each_with_object({}) do |(camel, value), result| result[(camel_to_snake[camel] || camel).to_sym] = value end end end |
#inspect ⇒ Object
135 136 137 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 135 def inspect "#<#{self.class.definition_name} #{to_h.inspect}>" end |
#to_h ⇒ Object
Returns the data as a plain Hash with camelCase string keys, matching the JSON wire format. Nested Definition instances are auto-coerced via deep_compact.
104 105 106 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 104 def to_h deep_compact(@data) end |
#valid! ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 85 def valid! errors = self.class.schema.validate(to_h).to_a if errors.empty? true else raise ValidationError.new( errors, definition_name: self.class.definition_name, data: to_h, ) end end |
#valid? ⇒ Boolean
--- validation ----------------------------------------------------
81 82 83 |
# File 'lib/ag_ui/protocol/json_schema/definition.rb', line 81 def valid? self.class.schema.valid?(to_h) end |