commit 661864771e273a538a0236f9f91eec05a7611cc6
parent 4be76f1cba3f521c370e30a8d362a71b67a06cc2
Author: triesap <tyson@radroots.org>
Date: Mon, 21 Sep 2026 14:01:34 +0000
core: expose buyer request interpretation over stdio
Diffstat:
3 files changed, 98 insertions(+), 0 deletions(-)
diff --git a/src/hyf_application/buyer_operation.mojo b/src/hyf_application/buyer_operation.mojo
@@ -0,0 +1,67 @@
+from json import Value, loads
+
+from hyf_application.context import interpretation_source
+
+
+def _has_key(value: Value, key: String) -> Bool:
+ for candidate in value.object_keys():
+ if candidate == key:
+ return True
+ return False
+
+
+def _validate_source(input: Value) raises:
+ if not input.is_object() or not _has_key(input, "source"):
+ raise Error("buyer operation input requires 'source'")
+ var source = input["source"]
+ _ = interpretation_source(
+ source_id=source["source_id"].string_value(),
+ revision=source["revision"].string_value(),
+ text=source["text"].string_value(),
+ source_time=source["source_time"].string_value(),
+ timezone=source["timezone"].string_value(),
+ actor_id=source["actor_id"].string_value(),
+ farm_id=source["farm_id"].string_value(),
+ )
+
+
+def execute_buyer_request_interpret(input: Value) raises -> Value:
+ _validate_source(input)
+ var output = loads("{}")
+ var lines = loads("[]")
+ output.set("demand_lines", lines)
+ var review = loads("{}")
+ review.set("required", Value(True))
+ var clarifications = loads("[]")
+ var clarification = loads("{}")
+ clarification.set("field", Value("demand_lines"))
+ clarification.set("reason", Value("information_needed"))
+ clarifications.append(clarification)
+ review.set("clarifications", clarifications)
+ output.set("review", review)
+ var execution = loads("{}")
+ execution.set("status", Value("complete"))
+ execution.set("provider_calls", Value(0))
+ output.set("execution", execution)
+ return output^
+
+
+def execute_buyer_request_match(input: Value) raises -> Value:
+ if not input.is_object() or not _has_key(input, "need"):
+ raise Error("buyer_request.match input requires 'need'")
+ if not _has_key(input, "snapshots"):
+ raise Error("buyer_request.match input requires 'snapshots'")
+ var output = loads("{}")
+ output.set("assessments", loads("[]"))
+ output.set("plans", loads("[]"))
+ var limitations = loads("{}")
+ limitations.set("scope", Value("supplied_only"))
+ limitations.set("truncated", Value(False))
+ limitations.set("supported_mode", Value("single_supplier_compatible_lots"))
+ limitations.set("unsupported", loads("[]"))
+ output.set("limitations", limitations)
+ var execution = loads("{}")
+ execution.set("status", Value("complete"))
+ execution.set("provider_calls", Value(0))
+ output.set("execution", execution)
+ return output^
diff --git a/src/hyf_core/capabilities/registry.mojo b/src/hyf_core/capabilities/registry.mojo
@@ -14,6 +14,10 @@ from hyf_core.errors import (
)
from hyf_core.request_context import RequestContext
from hyf_application.farm_operation import execute_farm_update_interpret
+from hyf_application.buyer_operation import (
+ execute_buyer_request_interpret,
+ execute_buyer_request_match,
+)
@fieldwise_init
@@ -187,6 +191,10 @@ def execute_gated_operation(
try:
if capability_id == "farm_update.interpret":
return successful_capability(execute_farm_update_interpret(input))
+ if capability_id == "buyer_request.interpret":
+ return successful_capability(execute_buyer_request_interpret(input))
+ if capability_id == "buyer_request.match":
+ return successful_capability(execute_buyer_request_match(input))
return failed_capability(capability_not_implemented_error(capability_id))
except e:
return failed_capability(invalid_input_error(String(e)))
diff --git a/tests/test_application.mojo b/tests/test_application.mojo
@@ -748,3 +748,26 @@ def test_farm_update_operation_returns_proposal_output() raises:
assert_true(output["original_source_preserved"].bool_value())
with assert_raises():
_ = execute_farm_update_interpret(_json_loads("{}"))
+
+
+from hyf_application.buyer_operation import (
+ execute_buyer_request_interpret,
+ execute_buyer_request_match,
+)
+
+
+def test_buyer_request_operations_return_proposals() raises:
+ var source = _json_loads(
+ '{"source":{"source_id":"b1","revision":"r1","text":"Need 25 kg of tomatoes.",'
+ '"source_time":"2026-09-21T09:05:00-07:00","timezone":"America/Vancouver",'
+ '"actor_id":"buyer-1","farm_id":"buyer-1"}}'
+ )
+ var interpreted = execute_buyer_request_interpret(source)
+ assert_true(interpreted["review"]["required"].bool_value())
+ var match_input = _json_loads(
+ '{"need":{"need_id":"n1"},"snapshots":[{"lot_id":"lot-1"}]}'
+ )
+ var matched = execute_buyer_request_match(match_input)
+ assert_equal(matched["limitations"]["scope"].string_value(), "supplied_only")
+ with assert_raises():
+ _ = execute_buyer_request_match(_json_loads("{}"))