hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

envelope.mojo (7552B)


      1 from std.collections import Dict, Optional
      2 
      3 from json import Value, loads
      4 from json.deserialize import Deserializable, get_string
      5 
      6 from hyf_core.metadata import hyf_protocol_version
      7 from hyf_core.operation_context import (
      8     OperationContext,
      9     context_selects_v2_any,
     10     is_corrected_operation,
     11     operation_context_selects_v2,
     12     parse_operation_context,
     13 )
     14 from hyf_core.request_context import (
     15     RequestContext,
     16     default_request_context,
     17     parse_request_context,
     18 )
     19 from hyf_stdio.errors import WireError
     20 
     21 
     22 def _require_object(value: Value, context: String) raises:
     23     if not value.is_object():
     24         raise Error(context + " must be a JSON object")
     25 
     26 
     27 def _require_non_empty(value: String, field_name: String) raises:
     28     if value == "":
     29         raise Error(
     30             "request envelope field '" + field_name + "' must not be empty"
     31         )
     32 
     33 
     34 def _require_request_keys(value: Value) raises:
     35     for key in value.object_keys():
     36         if (
     37             key != "version"
     38             and key != "request_id"
     39             and key != "trace_id"
     40             and key != "capability"
     41             and key != "context"
     42             and key != "input"
     43         ):
     44             raise Error(
     45                 "request envelope contains unexpected field '" + key + "'"
     46             )
     47 
     48 
     49 def _has_key(value: Value, key: String) -> Bool:
     50     for candidate in value.object_keys():
     51         if candidate == key:
     52             return True
     53     return False
     54 
     55 
     56 def _first_duplicate_root_key(value: Value) raises -> Optional[String]:
     57     # ADR-0026 D46 CR04: decoded-key identity across every raw object entry, so
     58     # escaped equivalents (`\u0063ontext`) and repeated values are both found
     59     # rather than only the first `value[key]` lookup.
     60     var seen = Dict[String, Bool]()
     61     for item in value.object_items():
     62         var key = String(item[0])
     63         if key in seen:
     64             return Optional[String](key)
     65         seen[key] = True
     66     return None
     67 
     68 
     69 def envelope_targets_corrected_v2(json: Value) raises -> Bool:
     70     """True when an envelope contains a corrected-op capability value or a
     71     duplicate-aware v2 context selector.
     72 
     73     Scans every raw root entry, so a duplicated `capability` or `context` key
     74     cannot hide a corrected-operation value or a v2 selector behind an earlier
     75     legacy entry.
     76     """
     77     for item in json.object_items():
     78         if item[0] == "capability" and item[1].is_string():
     79             if is_corrected_operation(String(item[1].string_value())):
     80                 return True
     81         elif item[0] == "context":
     82             if context_selects_v2_any(item[1]):
     83                 return True
     84     return False
     85 
     86 
     87 def _require_protocol_version(json: Value) raises -> Int:
     88     if not _has_key(json, "version"):
     89         raise Error("request envelope field 'version' is required")
     90 
     91     var version = json["version"]
     92     if not version.is_int():
     93         raise Error("request envelope field 'version' must be an integer")
     94 
     95     var version_value = Int(version.int_value())
     96     if version_value != hyf_protocol_version():
     97         raise Error(
     98             "request envelope version "
     99             + String(version_value)
    100             + " is unsupported; expected "
    101             + String(hyf_protocol_version())
    102         )
    103     return version_value
    104 
    105 
    106 def _parse_optional_trace_id(json: Value) raises -> Optional[String]:
    107     if not _has_key(json, "trace_id"):
    108         return None
    109 
    110     var trace_id = get_string(json, "trace_id")
    111     _require_non_empty(trace_id, "trace_id")
    112     return String(trace_id)
    113 
    114 
    115 def _require_input_value(json: Value) raises -> Value:
    116     if not _has_key(json, "input"):
    117         raise Error("request envelope field 'input' is required")
    118 
    119     var input = json["input"]
    120     if not input.is_object():
    121         raise Error("request envelope field 'input' must be a JSON object")
    122     return input.clone()
    123 
    124 
    125 @fieldwise_init
    126 struct WireRequest(Copyable, Deserializable, Movable):
    127     var version: Int
    128     var request_id: String
    129     var trace_id: Optional[String]
    130     var capability: String
    131     var context: RequestContext
    132     var input: Value
    133     # ADR-0025 D45 CB01: present only for a recognized hyf_ops_v2 request to one
    134     # of the three corrected operations. Legacy requests leave this None and
    135     # keep the unchanged legacy context.
    136     var operation_context: Optional[OperationContext]
    137 
    138     @staticmethod
    139     def from_json(json: Value) raises -> Self:
    140         _require_object(json, "request envelope")
    141         # ADR-0026 D46 CR04: reject ambiguous duplicate top-level keys before
    142         # first-wins lookup/selector dispatch for any envelope that targets a
    143         # corrected-operation capability or a v2 context selector. Unrelated
    144         # legacy capabilities keep their existing admission behavior.
    145         if envelope_targets_corrected_v2(json):
    146             var duplicate = _first_duplicate_root_key(json)
    147             if duplicate:
    148                 raise Error(
    149                     "request envelope contains duplicate top-level field '"
    150                     + duplicate.value()
    151                     + "'"
    152                 )
    153         _require_request_keys(json)
    154         var version = _require_protocol_version(json)
    155 
    156         var request_id = get_string(json, "request_id")
    157         _require_non_empty(request_id, "request_id")
    158 
    159         var trace_id = _parse_optional_trace_id(json)
    160 
    161         var capability = get_string(json, "capability")
    162         _require_non_empty(capability, "capability")
    163 
    164         var context_json = Value(None)
    165         if _has_key(json, "context"):
    166             context_json = json["context"].clone()
    167 
    168         var context = default_request_context()
    169         var operation_context: Optional[OperationContext] = None
    170         if is_corrected_operation(capability) and operation_context_selects_v2(
    171             context_json
    172         ):
    173             operation_context = parse_operation_context(
    174                 context_json.clone(), capability
    175             )
    176         else:
    177             context = parse_request_context(context_json)
    178         var input = _require_input_value(json)
    179 
    180         return Self(
    181             version=version,
    182             request_id=request_id,
    183             trace_id=trace_id^,
    184             capability=capability,
    185             context=context^,
    186             input=input^,
    187             operation_context=operation_context^,
    188         )
    189 
    190 
    191 @fieldwise_init
    192 struct WireSuccessResponse(Copyable, Movable):
    193     var version: Int
    194     var request_id: String
    195     var trace_id: Optional[String]
    196     var output: Value
    197     var meta: Optional[Value]
    198 
    199     def to_json_value(self) raises -> Value:
    200         var value = loads("{}")
    201         value.set("version", Value(self.version))
    202         value.set("request_id", Value(String(self.request_id)))
    203         if self.trace_id:
    204             value.set("trace_id", Value(String(self.trace_id.value())))
    205         value.set("ok", Value(True))
    206         value.set("output", self.output.clone())
    207         if self.meta:
    208             value.set("meta", self.meta.value().clone())
    209         return value^
    210 
    211 
    212 @fieldwise_init
    213 struct WireErrorResponse(Copyable, Movable):
    214     var version: Int
    215     var request_id: String
    216     var trace_id: Optional[String]
    217     var error: WireError
    218 
    219     def to_json_value(self) raises -> Value:
    220         var value = loads("{}")
    221         value.set("version", Value(self.version))
    222         value.set("request_id", Value(String(self.request_id)))
    223         if self.trace_id:
    224             value.set("trace_id", Value(String(self.trace_id.value())))
    225         value.set("ok", Value(False))
    226         value.set("error", self.error.to_json_value())
    227         return value^