hyf

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

commit f89b737c3b52ea8b29bdb377ef566f598736a5d4
parent 868c7e156b70e2948b0d1b4203eeda092261dbcf
Author: triesap <tyson@radroots.org>
Date:   Mon, 21 Sep 2026 13:45:31 +0000

provider: implement the production jev http client

Diffstat:
Asrc/hyf_provider/jev_client.mojo | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/test_jev.mojo | 34++++++++++++++++++++++++++++++++++
2 files changed, 106 insertions(+), 0 deletions(-)

diff --git a/src/hyf_provider/jev_client.mojo b/src/hyf_provider/jev_client.mojo @@ -0,0 +1,72 @@ +from flare.http import HttpClient +from json import Value, dumps + + +@fieldwise_init +struct JevHttpOutcome(Copyable, Movable): + var status: Int + var body_text: String + + +def _is_loopback_host(host: String) -> Bool: + return ( + host == "localhost" + or host == "127.0.0.1" + or host == "[::1]" + or host == "::1" + ) + + +def validate_jev_base_url(base_url: String) raises -> String: + var trimmed = String(String(base_url).strip()) + while trimmed.byte_length() > 1 and trimmed.endswith("/"): + trimmed = String(trimmed[byte=0:trimmed.byte_length() - 1]) + if trimmed == "": + raise Error("jev base_url must not be empty") + var scheme = "" + var rest = trimmed + if trimmed.startswith("https://"): + scheme = "https" + rest = String(trimmed[byte=8:]) + elif trimmed.startswith("http://"): + scheme = "http" + rest = String(trimmed[byte=7:]) + else: + raise Error("jev base_url must use https") + if rest.find("@") >= 0: + raise Error("jev base_url must not contain credentials") + if rest.find("?") >= 0: + raise Error("jev base_url must not contain a query") + if rest.find("#") >= 0: + raise Error("jev base_url must not contain a fragment") + var slash = rest.find("/") + var host_port = rest if slash < 0 else String(rest[byte=0:slash]) + var host = host_port + var colon = host_port.find(":") + if colon >= 0: + if host_port.startswith("["): + var close = host_port.find("]") + if close >= 0: + host = String(host_port[byte=0:close + 1]) + else: + host = String(host_port[byte=0:colon]) + if host == "": + raise Error("jev base_url must include a host") + if scheme == "http" and not _is_loopback_host(host): + raise Error( + "jev base_url must use https unless the host is loopback" + ) + return trimmed^ + + +def jev_systemone_url(base_url: String) raises -> String: + return validate_jev_base_url(base_url) + "/v1/systemone" + + +def post_jev_systemone( + base_url: String, body: Value, timeout_ms: Int +) raises -> JevHttpOutcome: + var url = jev_systemone_url(base_url) + with HttpClient(timeout_ms=timeout_ms, max_redirects=0) as client: + var response = client.post(url, dumps(body)) + return JevHttpOutcome(status=response.status, body_text=response.text()) diff --git a/tests/test_jev.mojo b/tests/test_jev.mojo @@ -287,3 +287,37 @@ def test_local_provider_server_scripts_transport_failures() raises: ) assert_equal(response.status, 500) err_stub.wait() + + +from hyf_provider.jev_client import post_jev_systemone, validate_jev_base_url +from json import loads as _loads + + +def test_jev_endpoint_policy_and_loopback_client() raises: + assert_equal( + validate_jev_base_url("https://api.typesafe.ai/"), + "https://api.typesafe.ai", + ) + assert_equal( + validate_jev_base_url("http://127.0.0.1:8000"), + "http://127.0.0.1:8000", + ) + with assert_raises(): + _ = validate_jev_base_url("http://api.typesafe.ai") + with assert_raises(): + _ = validate_jev_base_url("http://127.0.0.1.evil.example") + with assert_raises(): + _ = validate_jev_base_url("https://user:pass@api.typesafe.ai") + with assert_raises(): + _ = validate_jev_base_url("ftp://api.typesafe.ai") + + var port = reserve_jev_port() + var stub = spawn_jev_stub(port, "ok", 1) + var outcome = post_jev_systemone( + "http://127.0.0.1:" + String(port), + _loads('{"model":"jev-1.13.0","state":"s","questions":{}}'), + 5000, + ) + assert_equal(outcome.status, 200) + assert_true(outcome.body_text.find("jev-1.13.0") >= 0) + stub.wait()