kitchenbench 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kitchenbench/tasks.py ADDED
@@ -0,0 +1,169 @@
1
+ """The 10 KitchenBench tasks, generated from :data:`kitchenbench.specs.SPECS`.
2
+
3
+ Each task instance (a stochastic setup + goal) becomes one Inspect Robots ``Scene``;
4
+ each task runs ``K_REALIZATIONS`` (5) realizations per instance via
5
+ ``Epochs(count=5, reducer="mean")``, so the per-scene reduced ``task_success`` is
6
+ the methodology's instance success probability P̂[Yᵢ=1]. With ``K_INSTANCES`` (5)
7
+ instances per task that is 5 scenes x 5 epochs per task.
8
+
9
+ Each task is registered with Inspect Robots under ``kitchenbench/<key>`` (the slash
10
+ namespaces KitchenBench within WorldEvals). The entry-point name, the ``@task``
11
+ name, and the returned ``Task.name`` are all identical.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import re
17
+ from dataclasses import asdict
18
+ from typing import Any
19
+
20
+ from inspect_robots import Epochs, Scene, Target, Task, episode_length, task
21
+ from inspect_robots.rollout import derive_seed
22
+
23
+ from kitchenbench.instances import K_INSTANCES, K_REALIZATIONS, Realization
24
+ from kitchenbench.scoring import task_success
25
+ from kitchenbench.specs import SPEC_BY_KEY, TaskSpec
26
+
27
+ _SLUG_RE = re.compile(r"[^a-z0-9]+")
28
+
29
+
30
+ def _slug(text: str) -> str:
31
+ return _SLUG_RE.sub("-", text.lower()).strip("-")
32
+
33
+
34
+ def _validation_dict(spec_validation: Any) -> dict[str, Any]:
35
+ """``asdict`` a Validation, casting rating tuples to lists for clean JSON."""
36
+ return {k: (list(v) if isinstance(v, tuple) else v) for k, v in asdict(spec_validation).items()}
37
+
38
+
39
+ def build_scenes(spec: TaskSpec) -> list[Scene]:
40
+ """Build one Scene per task instance (5 per task)."""
41
+ scenes: list[Scene] = []
42
+ for index, inst in enumerate(spec.instances):
43
+ # The displayed instruction is the realization of epoch 0 under the default
44
+ # eval(seed=0), so it equals the first actual rollout's instruction.
45
+ canonical = inst.realize(derive_seed(0, index, 0))
46
+ scenes.append(
47
+ Scene(
48
+ id=_slug(inst.instance_id),
49
+ instruction=canonical.instruction,
50
+ target=Target(kind=inst.target_kind, spec=dict(inst.static)),
51
+ init_seed=index,
52
+ metadata={
53
+ "benchmark": "kitchenbench",
54
+ "task": spec.key,
55
+ "category": spec.category,
56
+ "bimanual": spec.bimanual,
57
+ "version": spec.version,
58
+ "instance_id": inst.instance_id,
59
+ "instance_index": index,
60
+ "setup": inst.setup_spec(),
61
+ "language_vars": list(inst.language_vars),
62
+ "validation": _validation_dict(inst.validation),
63
+ },
64
+ )
65
+ )
66
+ return scenes
67
+
68
+
69
+ def realize_scene(scene: Scene, seed: int | None) -> Realization:
70
+ """Recover the task instance behind a Scene and realize it for ``seed``.
71
+
72
+ The seam a real embodiment / operator tool uses to get the concrete setup for
73
+ a given realization. Recovery is by ``instance_id`` (stable across releases),
74
+ not by position — a scene logged under an older task set either resolves to
75
+ the same instance or fails loudly, never silently realizes a different one.
76
+ ``seed=None`` (direct ``reset(scene)`` calls) is guarded to ``0`` for
77
+ determinism.
78
+ """
79
+ key = str(scene.metadata["task"])
80
+ instance_id = str(scene.metadata["instance_id"])
81
+ for inst in SPEC_BY_KEY[key].instances:
82
+ if inst.instance_id == instance_id:
83
+ return inst.realize(seed if seed is not None else 0)
84
+ raise LookupError(f"no instance {instance_id!r} in task {key!r} (removed or renamed?)")
85
+
86
+
87
+ def make_task(spec: TaskSpec) -> Task:
88
+ """Assemble a Inspect Robots :class:`~inspect_robots.Task` from a :class:`TaskSpec`."""
89
+ return Task(
90
+ name=f"kitchenbench/{spec.key}",
91
+ scenes=build_scenes(spec),
92
+ scorer=[task_success(), episode_length()],
93
+ max_steps=spec.max_steps,
94
+ epochs=Epochs(count=K_REALIZATIONS, reducer="mean"),
95
+ metadata={
96
+ "title": spec.title,
97
+ "category": spec.category,
98
+ "bimanual": spec.bimanual,
99
+ "version": spec.version,
100
+ "description": spec.description,
101
+ "k_instances": K_INSTANCES,
102
+ "k_realizations": K_REALIZATIONS,
103
+ },
104
+ )
105
+
106
+
107
+ @task("kitchenbench/place_cutlery")
108
+ def place_cutlery() -> Task:
109
+ return make_task(SPEC_BY_KEY["place_cutlery"])
110
+
111
+
112
+ @task("kitchenbench/stack")
113
+ def stack() -> Task:
114
+ return make_task(SPEC_BY_KEY["stack"])
115
+
116
+
117
+ @task("kitchenbench/place_in_rack")
118
+ def place_in_rack() -> Task:
119
+ return make_task(SPEC_BY_KEY["place_in_rack"])
120
+
121
+
122
+ @task("kitchenbench/pour_pasta")
123
+ def pour_pasta() -> Task:
124
+ return make_task(SPEC_BY_KEY["pour_pasta"])
125
+
126
+
127
+ @task("kitchenbench/open_container")
128
+ def open_container() -> Task:
129
+ return make_task(SPEC_BY_KEY["open_container"])
130
+
131
+
132
+ @task("kitchenbench/fold_cloth")
133
+ def fold_cloth() -> Task:
134
+ return make_task(SPEC_BY_KEY["fold_cloth"])
135
+
136
+
137
+ @task("kitchenbench/seal_container")
138
+ def seal_container() -> Task:
139
+ return make_task(SPEC_BY_KEY["seal_container"])
140
+
141
+
142
+ @task("kitchenbench/handoff")
143
+ def handoff() -> Task:
144
+ return make_task(SPEC_BY_KEY["handoff"])
145
+
146
+
147
+ @task("kitchenbench/sort_cutlery")
148
+ def sort_cutlery() -> Task:
149
+ return make_task(SPEC_BY_KEY["sort_cutlery"])
150
+
151
+
152
+ @task("kitchenbench/scoop_pasta")
153
+ def scoop_pasta() -> Task:
154
+ return make_task(SPEC_BY_KEY["scoop_pasta"])
155
+
156
+
157
+ #: All task factories, keyed by their bare key (used by ``__init__`` + tests).
158
+ TASK_FACTORIES = {
159
+ "place_cutlery": place_cutlery,
160
+ "stack": stack,
161
+ "place_in_rack": place_in_rack,
162
+ "pour_pasta": pour_pasta,
163
+ "open_container": open_container,
164
+ "fold_cloth": fold_cloth,
165
+ "seal_container": seal_container,
166
+ "handoff": handoff,
167
+ "sort_cutlery": sort_cutlery,
168
+ "scoop_pasta": scoop_pasta,
169
+ }
@@ -0,0 +1,273 @@
1
+ Metadata-Version: 2.4
2
+ Name: kitchenbench
3
+ Version: 0.3.0
4
+ Summary: A bimanual kitchen-manipulation benchmark for VLA models, built on Inspect Robots.
5
+ Project-URL: Homepage, https://github.com/robocurve/kitchenbench
6
+ Project-URL: Collection, https://github.com/robocurve/worldevals
7
+ Project-URL: Framework, https://github.com/robocurve/inspect-robots
8
+ Author: RoboCurve
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: benchmark,bimanual,kitchen,manipulation,robotics,vla
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Classifier: Typing :: Typed
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: inspect-robots>=0.3
20
+ Requires-Dist: numpy>=1.24
21
+ Provides-Extra: dev
22
+ Requires-Dist: mypy>=1.11; extra == 'dev'
23
+ Requires-Dist: pre-commit>=3.5; extra == 'dev'
24
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
25
+ Requires-Dist: pytest>=8.0; extra == 'dev'
26
+ Requires-Dist: ruff>=0.6; extra == 'dev'
27
+ Description-Content-Type: text/markdown
28
+
29
+ <div align="center">
30
+
31
+ # 🍳 KitchenBench
32
+
33
+ **A bimanual kitchen-manipulation benchmark for VLA models.**
34
+
35
+ Built on [Inspect Robots](https://github.com/robocurve/inspect-robots) · part of
36
+ [WorldEvals](https://github.com/robocurve/worldevals), the "Inspect Evals for robotics".
37
+
38
+ [![CI](https://github.com/robocurve/kitchenbench/actions/workflows/ci.yml/badge.svg)](https://github.com/robocurve/kitchenbench/actions/workflows/ci.yml)
39
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
40
+ [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)](https://github.com/robocurve/kitchenbench/actions/workflows/ci.yml)
41
+ [![Built on Inspect Robots](https://img.shields.io/badge/built%20on-Inspect%20Robots-indigo)](https://github.com/robocurve/inspect-robots)
42
+
43
+ </div>
44
+
45
+ KitchenBench is **10 kitchen-manipulation tasks** expressed as Inspect Robots `Task`s —
46
+ embodiment-agnostic, so you run them against *any* compatible policy/embodiment.
47
+ The set emphasizes **bimanual coordination**: pouring, lid removal, folding,
48
+ part-mating, a pure two-arm handover, and tool-mediated scooping, alongside
49
+ classic pick-place / stacking / slotted insertion and a multi-instance sort.
50
+
51
+ It ships a **dependency-free mock kitchen** so the whole suite runs in CI, and is
52
+ designed to point straight at real hardware — e.g. **YAM bimanual arms** driven by
53
+ **MolmoAct2**.
54
+
55
+ ## The tasks
56
+
57
+ | Task (`--task`) | Goal | Bimanual | Category |
58
+ |---|---|:--:|---|
59
+ | `kitchenbench/place_cutlery` | place the {cutlery} on the {dishware} | | pick-place |
60
+ | `kitchenbench/stack` | stack the cups / bowls / plates | | stacking |
61
+ | `kitchenbench/place_in_rack` | place the {dishware} into the dish rack | | insertion |
62
+ | `kitchenbench/pour_pasta` | pour the dry pasta into the {vessel} | ✅ | granular |
63
+ | `kitchenbench/open_container` | open the {container} | ✅ | articulated |
64
+ | `kitchenbench/fold_cloth` | fold the {cloth} | ✅ | deformable |
65
+ | `kitchenbench/seal_container` | seal the {container} with its lid | ✅ | mating |
66
+ | `kitchenbench/handoff` | hand off the {item} from one arm to the other | ✅ | coordination |
67
+ | `kitchenbench/sort_cutlery` | sort the cutlery into the correct tray compartments | | classification |
68
+ | `kitchenbench/scoop_pasta` | scoop the {pasta} with the {tool} and transfer it to the container | ✅ | granular+tool |
69
+
70
+ ## Task instances & realizations
71
+
72
+ KitchenBench follows the
73
+ [physical-automation methodology](https://github.com/jeqcho/physical-automation-methodology-docs).
74
+ The key ideas, top-down:
75
+
76
+ - A **task** (e.g. `pour_pasta`) is a set of **task instances**.
77
+ - A **task instance** is one concrete *scenario written as a distribution*: a
78
+ **stochastic setup** (named random variables, each with a distribution) plus a
79
+ **goal** (a natural-language success criterion that may reference the sampled
80
+ variables). It is *not* a single fixed scene — it is a recipe for generating many.
81
+ - A **realization** is one sample of that recipe: draw every random variable from
82
+ its distribution to get one concrete environment (and a concrete goal sentence).
83
+ - Running a `(policy, embodiment)` pair on `K_realizations` realizations and
84
+ averaging the binary successes estimates the **instance success probability**
85
+ P̂[Yᵢ = 1].
86
+
87
+ ```
88
+ task pour_pasta
89
+ ├─ instance 1 (a distribution) ──realize──▶ 5 concrete environments ──▶ P̂₁
90
+ ├─ instance 2 (a distribution) ──realize──▶ 5 concrete environments ──▶ P̂₂
91
+ │ … 5 instances total …
92
+ └─ instance 5 (a distribution) ──realize──▶ 5 concrete environments ──▶ P̂₅
93
+ ```
94
+
95
+ KitchenBench uses the methodology's recommended defaults: **5 instances per task**
96
+ (`K_INSTANCES`) and **5 realizations per instance** (`K_REALIZATIONS`).
97
+
98
+ ### A worked example
99
+
100
+ This is one of `pour_pasta`'s five instances (from
101
+ [`specs.py`](src/kitchenbench/specs.py), lightly reformatted):
102
+
103
+ ```python
104
+ TaskInstance(
105
+ instance_id="pour_pasta/measuring-cup-to-bowl",
106
+ goal="pour the dry pasta into the {vessel}", # {vessel} is sampled
107
+ setup={
108
+ "vessel": Categorical(("bowl", "cup", "pot")),
109
+ "fill_g": Uniform(80, 200), # grams of pasta
110
+ "pour_height_cm": Uniform(8, 15),
111
+ "vessel_x_cm": Normal(0.0, 3.0), # placement jitter (cm)
112
+ "vessel_y_cm": Normal(0.0, 3.0),
113
+ },
114
+ language_vars=("vessel",),
115
+ target_kind="pour_into",
116
+ static={"substance": "dry_pasta"},
117
+ )
118
+ ```
119
+
120
+ **Realizing it** with different seeds samples those distributions into concrete
121
+ environments an operator can physically arrange (and a goal to give the VLA)
122
+ (numbers rounded here for readability):
123
+
124
+ ```
125
+ realize(seed=0) realize(seed=2)
126
+ Goal: pour the dry pasta into the bowl Goal: pour the dry pasta into the cup
127
+ Setup: Setup:
128
+ vessel = bowl vessel = cup
129
+ fill_g = 156 fill_g = 111
130
+ pour_height_cm = 9.9 pour_height_cm = 10.1
131
+ vessel_x_cm = +0.3 vessel_x_cm = -7.3
132
+ vessel_y_cm = -1.6 vessel_y_cm = +5.4
133
+ ```
134
+
135
+ Inspect and realize instances from Python:
136
+
137
+ ```python
138
+ from kitchenbench import SPEC_BY_KEY
139
+
140
+ inst = SPEC_BY_KEY["pour_pasta"].instances[0]
141
+ inst.setup_spec()
142
+ # {'fill_g': 'Uniform[80, 200]', 'pour_height_cm': 'Uniform[8, 15]',
143
+ # 'vessel': 'Categorical({bowl, cup, pot})', 'vessel_x_cm': 'N(0, 3²)', ...}
144
+
145
+ r = inst.realize(seed=0)
146
+ r.instruction # 'pour the dry pasta into the bowl'
147
+ r.values # {'vessel': 'bowl', 'fill_g': 156.43…, 'pour_height_cm': 9.88…, …} (JSON-native)
148
+ r.setup_lines # ('fill_g = 156.43…', 'pour_height_cm = 9.88…', 'vessel = bowl', …)
149
+ ```
150
+
151
+ ### How it maps to a run
152
+
153
+ Each instance becomes one Inspect Robots `Scene`; the 5 realizations are the 5 **epochs**
154
+ (`Epochs(count=5, reducer="mean")`), each seeded independently. Because the reducer
155
+ is the mean, **each scene's reduced `task_success` is the instance success
156
+ probability P̂[Yᵢ = 1]** — exactly the methodology's estimator:
157
+
158
+ ```python
159
+ from inspect_robots import eval
160
+ (log,) = eval("kitchenbench/pour_pasta", "kitchen_scripted", "kitchen")
161
+ for s in log.samples:
162
+ print(s.scene_id, s.reduced["task_success"]) # one P̂ per instance
163
+ ```
164
+
165
+ On real hardware an embodiment (or operator tool) calls `realize_scene(scene,
166
+ seed)` to get the concrete setup to arrange — `Realization.setup_lines` is the
167
+ "arrange this" checklist, and `Realization.instruction` is the goal fed to the VLA.
168
+
169
+ **Distribution types** (in [`distributions.py`](src/kitchenbench/distributions.py)):
170
+ `Uniform(a, b)` continuous · `Categorical((…), weights=None)` over a finite set ·
171
+ `Normal(μ, σ)` Gaussian · `Constant(v)` fixed. Every sample is a builtin
172
+ `float`/`int`/`str` (JSON-native), and `Categorical` preserves value types (an `int`
173
+ category samples back as an `int`).
174
+
175
+ > **Validation status — read before trusting the numbers.** The shipped instances
176
+ > are **AI-authored drafts** (`Validation(source="opus-draft")`, `validated=False`).
177
+ > The methodology's `K_i = 5` is the count *after* human validation — 3 experts
178
+ > rating each instance on representativeness **and** quality, accepted only if both
179
+ > are ≥ 4. Run that commissioning pipeline before relying on the instances; we do
180
+ > **not** fabricate ratings. Also note `eval()`'s task-level
181
+ > `metrics["task_success"]` is the *mean of P̂ over instances* — a convenience
182
+ > aggregate, **not** a methodology output (the methodology sorts the per-instance P̂
183
+ > into quantiles and fits the pTQ / automation-halvings curves).
184
+
185
+ ## Install
186
+
187
+ ```bash
188
+ # Inspect Robots isn't on PyPI yet, so install both from GitHub (uv recommended):
189
+ uv pip install "inspect-robots @ git+https://github.com/robocurve/inspect-robots@v0.3.0"
190
+ uv pip install "kitchenbench @ git+https://github.com/robocurve/kitchenbench"
191
+ ```
192
+
193
+ ## Run it (mock kitchen, no hardware)
194
+
195
+ KitchenBench registers a dependency-free mock embodiment (`kitchen`) and policies
196
+ (`kitchen_scripted` / `kitchen_random` / `kitchen_noop`) via entry points:
197
+
198
+ ```bash
199
+ inspect-robots list tasks # see all kitchenbench/* tasks
200
+ inspect-robots run --task kitchenbench/pour_pasta --policy kitchen_scripted --embodiment kitchen
201
+ ```
202
+
203
+ Or in Python:
204
+
205
+ ```python
206
+ from inspect_robots import eval
207
+
208
+ (log,) = eval("kitchenbench/open_container", "kitchen_scripted", "kitchen")
209
+ # Per-instance success probability P̂[Yᵢ=1] lives in each sample's reduced score:
210
+ for s in log.samples:
211
+ print(s.scene_id, s.reduced["task_success"])
212
+ # log.results.metrics["task_success"] is the mean of P̂ over instances — a
213
+ # convenience aggregate, NOT a methodology quantity (the methodology sorts P̂ into
214
+ # quantiles and fits pTQ / automation-halvings; out of scope here).
215
+ ```
216
+
217
+ The mock is abstract (it models *progress toward the scene goal*, like Inspect Robots's
218
+ `CubePick`) — its job is to exercise the pipeline and give you a template. **In the
219
+ mock, success depends only on the seeded goal direction, so the sampled setup
220
+ distributions have no causal effect** (P̂ is degenerately 1.0 for the scripted
221
+ oracle); the distribution *content* only bites on a real embodiment. The **value is
222
+ the task definitions**, which run unchanged on a real robot.
223
+
224
+ ## Run it on real hardware (YAM arms + MolmoAct2)
225
+
226
+ KitchenBench tasks are embodiment-agnostic. To evaluate on real **YAM bimanual
227
+ arms** with **MolmoAct2**, provide two Inspect Robots components (e.g. in your own
228
+ adapter package such as `robocurve/embodiments`):
229
+
230
+ - a **`Policy`** wrapping MolmoAct2: `act(observation) -> ActionChunk` (the
231
+ scene's `instruction` is fed to the VLA verbatim);
232
+ - an **`Embodiment`** for the YAM arms: `reset`/`step`/`close`, declaring its
233
+ action space (e.g. two 7-DoF arms + grippers) and cameras. Because there is no
234
+ privileged success oracle, the embodiment should turn the **operator's
235
+ confirmation** at episode end into `StepResult(terminated=True,
236
+ termination_reason="success")` (or set `record.operator_judgement`) —
237
+ KitchenBench's `task_success` scorer reads either. Declare the `"self_paced"`
238
+ capability and pace the control loop inside `step()`.
239
+
240
+ ```bash
241
+ inspect-robots run --task kitchenbench/pour_pasta --policy molmoact2 --embodiment yam_arms
242
+ ```
243
+
244
+ Inspect Robots checks `(policy, embodiment)` compatibility (action dims, semantics,
245
+ camera/state keys) before any motion and writes an immutable `EvalLog`.
246
+
247
+ ## Development
248
+
249
+ ```bash
250
+ uv venv && uv pip install -e ".[dev]" # inspect_robots resolved from the v0.3.0 tag
251
+ uv run pre-commit install
252
+ uv run pytest --cov # 100% coverage required
253
+ uv run ruff check . && uv run mypy
254
+ ```
255
+
256
+ ## Citation
257
+
258
+ If you use KitchenBench in your research, please cite it:
259
+
260
+ ```bibtex
261
+ @software{kitchenbench,
262
+ author = {Robocurve},
263
+ title = {KitchenBench: A bimanual kitchen-manipulation benchmark for VLA models},
264
+ year = {2026},
265
+ url = {https://github.com/robocurve/kitchenbench},
266
+ version = {0.3.0},
267
+ license = {MIT}
268
+ }
269
+ ```
270
+
271
+ ## License
272
+
273
+ [MIT](LICENSE)
@@ -0,0 +1,15 @@
1
+ kitchenbench/CLAUDE.md,sha256=m0osDadTTON6oxz4TojcB7678wYLOYEKl29YpChkjYw,4891
2
+ kitchenbench/__init__.py,sha256=AVrD5TzUPYAC4ZRcSS03fM9KbGQftlWAsNLCFlhHL-Q,2166
3
+ kitchenbench/distributions.py,sha256=GFcOTgdqnSUWLGEhegtNo_dlmjpYRx1yHVTLThL_Mt8,3992
4
+ kitchenbench/embodiment.py,sha256=zLVlFRrNAFnN8_1ethQsR_KzVejbZFK1f5DP-k6AoJQ,5327
5
+ kitchenbench/instances.py,sha256=tYyuyG3Dqwmiv4o-KLYxqw71AVd23jIKW7Tox_TSnn0,3352
6
+ kitchenbench/policies.py,sha256=ecA8R8ITDX8Rio9Fl7lx6I-YvERjqohFli-rUXhI4ZQ,3398
7
+ kitchenbench/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ kitchenbench/scoring.py,sha256=qvBjN1HYII9Zer_JMTjaOMDVqOE-H6THAlFbTnpa6U8,1454
9
+ kitchenbench/specs.py,sha256=iZmQPGvpmOsFBkEHtclZYYu4w1dJLueovQRqQtfxXhA,22984
10
+ kitchenbench/tasks.py,sha256=JdeQ00aMn7zbjlFs52yg-yRGkoKdyueeNVrgVtHGXWk,5833
11
+ kitchenbench-0.3.0.dist-info/METADATA,sha256=EMptRr_HscTknBdjDZKmwKZ4knVxdP2sY7yVXlPtG-o,12294
12
+ kitchenbench-0.3.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
13
+ kitchenbench-0.3.0.dist-info/entry_points.txt,sha256=g2yDnRT9agBRkx_3P28FbkrI8mp77UuyvNV-S_0fJfU,887
14
+ kitchenbench-0.3.0.dist-info/licenses/LICENSE,sha256=NaimrZjfDyMR93d5rbHzWsYQ4UrnVsxgIXZui2UHFjU,1066
15
+ kitchenbench-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,19 @@
1
+ [inspect_robots.embodiments]
2
+ kitchen = kitchenbench.embodiment:KitchenEmbodiment
3
+
4
+ [inspect_robots.policies]
5
+ kitchen_noop = kitchenbench.policies:NoopKitchenPolicy
6
+ kitchen_random = kitchenbench.policies:RandomKitchenPolicy
7
+ kitchen_scripted = kitchenbench.policies:ScriptedKitchenPolicy
8
+
9
+ [inspect_robots.tasks]
10
+ kitchenbench/fold_cloth = kitchenbench.tasks:fold_cloth
11
+ kitchenbench/handoff = kitchenbench.tasks:handoff
12
+ kitchenbench/open_container = kitchenbench.tasks:open_container
13
+ kitchenbench/place_cutlery = kitchenbench.tasks:place_cutlery
14
+ kitchenbench/place_in_rack = kitchenbench.tasks:place_in_rack
15
+ kitchenbench/pour_pasta = kitchenbench.tasks:pour_pasta
16
+ kitchenbench/scoop_pasta = kitchenbench.tasks:scoop_pasta
17
+ kitchenbench/seal_container = kitchenbench.tasks:seal_container
18
+ kitchenbench/sort_cutlery = kitchenbench.tasks:sort_cutlery
19
+ kitchenbench/stack = kitchenbench.tasks:stack
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 robocurve
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.