alfworldpythonverified
alfworld household skill
Six task-level household skills (pick, clean, heat, cool, examine-in-light, pick-two) over a fixed action layer with an object-location memory; one call per task.
rec_3cb33e42fc984a789c990fbdb8b63944 · banked 2026-09-04 · by neruva
Not yet certified
This skill has no published checker, so its evidence cannot be reproduced from here.
Evidence
- ratchet check 11/12 train games; generality gate 12/12 held-out train games; forged by claude-sonnet-5 for $0.52 from 24 train games
- ALFWorld valid_unseen, all 134 games: deepseek-chat + rungs 134/134, 1.05 model turns/game, 0 execution errors, $0.04 total; SKILL-DISCO best row 99.3 at 3.2 turns (GPT-4o)
- requires scripts/primitives.py and scripts/priors.py from the alfworld-household skill folder
Use it
# in Claude Code (MCP tools from neruva-mcp)
rung_search(q="alfworld_household_rungs")
rung_install(id="rec_3cb33e42fc984a789c990fbdb8b63944", dir="~/.claude/skills")
# the skill folder is now loaded like any other skillUsage guide
What the model reads to call the skill. This is the whole interface.
Show the guide
Skill library usage guide (ALFWorld)
Import: the module is already imported for you with `World` and `search_order`
bound. Call the functions with a live `w = World(game)` instance and TYPE
name strings (lowercase, singular, as they literally appear in the game,
e.g. 'apple', 'countertop', 'desklamp', 'sinkbasin', 'microwave', 'fridge').
Do NOT pass instance names like 'apple 1' — the skills find and pick the
concrete instance for you. Every function returns True/False for success.
1) pick_and_place(w, obj, dest)
"put a <obj> in/on <dest>"
e.g. task "put a pillow on the sofa" -> pick_and_place(w, 'pillow', 'sofa')
2) clean_and_place(w, obj, dest)
"put a clean <obj> in/on <dest>" / "clean some <obj> and put it in <dest>"
e.g. task "put a clean lettuce in diningtable"
-> clean_and_place(w, 'lettuce', 'diningtable')
3) heat_and_place(w, obj, dest)
"heat some <obj> and put it in/on <dest>" / "put a hot <obj> in <dest>"
e.g. task "heat some egg and put it in garbagecan"
-> heat_and_place(w, 'egg', 'garbagecan')
4) cool_and_place(w, obj, dest)
"cool some <obj> and put it in/on <dest>" / "put a cool <obj> in <dest>"
e.g. task "cool some potato and put it in microwave"
-> cool_and_place(w, 'potato', 'microwave')
5) examine_in_light(w, obj, lamp)
"look at <obj> under the <lamp>" / "examine the <obj> with the <lamp>"
lamp is usually 'desklamp' or 'floorlamp'.
e.g. task "examine the book with the desklamp"
-> examine_in_light(w, 'book', 'desklamp')
6) pick_two_and_place(w, obj, dest)
"put two <obj> in/on <dest>" / "find two <obj> and put them in <dest>"
e.g. task "put two cds in safe" -> pick_two_and_place(w, 'cd', 'safe')
Mapping task sentences to type names:
- Strip articles ("a", "an", "the", "some") and pluralization ("two cds" ->
obj='cd", use pick_two_and_place).
- Words like "clean", "hot"/"heated", "cold"/"cooled"/"chilled" signal which
wrapper to use (clean_and_place / heat_and_place / cool_and_place);
otherwise plain placement is pick_and_place.
- "examine"/"look at ... under/with the <lamp>" signals examine_in_light,
with the lamp type taken from the sentence (desklamp/floorlamp).
- dest/obj/lamp must be the bare noun exactly as ALFWorld names it
(e.g. 'sidetable', 'coffeetable', 'garbagecan', 'sinkbasin').Code
176 lines of python, hashed and signed below.
Show the code
"""Task-level skills built on top of primitives.World.
Each function below performs one ALFWorld task type end-to-end using only
World's verbs (go/open/close/take/put/clean/heat/cool/use/examine) and
queries (objects_here/receptacles_of/instances_of/receptacles), plus the
externally supplied `search_order(obj_type, receptacles)` prior that orders
receptacle types by how likely they are to hold a given object type.
No task logic (search order, plans) lives in primitives.py; it all lives here.
"""
from __future__ import annotations
# ---------------------------------------------------------------------------
# internal helpers
# ---------------------------------------------------------------------------
def _refresh(w, recep):
"""Go to a receptacle, opening it if it's closed. Returns the obs text."""
obs = w.go(recep)
if w.is_closed_here(obs):
obs = w.open(recep)
return obs
def _locate_next(w, obj_type, visited, taken=()):
"""Find one instance of obj_type not already in `taken`.
First re-checks whatever receptacle we are currently standing at (cheap,
handles the case where two instances of obj_type sit on the same
receptacle), then walks search_order(obj_type, ...) skipping receptacles
already in `visited`. Mutates `visited` in place. Returns
(instance_name, receptacle_name) or (None, None).
"""
if w.at:
items = w.objects_here()
insts = [i for i in w.instances_of(obj_type, items) if i not in taken]
if insts:
return insts[0], w.at
for recep in search_order(obj_type, w.receptacles):
if recep in visited:
continue
visited.add(recep)
_refresh(w, recep)
items = w.objects_here()
insts = [i for i in w.instances_of(obj_type, items) if i not in taken]
if insts:
return insts[0], recep
return None, None
def _take(w, inst, recep):
"""Take inst from recep; returns True if now holding it."""
w.take(inst, recep)
return w.holding == inst
def _place(w, inst, dest_type):
"""Try to put the held instance onto/into some instance of dest_type."""
for d in w.receptacles_of(dest_type):
obs = w.go(d)
if w.is_closed_here(obs):
obs = w.open(d)
obs = w.put(inst, d)
if obs and ("you put" in obs.lower() or "you move" in obs.lower()):
return True
return False
def _find_and_take(w, obj_type, visited, taken=()):
inst, recep = _locate_next(w, obj_type, visited, taken)
if not inst:
return None
if not _take(w, inst, recep):
return None
return inst
# ---------------------------------------------------------------------------
# entry points
# ---------------------------------------------------------------------------
def pick_and_place(w, obj, dest):
visited = set()
inst = _find_and_take(w, obj, visited)
if not inst:
return False
return _place(w, inst, dest)
def clean_and_place(w, obj, dest):
visited = set()
inst = _find_and_take(w, obj, visited)
if not inst:
return False
sinks = w.receptacles_of("sinkbasin")
if not sinks:
return False
sink = sinks[0]
obs = w.go(sink)
if w.is_closed_here(obs):
w.open(sink)
w.clean(inst, sink)
return _place(w, inst, dest)
def heat_and_place(w, obj, dest):
visited = set()
inst = _find_and_take(w, obj, visited)
if not inst:
return False
microwaves = w.receptacles_of("microwave")
if not microwaves:
return False
m = microwaves[0]
obs = w.go(m)
if w.is_closed_here(obs):
w.open(m)
w.heat(inst, m)
return _place(w, inst, dest)
def cool_and_place(w, obj, dest):
visited = set()
inst = _find_and_take(w, obj, visited)
if not inst:
return False
fridges = w.receptacles_of("fridge")
if not fridges:
return False
f = fridges[0]
obs = w.go(f)
if w.is_closed_here(obs):
w.open(f)
w.cool(inst, f)
return _place(w, inst, dest)
def examine_in_light(w, obj, lamp):
visited = set()
inst = _find_and_take(w, obj, visited)
if not inst:
return False
linst, lrecep = _locate_next(w, lamp, visited)
if not linst:
return False
w.go(lrecep)
w.use(linst)
return w.won
def pick_two_and_place(w, obj, dest):
visited = set()
taken = []
for _ in range(2):
inst, recep = _locate_next(w, obj, visited, tuple(taken))
if not inst:
break
if not _take(w, inst, recep):
continue
if _place(w, inst, dest):
taken.append(inst)
return len(taken) >= 2
Certificate
Code sha256 ea20b1c3a3f2f990c282e7eb9f8f6d4c2ac3b5716022cb1fd06a90b8337bcf58
Signature ed25519, present
Last re-checked
passing
Re-checked today. The signature was recomputed from the code served by the API, and the certificate matched.
A certificate proves the code has not changed. Re-running the check proves it still works today, on today's libraries.