Diese Seite wurde maschinell übersetzt und wurde noch nicht von einer Person überprüft. Englisch ist die Referenz; Korrekturen auf GitHub sind willkommen. GitHub
Cookwala / SDK und Szenarien / 041
Stop a run and read the log it leaves behind
Stop always works. Start a run, stop it while it waits for a person, and read the ExecutionLog: what was done, by whom it was verified, and that it carries no personal data.
Zuerst lesen: /docs/CORE/ /docs/HUB/
Schritte
Start a shakshuka run with a person present.
startExecutionLet the arm finish the three cutting steps; the run then waits for a person to heat the pan.
Stop with a reason. The hub answers at once with state stopping; the device cuts motion and heat locally.
stopExecutionThe next tick of the simulated device completes the stop.
The run is now stopped, a final state.
getExecutionThe log exists once the run has ended. It records the three steps that ran, the device and its safety-limits pack, the outcome aborted_safe, and privacy fields that say no personal data is inside.
executionLog
Ergebnis
You know that a stop is answered immediately and that the log of an aborted run is as complete as the log of a served one. Next: scenario 058 looks at the privacy fields of the log.
Kommandozeile
cookwala hub --recipes examples --speed 200
curl -s -X POST http://localhost:7878/v1/executions/ex-2026-10-04-001/stop -H 'Content-Type: application/json' -H 'Idempotency-Key: stop-0001' -d '{"reason":"service ended"}'
curl -s http://localhost:7878/v1/executions/ex-2026-10-04-001/logAufgezeichnete Ausgabe
Status: ok
[1] startExecution: {"core": "0.2.0", "kind": "ExecutionStatus", "id": "ex-041-stop", "seq": 0, "state": "accepted", "request": "ex-041-stop", "updatedAt": "2026-10-07T00:54:11Z", "x-hub-plan": [{"node": "n1", "op": "cw.op.cut", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.vision"}, {"node": "n2", "op": "cw.op.cut", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.vision"}, {"node": "n3", "op": "cw.op.cut", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.vision"}, {"node": "n4", "op": "cw.op.heat", "by": "human", "verifiedBy": "human"}, {"node": "n5", "op": "cw.op.saute", "by": "hu…
[3] stopExecution: {"core": "0.2.0", "kind": "ExecutionStatus", "id": "ex-041-stop", "seq": 7, "state": "stopping", "request": "ex-041-stop", "updatedAt": "2026-10-07T00:54:15Z", "x-hub-plan": [{"node": "n1", "op": "cw.op.cut", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.vision"}, {"node": "n2", "op": "cw.op.cut", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.vision"}, {"node": "n3", "op": "cw.op.cut", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.vision"}, {"node": "n4", "op": "cw.op.heat", "by": "human", "verifiedBy": "human"}, {"node": "n5", "op": "cw.op.saute", "by": "hu…
[5] getExecution: {"core": "0.2.0", "kind": "ExecutionStatus", "id": "ex-041-stop", "seq": 8, "state": "stopped", "request": "ex-041-stop", "updatedAt": "2026-10-07T00:54:16Z", "x-hub-plan": [{"node": "n1", "op": "cw.op.cut", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.vision"}, {"node": "n2", "op": "cw.op.cut", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.vision"}, {"node": "n3", "op": "cw.op.cut", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.vision"}, {"node": "n4", "op": "cw.op.heat", "by": "human", "verifiedBy": "human"}, {"node": "n5", "op": "cw.op.saute", "by": "hum…
[6] executionLog: {"core": "0.2.0", "kind": "ExecutionLog", "id": "log-ex-041-stop", "recipe": "cw:cookwala.ai:example-shakshuka", "recipeHash": "sha256:2ea6fab93cc673fc6784f9bc9fe401d2387bb7779dc537df97286b73807c8841", "device": {"vendor": "Example Robotics", "model": "CounterArm 2", "firmware": "hub-0.1", "safetyLimits": "[email protected]"}, "startedAt": "2026-10-07T00:54:11Z", "endedAt": "2026-10-07T00:54:16Z", "outcome": "aborted_safe", "servings": 4, "steps": [{"node": "n1", "op": "cw.op.cut", "verifiedBy": "sensor", "envelopeOk": true, "startedAt": "2026-10-07T00:54:12Z", "endedAt": "2026-10-07T00:5…Code
Ausführen: python scenarios/out/041-stop-an-execution-and-read-its-log/python.py
# Scenario 041: Stop a run and read the log it leaves behind
# Stop always works. Start a run, stop it while it waits for a person, and read the ExecutionLog: what was done, by whom it was verified, and that it carries no personal data.
# 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: Start a shakshuka run with a person present.
try:
started = c.start_execution({"core": "0.2.0", "kind": "ExecuteRequest", "id": "ex-041-stop", "recipe": "cw:cookwala.ai:example-shakshuka", "recipeHash": "sha256:2ea6fab93cc673fc6784f9bc9fe401d2387bb7779dc537df97286b73807c8841", "servings": 4, "requestedBy": "agent:planner-1", "idempotencyKey": "ex-041-stop-a"}, "ex-041-stop-key", True)
except CookwalaProblem as p:
started = p.body # a refusal is a result, not a crash
print("refused:", p.refusal)
assert pick(started, "state") == "accepted", pick(started, "state")
print("ok", "state", "=", "accepted")
assert pick(started, "seq") == 0, pick(started, "seq")
print("ok", "seq", "=", 0)
# Step 2: Let the arm finish the three cutting steps; the run then waits for a person to heat the pan.
import time; time.sleep(4)
# Step 3: Stop with a reason. The hub answers at once with state stopping; the device cuts motion and heat locally.
try:
stop = c.stop_execution("ex-041-stop", "service ended")
except CookwalaProblem as p:
stop = p.body # a refusal is a result, not a crash
print("refused:", p.refusal)
assert pick(stop, "state") == "stopping", pick(stop, "state")
print("ok", "state", "=", "stopping")
assert pick(stop, "seq") == 7, pick(stop, "seq")
print("ok", "seq", "=", 7)
# Step 4: The next tick of the simulated device completes the stop.
import time; time.sleep(1.5)
# Step 5: The run is now stopped, a final state.
status = c.get_execution("ex-041-stop")
assert pick(status, "state") == "stopped", pick(status, "state")
print("ok", "state", "=", "stopped")
assert pick(status, "seq") == 8, pick(status, "seq")
print("ok", "seq", "=", 8)
# Step 6: The log exists once the run has ended. It records the three steps that ran, the device and its safety-limits pack, the outcome aborted_safe, and privacy fields that say no personal data is inside.
log = c.execution_log("ex-041-stop")
assert pick(log, "outcome") == "aborted_safe", pick(log, "outcome")
print("ok", "outcome", "=", "aborted_safe")
assert pick(log, "steps.length") == 3, pick(log, "steps.length")
print("ok", "steps.length", "=", 3)
assert pick(log, "device.model") == "CounterArm 2", pick(log, "device.model")
print("ok", "device.model", "=", "CounterArm 2")
assert pick(log, "device.safetyLimits") == "[email protected]", pick(log, "device.safetyLimits")
print("ok", "device.safetyLimits", "=", "[email protected]")
assert pick(log, "privacy.personalData") == "none", pick(log, "privacy.personalData")
print("ok", "privacy.personalData", "=", "none")
print("scenario complete")