Class: Mistri::Schema
- Inherits:
-
Object
- Object
- Mistri::Schema
- Defined in:
- lib/mistri/schema.rb
Overview
Builds tool schemas and validates the portable JSON Schema subset Mistri owns.
Constant Summary collapse
- DIALECT =
"https://json-schema.org/draft/2020-12/schema"
Class Method Summary collapse
-
.build(&block) ⇒ Object
instance_exec binds self to the builder without passing an argument, so zero-arity lambdas and procs behave the same way.
-
.strict(schema, all_required: false) ⇒ Object
Prepares a schema for constrained decoding without turning a freeform object into one that accepts only {}.
-
.task_plan(schema, all_required: false) ⇒ Object
One task plan owns the strict prompt and validation schema.
-
.task_violations(value, schema, path = "$") ⇒ Object
Task mode validates only schemas whose complete assertion contract is implemented locally; provider constrained decoding is an optimization.
-
.tool_validator(schema, complete: false) ⇒ Object
A Tool keeps this plan for its lifetime.
-
.unsupported_assertions(schema) ⇒ Object
Paths to standard assertions that the zero-dependency validator does not implement.
-
.validate_definition!(schema) ⇒ Object
Definition checks cover the complete JSON document.
-
.validate_mcp!(schema, complete: false) ⇒ Object
MCP schemas get the same stance as host-authored tools: directly reachable portable constraints are enforced locally, while unsupported applicator subtrees stay server guidance.
-
.violations(value, schema, path = "$") ⇒ Object
Returns bounded, model-readable failures for the subset Mistri owns: type, enum, required, properties, additionalProperties, items, and prefixItems.
Instance Method Summary collapse
- #array(name, description = nil, items: { type: "string" }, required: false, **extra) ⇒ Object
-
#initialize ⇒ Schema
constructor
A new instance of Schema.
- #object(name, description = nil, required: false, &block) ⇒ Object
- #to_h ⇒ Object
Constructor Details
#initialize ⇒ Schema
Returns a new instance of Schema.
28 29 30 31 |
# File 'lib/mistri/schema.rb', line 28 def initialize @properties = {} @required = [] end |
Class Method Details
.build(&block) ⇒ Object
instance_exec binds self to the builder without passing an argument, so zero-arity lambdas and procs behave the same way.
20 21 22 23 24 25 26 |
# File 'lib/mistri/schema.rb', line 20 def self.build(&block) raise ConfigurationError, "schema needs a block" unless block builder = new builder.instance_exec(&block) builder.to_h end |
.strict(schema, all_required: false) ⇒ Object
Prepares a schema for constrained decoding without turning a freeform object into one that accepts only {}. Definition compilation happens first so recursive transformation never sees a cyclic or hostile graph.
123 124 125 126 |
# File 'lib/mistri/schema.rb', line 123 def strict(schema, all_required: false) source = Compiled.new(schema) strict_at(source.schema, all_required:, path: "$") end |
.task_plan(schema, all_required: false) ⇒ Object
One task plan owns the strict prompt and validation schema. Providers may derive a compatible native constraint, but local validation remains the guarantee when their structured-output subset is narrower.
114 115 116 117 118 |
# File 'lib/mistri/schema.rb', line 114 def task_plan(schema, all_required: false) source = compile_task_schema(schema) strict = strict_at(source.schema, all_required:, path: "$") TaskPlan.new(Compiled.new(strict)) end |
.task_violations(value, schema, path = "$") ⇒ Object
Task mode validates only schemas whose complete assertion contract is implemented locally; provider constrained decoding is an optimization.
107 108 109 |
# File 'lib/mistri/schema.rb', line 107 def task_violations(value, schema, path = "$") task_plan(schema).violations(value, path) end |
.tool_validator(schema, complete: false) ⇒ Object
A Tool keeps this plan for its lifetime. complete is explicit authority for a host validator to own schema interactions core cannot represent.
83 84 85 |
# File 'lib/mistri/schema.rb', line 83 def tool_validator(schema, complete: false) Compiled.new(schema, tool: true, complete: complete) end |
.unsupported_assertions(schema) ⇒ Object
Paths to standard assertions that the zero-dependency validator does not implement. An empty list means local validation owns the contract.
100 101 102 103 |
# File 'lib/mistri/schema.rb', line 100 def unsupported_assertions(schema) compiled = Compiled.new(schema) AssertionScanner.new.call(compiled.schema).map(&:first).freeze end |
.validate_definition!(schema) ⇒ Object
Definition checks cover the complete JSON document. Unsupported assertion keywords remain provider guidance in this general API.
69 70 71 72 |
# File 'lib/mistri/schema.rb', line 69 def validate_definition!(schema) Compiled.new(schema) schema end |
.validate_mcp!(schema, complete: false) ⇒ Object
MCP schemas get the same stance as host-authored tools: directly reachable portable constraints are enforced locally, while unsupported applicator subtrees stay server guidance. Complete validators own the whole local contract; external references are rejected in either mode.
91 92 93 94 95 96 |
# File 'lib/mistri/schema.rb', line 91 def validate_mcp!(schema, complete: false) compiled = Compiled.new(schema, tool: true, complete: complete) AssertionContract.new(complete:, context: "MCP input schema", allow_guidance: true).call(compiled.schema) compiled.schema end |
.violations(value, schema, path = "$") ⇒ Object
Returns bounded, model-readable failures for the subset Mistri owns: type, enum, required, properties, additionalProperties, items, and prefixItems. The input is first normalized to the JSON value providers see.
77 78 79 |
# File 'lib/mistri/schema.rb', line 77 def violations(value, schema, path = "$") Compiled.new(schema).violations(value, path) end |
Instance Method Details
#array(name, description = nil, items: { type: "string" }, required: false, **extra) ⇒ Object
44 45 46 47 48 49 50 |
# File 'lib/mistri/schema.rb', line 44 def array(name, description = nil, items: { type: "string" }, required: false, **extra) prop = { type: "array", items: items } prop[:description] = description if description @properties[name.to_s] = prop.merge(extra) @required << name.to_s if required nil end |
#object(name, description = nil, required: false, &block) ⇒ Object
52 53 54 55 56 57 58 |
# File 'lib/mistri/schema.rb', line 52 def object(name, description = nil, required: false, &block) prop = block ? self.class.build(&block) : self.class.new.to_h prop[:description] = description if description @properties[name.to_s] = prop @required << name.to_s if required nil end |
#to_h ⇒ Object
60 61 62 63 64 |
# File 'lib/mistri/schema.rb', line 60 def to_h schema = { type: "object", properties: @properties } schema[:required] = @required unless @required.empty? schema end |