"""TypeSafe System One / OpenRouter Decisions protocol, not a chat endpoint. Protocol shape informed by MIT-licensed jev-libero / embodied-jev; see THIRD_PARTY_NOTICES. """ import json import math from ..protocol import SCHEMA, VERSION, DecisionError, validate_jev from .http import post, usage def question(options, instruction): return { "type": "choice", "instructions": instruction, "criteria": {option: option for option in options}, } def answer(result, name, options): answers = result.get("answers") item = answers.get(name) if isinstance(answers, dict) else None if not isinstance(item, dict) or item.get("choice") not in options: raise DecisionError("jev_invalid_choice", 502) probabilities = item.get("probabilities", {}) if ( not isinstance(probabilities, dict) or probabilities.keys() - set(options) or any( type(p) not in (int, float) or not math.isfinite(p) or not 0 <= p <= 1 for p in probabilities.values() ) ): raise DecisionError("jev_invalid_probabilities", 502) # Keep official choice even when probabilities do not rank it highest. return item["choice"] async def decide(session, conn, request): props = SCHEMA["$defs"]["JevDecision"]["properties"] options = {name: props[name]["enum"] for name in ("grasp", "diagnosis", "recovery")} options["choice"] = request["candidates"] prompts = { "choice": ( "Choose an offered next skill if safe. Stop for hard safety faults. " "Only the local controller can determine success or permit actuation." ), "grasp": ( "secure requires two finger forces >=0.2 N, verified lift and stable grasp evidence. " "empty means no held object. slipping means a previously secure grasp is being lost. " "Use uncertain if evidence is insufficient. An open gripper is not a secure grasp." ), "diagnosis": ( "Report none when failure=none and there are no safety flags. " "An empty gripper before closing or after release is expected, not a fault. " "Otherwise diagnose empty, slipping, misaligned, unreachable, stalled or uncertain." ), "recovery": ( "Continue with a safe next skill if failure=none; retry only recoverable alignment " "or empty grasp failures before transport; replan when retries are insufficient; " "stop for hard safety faults or unsafe uncertainty." ), } result = await post( session, conn, "", { "model": conn.model, **( {"provider": {"allow_fallbacks": False}} if conn.protocol == "openrouter-decisions" else {} ), "state": json.dumps( {"observation": request["observation"], "failure": request.get("failure", "none")}, ensure_ascii=False, ), "questions": { name: question(values, prompts[name]) for name, values in options.items() }, }, ) value = { "version": VERSION, **{name: answer(result, name, values) for name, values in options.items()}, } return validate_jev(value, request["candidates"]), usage(result)