Module: Ask::SessionProtocol::Schema

Defined in:
lib/ask/session_protocol/schema.rb

Overview

Generates a JSON Schema (draft 2020-12) document from the contract registries (Events::TYPES, Interactions::PAYLOADS, Methods::METHODS).

The output is a static artifact (docs/ask-session-protocol.schema.json, regenerated by rake schema) so non-Ruby clients — bots, IDEs — can validate against the contract without loading this gem.

Class Method Summary collapse

Class Method Details

.buildHash

Returns the JSON Schema document.

Returns:

  • (Hash)

    the JSON Schema document



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/ask/session_protocol/schema.rb', line 13

def self.build
  {
    "$schema" => "https://json-schema.org/draft/2020-12/schema",
    "title" => "Ask Session Protocol",
    "description" => "Canonical wire contract for ask agent sessions: " \
                     "event vocabulary, interactions, and the RPC method surface. " \
                     "See the ask-session-protocol gem for the authoritative registry.",
    "protocolVersion" => Ask::SessionProtocol::PROTOCOL_VERSION,
    "$defs" => {
      "event" => build_event_schema,
      "interaction" => build_interaction_schema,
      "method" => build_method_schema
    }
  }
end

.build_event_schemaHash

Event envelope schema: one schema per canonical event type.

Returns:

  • (Hash)

    "$defs/event"



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/ask/session_protocol/schema.rb', line 50

def self.build_event_schema
  Events::TYPES.each_with_object({}) do |(type, spec), out|
    out[type] = {
      "type" => "object",
      "description" => spec[:description],
      "properties" => {
        "type" => { "const" => type },
        "seq" => { "type" => "integer", "minimum" => 1 },
        "payload" => build_payload_schema(spec[:payload])
      },
      "required" => %w[type seq payload],
      "additionalProperties" => false
    }
    out[type]["x-interaction"] = true if spec[:interaction]
  end
end

.build_interaction_schemaHash

Interaction schema per kind.

Returns:

  • (Hash)

    "$defs/interaction"



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ask/session_protocol/schema.rb', line 70

def self.build_interaction_schema
  Interactions::PAYLOADS.each_with_object({}) do |(kind, payload), out|
    out[kind] = {
      "type" => "object",
      "properties" => {
        "id" => { "type" => "string" },
        "kind" => { "const" => kind },
        "status" => { "type" => "string", "enum" => Interactions::STATUSES },
        "payload" => build_payload_schema(payload)
      },
      "required" => %w[id kind status payload],
      "additionalProperties" => false
    }
  end
end

.build_method_schemaHash

Method schema per client → host method: params and result.

Returns:

  • (Hash)

    "$defs/method"



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/ask/session_protocol/schema.rb', line 89

def self.build_method_schema
  Methods::METHODS.each_with_object({}) do |(name, spec), out|
    out[name] = {
      "type" => "object",
      "description" => spec[:description],
      "properties" => {
        "method" => { "const" => name },
        "params" => build_payload_schema(spec[:params])
      },
      "required" => %w[method params],
      "additionalProperties" => false
    }
  end
end

.field_schema(field_spec) ⇒ Hash

Convert a registry field spec to a JSON Schema fragment.

Parameters:

  • field_spec (Hash)

    { type:, required:, enum:, description: }

Returns:

  • (Hash)


33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/ask/session_protocol/schema.rb', line 33

def self.field_schema(field_spec)
  schema = {}
  schema["description"] = field_spec[:description] if field_spec[:description]
  schema["enum"] = field_spec[:enum] if field_spec[:enum]

  case field_spec[:type]
  when :any then schema
  when :number then schema.merge("type" => "number")
  when :object then schema.merge("type" => "object")
  when :array then schema.merge("type" => "array")
  else schema.merge("type" => field_spec[:type].to_s)
  end
end