Esta página fue traducida por una máquina y aún no ha sido revisada por una persona. El inglés es la referencia; las correcciones son bienvenidas en GitHub. GitHub

Cookwala / SDK y escenarios / 028

The refusals an agent sees when nobody is home

An agent planning dinner for an empty house gets needs_human_present at the first step whose envelope says unattended is false. The plan up to that step is returned, so the agent can say what could have run.

Audiencia: agent builder · Objetivo: Robots para las personas · Nivel: beginner

Leer primero: /docs/CORE/ /docs/QUICKSTART/

Pasos

  1. Shakshuka starts with cutting: refused at n1 with an empty plan. dryRun

  2. Molokhia boils and simmers the chicken first: five steps are planned, then heating a pan stops it. dryRun

  3. Koshari on the fryer robot: six boiling, simmering and draining steps are fine unattended; heating the pan for the vermicelli is not. dryRun

  4. The same molokhia with a person in the house: twelve steps, all by the device. dryRun

Resultado

Your agent can explain a refusal to the household in one sentence and offer the alternative: start when someone is home. The rule is in Core section 6, item 6.

Línea de comandos

cookwala dryrun examples/shakshuka.cookwala.json --device examples/capabilities/demo-hob-robot.json
cookwala dryrun examples/molokhia.cookwala.json --device examples/capabilities/demo-hob-robot.json
cookwala dryrun examples/koshari.cookwala.json --device examples/capabilities/demo-fryer-robot.json
cookwala dryrun examples/molokhia.cookwala.json --device examples/capabilities/demo-hob-robot.json --human-present

Salida grabada

Estado: ok

[1] dryRun: {"state": "refused", "refusal": {"reason": "needs_human_present", "node": "n1", "detail": "cw.op.cut may not run unattended"}, "plan": []}
[2] dryRun: {"state": "refused", "refusal": {"reason": "needs_human_present", "node": "n6", "detail": "cw.op.heat may not run unattended"}, "plan": [{"node": "n1", "op": "cw.op.boil", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n2", "op": "cw.op.simmer", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n3", "op": "cw.op.drain", "by": "device", "verifiedBy": "time", "rung": "time"}, {"node": "n4", "op": "cw.op.simmer", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n5", "op": "cw.op.crush", "by": "d…
[3] dryRun: {"state": "refused", "refusal": {"reason": "needs_human_present", "node": "n7", "detail": "cw.op.heat may not run unattended"}, "plan": [{"node": "n1", "op": "cw.op.boil", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n2", "op": "cw.op.simmer", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n3", "op": "cw.op.drain", "by": "device", "verifiedBy": "time", "rung": "time"}, {"node": "n4", "op": "cw.op.boil", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n5", "op": "cw.op.boil", "by": "devi…
[4] dryRun: {"state": "accepted", "plan": [{"node": "n1", "op": "cw.op.boil", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n2", "op": "cw.op.simmer", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n3", "op": "cw.op.drain", "by": "device", "verifiedBy": "time", "rung": "time"}, {"node": "n4", "op": "cw.op.simmer", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n5", "op": "cw.op.crush", "by": "device", "verifiedBy": "time", "rung": "time"}, {"node": "n6", "op": "cw.op.heat", "by": "device", "verifie…

Código

Ejecutar: python scenarios/out/028-refusals-when-nobody-is-home/python.py

# Scenario 028: The refusals an agent sees when nobody is home
# An agent planning dinner for an empty house gets needs_human_present at the first step whose envelope says unattended is false. The plan up to that step is returned, so the agent can say what could have run.
# 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: Shakshuka starts with cutting: refused at n1 with an empty plan.
shakshuka = c.dry_run(recipe_id="shakshuka", device_id="demo-hob-robot", human_present=False)
assert pick(shakshuka, "state") == "refused", pick(shakshuka, "state")
print("ok", "state", "=", "refused")
assert pick(shakshuka, "refusal.reason") == "needs_human_present", pick(shakshuka, "refusal.reason")
print("ok", "refusal.reason", "=", "needs_human_present")
assert pick(shakshuka, "refusal.node") == "n1", pick(shakshuka, "refusal.node")
print("ok", "refusal.node", "=", "n1")
assert pick(shakshuka, "plan.length") == 0, pick(shakshuka, "plan.length")
print("ok", "plan.length", "=", 0)

# Step 2: Molokhia boils and simmers the chicken first: five steps are planned, then heating a pan stops it.
molokhia = c.dry_run(recipe_id="molokhia", device_id="demo-hob-robot", human_present=False)
assert pick(molokhia, "state") == "refused", pick(molokhia, "state")
print("ok", "state", "=", "refused")
assert pick(molokhia, "refusal.reason") == "needs_human_present", pick(molokhia, "refusal.reason")
print("ok", "refusal.reason", "=", "needs_human_present")
assert pick(molokhia, "refusal.node") == "n6", pick(molokhia, "refusal.node")
print("ok", "refusal.node", "=", "n6")
assert pick(molokhia, "plan.length") == 5, pick(molokhia, "plan.length")
print("ok", "plan.length", "=", 5)
assert pick(molokhia, "plan[0].rung") == "cw.sense.liquid_temp", pick(molokhia, "plan[0].rung")
print("ok", "plan[0].rung", "=", "cw.sense.liquid_temp")

# Step 3: Koshari on the fryer robot: six boiling, simmering and draining steps are fine unattended; heating the pan for the vermicelli is not.
koshari = c.dry_run(recipe_id="koshari", device_id="demo-fryer-robot", human_present=False)
assert pick(koshari, "state") == "refused", pick(koshari, "state")
print("ok", "state", "=", "refused")
assert pick(koshari, "refusal.reason") == "needs_human_present", pick(koshari, "refusal.reason")
print("ok", "refusal.reason", "=", "needs_human_present")
assert pick(koshari, "refusal.node") == "n7", pick(koshari, "refusal.node")
print("ok", "refusal.node", "=", "n7")
assert pick(koshari, "plan.length") == 6, pick(koshari, "plan.length")
print("ok", "plan.length", "=", 6)

# Step 4: The same molokhia with a person in the house: twelve steps, all by the device.
molokhiaWithPerson = c.dry_run(recipe_id="molokhia", device_id="demo-hob-robot", human_present=True)
assert pick(molokhiaWithPerson, "state") == "accepted", pick(molokhiaWithPerson, "state")
print("ok", "state", "=", "accepted")
assert pick(molokhiaWithPerson, "plan.length") == 12, pick(molokhiaWithPerson, "plan.length")
print("ok", "plan.length", "=", 12)

print("scenario complete")

scenarios/028-refusals-when-nobody-is-home.json

Anterior: 027 Siguiente: 029