hyf

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

commit 4fe170de7b4ef1fe298f2697c9e9d57ca6600704
parent 49410dd3d553a808259a17392a6351a9066ea1c4
Author: triesap <tyson@radroots.org>
Date:   Wed,  8 Apr 2026 20:54:00 +0000

control: make hyf feature reporting truthful

Diffstat:
Msrc/hyf_core/request_context.mojo | 23++++++++++++++++++++++-
Msrc/hyf_stdio/control/capabilities.mojo | 8+++++---
Asrc/hyf_stdio/control/request_context_contract.mojo | 29+++++++++++++++++++++++++++++
Msrc/hyf_stdio/control/status.mojo | 12+++++++-----
Mtests/test_hyf.mojo | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/test_stdio_contract.mojo | 8++++++++
6 files changed, 132 insertions(+), 9 deletions(-)

diff --git a/src/hyf_core/request_context.mojo b/src/hyf_core/request_context.mojo @@ -78,6 +78,10 @@ struct RequestContext(Copyable, Movable): def request_context_feature_names() -> List[String]: + return request_context_allowed_keys() + + +def request_context_allowed_keys() -> List[String]: var features = List[String]() features.append("consumer") features.append("execution_mode_preference") @@ -86,6 +90,23 @@ def request_context_feature_names() -> List[String]: return features^ +def accepted_request_context_feature_names() -> List[String]: + var features = List[String]() + features.append("consumer") + features.append("execution_mode_preference") + features.append("scope.listing_ids") + features.append("return_provenance") + return features^ + + +def effective_request_context_feature_names() -> List[String]: + var features = List[String]() + features.append("execution_mode_preference") + features.append("scope.listing_ids") + features.append("return_provenance") + return features^ + + def default_request_context() -> RequestContext: return RequestContext( consumer="unknown", @@ -149,7 +170,7 @@ def parse_request_context(json: Value) raises -> RequestContext: _require_object(json, "request context") - var allowed_keys = request_context_feature_names() + var allowed_keys = request_context_allowed_keys() _require_allowed_keys(json, allowed_keys, "request context") var context = default_request_context() diff --git a/src/hyf_stdio/control/capabilities.mojo b/src/hyf_stdio/control/capabilities.mojo @@ -3,7 +3,9 @@ from std.collections import List from mojson import Value, loads from hyf_core.capabilities.registry import canonical_business_capabilities -from hyf_core.request_context import request_context_feature_names +from hyf_stdio.control.request_context_contract import ( + build_request_context_contract_value, +) def _string_array(values: List[String]) raises -> Value: @@ -58,7 +60,7 @@ def build_capabilities_output() raises -> Value: output.set("business_capabilities", capabilities) output.set("assisted_backend_capabilities", loads("[]")) output.set( - "request_context_features", - _string_array(request_context_feature_names()), + "request_context_contract", + build_request_context_contract_value(), ) return output^ diff --git a/src/hyf_stdio/control/request_context_contract.mojo b/src/hyf_stdio/control/request_context_contract.mojo @@ -0,0 +1,29 @@ +from std.collections import List + +from mojson import Value, loads + +from hyf_core.request_context import ( + accepted_request_context_feature_names, + effective_request_context_feature_names, +) + + +def _string_array(values: List[String]) raises -> Value: + var array = loads("[]") + for value in values: + array.append(Value(String(value))) + return array^ + + +def build_request_context_contract_value() raises -> Value: + var contract = loads("{}") + contract.set( + "accepted_features", + _string_array(accepted_request_context_feature_names()), + ) + contract.set( + "effective_features", + _string_array(effective_request_context_feature_names()), + ) + contract.set("unsupported_field_behavior", Value("reject")) + return contract^ diff --git a/src/hyf_stdio/control/status.mojo b/src/hyf_stdio/control/status.mojo @@ -10,7 +10,9 @@ from hyf_core.capabilities.registry import ( implemented_deterministic_capability_count, ) from hyf_core.metadata import current_build_identity -from hyf_core.request_context import request_context_feature_names +from hyf_stdio.control.request_context_contract import ( + build_request_context_contract_value, +) def _string_array(values: List[String]) raises -> Value: @@ -107,10 +109,10 @@ def build_status_output() raises -> Value: var limits = loads("{}") limits.set("max_requests_per_process", Value(1)) - limits.set( - "request_context_features", - _string_array(request_context_feature_names()), - ) output.set("limits", limits) + output.set( + "request_context_contract", + build_request_context_contract_value(), + ) return output^ diff --git a/tests/test_hyf.mojo b/tests/test_hyf.mojo @@ -31,6 +31,13 @@ def _business_capability(result: Value, capability_id: String) raises -> Value: raise Error("missing capability '" + capability_id + "' in response") +def _array_string_values(value: Value) raises -> List[String]: + var items = List[String]() + for item in value.array_items(): + items.append(item.string_value()) + return items^ + + def test_decode_request_parses_context_and_input() raises: var request = decode_request( '{"version":1,"request_id":"req-1","trace_id":"trace-1","capability":"query_rewrite","context":{"consumer":"radroots-cli","execution_mode_preference":"deterministic","return_provenance":true},"input":{"query":"eggs near me"}}' @@ -188,6 +195,31 @@ def test_status_reports_registered_deterministic_ready() raises: ), 3, ) + assert_true( + not _has_key(result["output"]["limits"], "request_context_features") + ) + var status_request_context_contract = result["output"][ + "request_context_contract" + ] + var status_accepted = _array_string_values( + status_request_context_contract["accepted_features"] + ) + assert_equal(len(status_accepted), 4) + assert_equal(status_accepted[0], "consumer") + assert_equal(status_accepted[1], "execution_mode_preference") + assert_equal(status_accepted[2], "scope.listing_ids") + assert_equal(status_accepted[3], "return_provenance") + var status_effective = _array_string_values( + status_request_context_contract["effective_features"] + ) + assert_equal(len(status_effective), 3) + assert_equal(status_effective[0], "execution_mode_preference") + assert_equal(status_effective[1], "scope.listing_ids") + assert_equal(status_effective[2], "return_provenance") + assert_equal( + status_request_context_contract["unsupported_field_behavior"].string_value(), + "reject", + ) def test_capabilities_report_implemented_and_disabled_states() raises: @@ -217,6 +249,35 @@ def test_capabilities_report_implemented_and_disabled_states() raises: filter_extraction["disabled_reason"].string_value(), "deferred_bootstrap_capability", ) + assert_true( + not _has_key(result["output"], "request_context_features") + ) + var capabilities_request_context_contract = result["output"][ + "request_context_contract" + ] + var capabilities_accepted = _array_string_values( + capabilities_request_context_contract["accepted_features"] + ) + assert_equal(len(capabilities_accepted), 4) + assert_equal(capabilities_accepted[0], "consumer") + assert_equal( + capabilities_accepted[1], "execution_mode_preference" + ) + assert_equal(capabilities_accepted[2], "scope.listing_ids") + assert_equal(capabilities_accepted[3], "return_provenance") + var capabilities_effective = _array_string_values( + capabilities_request_context_contract["effective_features"] + ) + assert_equal(len(capabilities_effective), 3) + assert_equal( + capabilities_effective[0], "execution_mode_preference" + ) + assert_equal(capabilities_effective[1], "scope.listing_ids") + assert_equal(capabilities_effective[2], "return_provenance") + assert_equal( + capabilities_request_context_contract["unsupported_field_behavior"].string_value(), + "reject", + ) def test_disabled_capability_returns_capability_disabled() raises: diff --git a/tests/test_stdio_contract.mojo b/tests/test_stdio_contract.mojo @@ -33,6 +33,14 @@ def test_status_success() raises: response["output"]["execution_mode_request_behavior"]["assisted"].string_value(), "backend_unavailable", ) + assert_equal( + response["output"]["request_context_contract"]["accepted_features"][2].string_value(), + "scope.listing_ids", + ) + assert_equal( + response["output"]["request_context_contract"]["effective_features"][0].string_value(), + "execution_mode_preference", + ) def test_invalid_envelope_preserves_correlation() raises: