Esta página foi traduzida por máquina e ainda não foi revisada por uma pessoa. O inglês é a referência; correções são bem-vindas no GitHub. GitHub
Cookwala / SDK e cenários / 045
A run is refused before anything heats when no person is present
The hub dry-runs every request against the device before accepting it. This counter arm has no hob and may not cut unattended, so a request with nobody present is refused at the first node, and the refusal says why.
Leia primeiro: /docs/CORE/ /docs/HUB/
Passos
The device: three operations (cut, crack, transfer), one vision sensor, presence detection and a stop control.
capabilitiesSend the request with humanPresent false. The answer is an ExecutionStatus in state refused with a reason, the node and a detail; nothing was heated or moved.
startExecutionStop is never refused, even for a run that never started: the hub returns the final status unchanged.
stopExecution
Resultado
You have a refusal with reason, node and detail, which is the standard's first promise: check before heat. Next: scenarios 046 to 048 show the other refusal reasons a hub applies before the dry run.
Linha de comando
cookwala dryrun examples/shakshuka.cookwala.json --device examples/capabilities/robot-arm.json
cookwala dryrun examples/shakshuka.cookwala.json --device examples/capabilities/robot-arm.json --human-presentSaída gravada
Status: ok
[1] capabilities: {"cookwala": "0.1.0", "actor": {"kind": "robot", "id": "robot:arm-1", "vendor": "Example Robotics", "model": "CounterArm 2"}, "roles": ["executor"], "location": {"zone": "counter-left", "mobile": false}, "capabilities": {"ops": [{"op": "cw.op.cut", "params": {"shape": ["dice", "slice", "mince", "julienne"]}, "ingredientClasses": ["cw.ing.class.vegetable_firm", "cw.ing.class.herb"], "reliability": 0.97}, {"op": "cw.op.crack", "reliability": 0.95}, {"op": "cw.op.transfer", "maxMassG": 3000}], "sensors": [{"sensor": "cw.sense.vision", "visionCues": ["cw.sense.translucent", "cw.sense.egg_whites_se…
[2] startExecution: {"core": "0.2.0", "kind": "ExecutionStatus", "id": "ex-045-absent", "seq": 0, "state": "refused", "request": "ex-045-absent", "updatedAt": "2026-10-07T00:54:31Z", "refusal": {"reason": "needs_human_present", "detail": "cw.op.cut may not run unattended", "node": "n1"}}
[3] stopExecution: {"core": "0.2.0", "kind": "ExecutionStatus", "id": "ex-045-absent", "seq": 0, "state": "refused", "request": "ex-045-absent", "updatedAt": "2026-10-07T00:54:31Z", "refusal": {"reason": "needs_human_present", "detail": "cw.op.cut may not run unattended", "node": "n1"}}Código
Executar: python scenarios/out/045-refused-before-heat-when-no-person-is-present/python.py
# Scenario 045: A run is refused before anything heats when no person is present
# The hub dry-runs every request against the device before accepting it. This counter arm has no hob and may not cut unattended, so a request with nobody present is refused at the first node, and the refusal says why.
# Run a hub first: python hub/cookwala_hub.py --recipes examples
import json, os
from cookwala.client import CookwalaClient, CookwalaProblem
def load(path):
with open(path, encoding="utf-8") as f:
return json.load(f)
def pick(obj, path):
for part in path.replace("]", "").replace("[", ".").split("."):
obj = obj[int(part)] if part.isdigit() else (len(obj) if part == "length" else obj.get(part))
return obj
c = CookwalaClient(os.environ.get("COOKWALA_HUB", "http://localhost:7878"))
# Step 1: The device: three operations (cut, crack, transfer), one vision sensor, presence detection and a stop control.
hub = c.capabilities()
assert pick(hub, "capabilities.ops.length") == 3, pick(hub, "capabilities.ops.length")
print("ok", "capabilities.ops.length", "=", 3)
assert pick(hub, "capabilities.sensors.length") == 1, pick(hub, "capabilities.sensors.length")
print("ok", "capabilities.sensors.length", "=", 1)
assert pick(hub, "safety.presenceDetection") == True, pick(hub, "safety.presenceDetection")
print("ok", "safety.presenceDetection", "=", True)
# Step 2: Send the request with humanPresent false. The answer is an ExecutionStatus in state refused with a reason, the node and a detail; nothing was heated or moved.
try:
refused = c.start_execution({"core": "0.2.0", "kind": "ExecuteRequest", "id": "ex-045-absent", "recipe": "cw:cookwala.ai:example-shakshuka", "recipeHash": "sha256:2ea6fab93cc673fc6784f9bc9fe401d2387bb7779dc537df97286b73807c8841", "servings": 4, "requestedBy": "agent:planner-1", "idempotencyKey": "ex-045-absent-a"}, "ex-045-absent-key", False)
except CookwalaProblem as p:
refused = p.body # a refusal is a result, not a crash
print("refused:", p.refusal)
assert pick(refused, "state") == "refused", pick(refused, "state")
print("ok", "state", "=", "refused")
assert pick(refused, "refusal.reason") == "needs_human_present", pick(refused, "refusal.reason")
print("ok", "refusal.reason", "=", "needs_human_present")
assert pick(refused, "refusal.node") == "n1", pick(refused, "refusal.node")
print("ok", "refusal.node", "=", "n1")
assert pick(refused, "refusal.detail") == "cw.op.cut may not run unattended", pick(refused, "refusal.detail")
print("ok", "refusal.detail", "=", "cw.op.cut may not run unattended")
# Step 3: Stop is never refused, even for a run that never started: the hub returns the final status unchanged.
try:
stop = c.stop_execution("ex-045-absent")
except CookwalaProblem as p:
stop = p.body # a refusal is a result, not a crash
print("refused:", p.refusal)
assert pick(stop, "state") == "refused", pick(stop, "state")
print("ok", "state", "=", "refused")
assert pick(stop, "seq") == 0, pick(stop, "seq")
print("ok", "seq", "=", 0)
print("scenario complete")
scenarios/045-refused-before-heat-when-no-person-is-present.json