plancraft 0.1.0__tar.gz → 0.1.2__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. {plancraft-0.1.0/plancraft/plancraft.egg-info → plancraft-0.1.2}/PKG-INFO +22 -1
  2. plancraft-0.1.2/README.md +22 -0
  3. {plancraft-0.1.0 → plancraft-0.1.2/plancraft/plancraft.egg-info}/PKG-INFO +22 -1
  4. plancraft-0.1.2/plancraft/plancraft.egg-info/SOURCES.txt +13 -0
  5. {plancraft-0.1.0 → plancraft-0.1.2}/plancraft/plancraft.egg-info/requires.txt +1 -0
  6. plancraft-0.1.2/plancraft/plancraft.egg-info/top_level.txt +1 -0
  7. {plancraft-0.1.0 → plancraft-0.1.2}/pyproject.toml +4 -3
  8. plancraft-0.1.0/README.md +0 -2
  9. plancraft-0.1.0/plancraft/environments/__init__.py +0 -0
  10. plancraft-0.1.0/plancraft/environments/actions.py +0 -218
  11. plancraft-0.1.0/plancraft/environments/env_real.py +0 -315
  12. plancraft-0.1.0/plancraft/environments/env_symbolic.py +0 -215
  13. plancraft-0.1.0/plancraft/environments/items.py +0 -10
  14. plancraft-0.1.0/plancraft/environments/planner.py +0 -109
  15. plancraft-0.1.0/plancraft/environments/recipes.py +0 -542
  16. plancraft-0.1.0/plancraft/environments/sampler.py +0 -224
  17. plancraft-0.1.0/plancraft/models/__init__.py +0 -21
  18. plancraft-0.1.0/plancraft/models/act.py +0 -184
  19. plancraft-0.1.0/plancraft/models/base.py +0 -152
  20. plancraft-0.1.0/plancraft/models/bbox_model.py +0 -492
  21. plancraft-0.1.0/plancraft/models/dummy.py +0 -54
  22. plancraft-0.1.0/plancraft/models/few_shot_images/__init__.py +0 -16
  23. plancraft-0.1.0/plancraft/models/generators.py +0 -483
  24. plancraft-0.1.0/plancraft/models/oam.py +0 -284
  25. plancraft-0.1.0/plancraft/models/oracle.py +0 -268
  26. plancraft-0.1.0/plancraft/models/prompts.py +0 -158
  27. plancraft-0.1.0/plancraft/models/react.py +0 -98
  28. plancraft-0.1.0/plancraft/models/utils.py +0 -289
  29. plancraft-0.1.0/plancraft/plancraft.egg-info/SOURCES.txt +0 -34
  30. plancraft-0.1.0/plancraft/plancraft.egg-info/top_level.txt +0 -3
  31. plancraft-0.1.0/plancraft/train/dataset.py +0 -187
  32. {plancraft-0.1.0 → plancraft-0.1.2}/LICENSE +0 -0
  33. {plancraft-0.1.0 → plancraft-0.1.2}/plancraft/plancraft.egg-info/dependency_links.txt +0 -0
  34. {plancraft-0.1.0 → plancraft-0.1.2}/setup.cfg +0 -0
  35. {plancraft-0.1.0 → plancraft-0.1.2}/tests/test_planner.py +0 -0
  36. {plancraft-0.1.0 → plancraft-0.1.2}/tests/test_real_env.py +0 -0
  37. {plancraft-0.1.0 → plancraft-0.1.2}/tests/test_recipes.py +0 -0
  38. {plancraft-0.1.0 → plancraft-0.1.2}/tests/test_sampler.py +0 -0
  39. {plancraft-0.1.0 → plancraft-0.1.2}/tests/test_symbolic_env.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: plancraft
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Plancraft: an evaluation dataset for planning with LLM agents
5
5
  Requires-Python: >=3.9
6
6
  Description-Content-Type: text/markdown
@@ -20,6 +20,7 @@ Requires-Dist: imageio>=2.36.0
20
20
  Requires-Dist: inflection>=0.3.1
21
21
  Requires-Dist: ipython>=7.5.0
22
22
  Requires-Dist: jinja2>=2.11.2
23
+ Requires-Dist: loguru>=0.7.2
23
24
  Requires-Dist: lxml>=4.3.3
24
25
  Requires-Dist: matplotlib>=3.9.2
25
26
  Requires-Dist: networkx>=3.2.1
@@ -50,4 +51,24 @@ Provides-Extra: full
50
51
  Requires-Dist: gym<=0.23.1,>=0.19.0; extra == "full"
51
52
 
52
53
  # plancraft
54
+
55
+ [![Test](https://github.com/gautierdag/plancraft/actions/workflows/test.yaml/badge.svg)](https://github.com/gautierdag/plancraft/actions/workflows/test.yaml)
56
+ ![Python Version](https://img.shields.io/badge/python-3.9+-blue)
57
+ ![Ruff](https://img.shields.io/badge/linter-ruff-blue)
58
+ [![PyPI Version](https://img.shields.io/pypi/v/plancraft)](https://pypi.org/project/plancraft/)
59
+
53
60
  Plancraft is a minecraft environment and agent that innovates on planning LLM agents with a retriever
61
+
62
+ You can install the package by running the following command:
63
+
64
+ ```bash
65
+ pip install plancraft
66
+ ```
67
+
68
+ Should you need the multimodal version of the package, you will also need a custom [fork](https://github.com/gautierdag/minerl.git) of the minerl package. You can install it by running the following command:
69
+
70
+ ```bash
71
+ pip install git+hhttps://github.com/gautierdag/minerl.git
72
+ ```
73
+
74
+ Note that you may need to follow the same installation instructions as in the [minerl documentation](https://minerl.readthedocs.io/en/latest/tutorials/index.html).
@@ -0,0 +1,22 @@
1
+ # plancraft
2
+
3
+ [![Test](https://github.com/gautierdag/plancraft/actions/workflows/test.yaml/badge.svg)](https://github.com/gautierdag/plancraft/actions/workflows/test.yaml)
4
+ ![Python Version](https://img.shields.io/badge/python-3.9+-blue)
5
+ ![Ruff](https://img.shields.io/badge/linter-ruff-blue)
6
+ [![PyPI Version](https://img.shields.io/pypi/v/plancraft)](https://pypi.org/project/plancraft/)
7
+
8
+ Plancraft is a minecraft environment and agent that innovates on planning LLM agents with a retriever
9
+
10
+ You can install the package by running the following command:
11
+
12
+ ```bash
13
+ pip install plancraft
14
+ ```
15
+
16
+ Should you need the multimodal version of the package, you will also need a custom [fork](https://github.com/gautierdag/minerl.git) of the minerl package. You can install it by running the following command:
17
+
18
+ ```bash
19
+ pip install git+hhttps://github.com/gautierdag/minerl.git
20
+ ```
21
+
22
+ Note that you may need to follow the same installation instructions as in the [minerl documentation](https://minerl.readthedocs.io/en/latest/tutorials/index.html).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: plancraft
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Plancraft: an evaluation dataset for planning with LLM agents
5
5
  Requires-Python: >=3.9
6
6
  Description-Content-Type: text/markdown
@@ -20,6 +20,7 @@ Requires-Dist: imageio>=2.36.0
20
20
  Requires-Dist: inflection>=0.3.1
21
21
  Requires-Dist: ipython>=7.5.0
22
22
  Requires-Dist: jinja2>=2.11.2
23
+ Requires-Dist: loguru>=0.7.2
23
24
  Requires-Dist: lxml>=4.3.3
24
25
  Requires-Dist: matplotlib>=3.9.2
25
26
  Requires-Dist: networkx>=3.2.1
@@ -50,4 +51,24 @@ Provides-Extra: full
50
51
  Requires-Dist: gym<=0.23.1,>=0.19.0; extra == "full"
51
52
 
52
53
  # plancraft
54
+
55
+ [![Test](https://github.com/gautierdag/plancraft/actions/workflows/test.yaml/badge.svg)](https://github.com/gautierdag/plancraft/actions/workflows/test.yaml)
56
+ ![Python Version](https://img.shields.io/badge/python-3.9+-blue)
57
+ ![Ruff](https://img.shields.io/badge/linter-ruff-blue)
58
+ [![PyPI Version](https://img.shields.io/pypi/v/plancraft)](https://pypi.org/project/plancraft/)
59
+
53
60
  Plancraft is a minecraft environment and agent that innovates on planning LLM agents with a retriever
61
+
62
+ You can install the package by running the following command:
63
+
64
+ ```bash
65
+ pip install plancraft
66
+ ```
67
+
68
+ Should you need the multimodal version of the package, you will also need a custom [fork](https://github.com/gautierdag/minerl.git) of the minerl package. You can install it by running the following command:
69
+
70
+ ```bash
71
+ pip install git+hhttps://github.com/gautierdag/minerl.git
72
+ ```
73
+
74
+ Note that you may need to follow the same installation instructions as in the [minerl documentation](https://minerl.readthedocs.io/en/latest/tutorials/index.html).
@@ -0,0 +1,13 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ plancraft/plancraft.egg-info/PKG-INFO
5
+ plancraft/plancraft.egg-info/SOURCES.txt
6
+ plancraft/plancraft.egg-info/dependency_links.txt
7
+ plancraft/plancraft.egg-info/requires.txt
8
+ plancraft/plancraft.egg-info/top_level.txt
9
+ tests/test_planner.py
10
+ tests/test_real_env.py
11
+ tests/test_recipes.py
12
+ tests/test_sampler.py
13
+ tests/test_symbolic_env.py
@@ -13,6 +13,7 @@ imageio>=2.36.0
13
13
  inflection>=0.3.1
14
14
  ipython>=7.5.0
15
15
  jinja2>=2.11.2
16
+ loguru>=0.7.2
16
17
  lxml>=4.3.3
17
18
  matplotlib>=3.9.2
18
19
  networkx>=3.2.1
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plancraft"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  description = "Plancraft: an evaluation dataset for planning with LLM agents"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
@@ -20,6 +20,7 @@ dependencies = [
20
20
  "inflection>=0.3.1",
21
21
  "ipython>=7.5.0",
22
22
  "jinja2>=2.11.2",
23
+ "loguru>=0.7.2",
23
24
  "lxml>=4.3.3",
24
25
  "matplotlib>=3.9.2",
25
26
  "networkx>=3.2.1",
@@ -58,7 +59,7 @@ dev-dependencies = [
58
59
  ]
59
60
 
60
61
  [tool.setuptools.packages]
61
- find = { where = ["plancraft"]}
62
+ find = { where = ["plancraft"], include = ["plancraft*"] }
62
63
 
63
64
  [project.optional-dependencies]
64
65
  full = [
@@ -67,4 +68,4 @@ full = [
67
68
 
68
69
  [build-system]
69
70
  requires = ["setuptools"]
70
- build-backend = "setuptools.build_meta"
71
+ build-backend = "setuptools.build_meta"
plancraft-0.1.0/README.md DELETED
@@ -1,2 +0,0 @@
1
- # plancraft
2
- Plancraft is a minecraft environment and agent that innovates on planning LLM agents with a retriever
File without changes
@@ -1,218 +0,0 @@
1
- from typing import Union
2
-
3
- from pydantic import BaseModel, field_validator, model_validator
4
-
5
-
6
- def convert_to_slot_index(slot: str) -> int:
7
- slot = slot.strip()
8
- grid_map = {
9
- "[0]": 0,
10
- "[A1]": 1,
11
- "[A2]": 2,
12
- "[A3]": 3,
13
- "[B1]": 4,
14
- "[B2]": 5,
15
- "[B3]": 6,
16
- "[C1]": 7,
17
- "[C2]": 8,
18
- "[C3]": 9,
19
- }
20
- if slot in grid_map:
21
- return grid_map[slot]
22
- else:
23
- return int(slot[2:-1]) + 9
24
-
25
-
26
- def convert_from_slot_index(slot_index: int) -> str:
27
- grid_map = {
28
- 0: "[0]",
29
- 1: "[A1]",
30
- 2: "[A2]",
31
- 3: "[A3]",
32
- 4: "[B1]",
33
- 5: "[B2]",
34
- 6: "[B3]",
35
- 7: "[C1]",
36
- 8: "[C2]",
37
- 9: "[C3]",
38
- }
39
- if slot_index < 10:
40
- return grid_map[slot_index]
41
- else:
42
- return f"[I{slot_index-9}]"
43
-
44
-
45
- class SymbolicMoveAction(BaseModel):
46
- """ "Moves an item from one slot to another"""
47
-
48
- slot_from: int
49
- slot_to: int
50
- quantity: int
51
- action_type: str = "move"
52
-
53
- @field_validator("action_type", mode="before")
54
- def fix_action_type(cls, value) -> str:
55
- return "move"
56
-
57
- @field_validator("slot_from", "slot_to", mode="before")
58
- def transform_str_to_int(cls, value) -> int:
59
- # if value is a string like [A1] or [I1], convert it to an integer
60
- if isinstance(value, str):
61
- try:
62
- return convert_to_slot_index(value)
63
- except ValueError:
64
- raise AttributeError(
65
- "slot_from and slot_to must be [0] or [A1] to [C3] or [I1] to [I36]"
66
- )
67
- return value
68
-
69
- @field_validator("quantity", mode="before")
70
- def transform_quantity(cls, value) -> int:
71
- if isinstance(value, str):
72
- try:
73
- return int(value)
74
- except ValueError:
75
- raise AttributeError("quantity must be an integer")
76
- return value
77
-
78
- @model_validator(mode="after")
79
- def validate(self):
80
- if self.slot_from == self.slot_to:
81
- raise AttributeError("slot_from and slot_to must be different")
82
- if self.slot_from < 0 or self.slot_from > 45:
83
- raise AttributeError("slot_from must be between 0 and 45")
84
- if self.slot_to < 1 or self.slot_to > 45:
85
- raise AttributeError("slot_to must be between 1 and 45")
86
- if self.quantity < 1 or self.quantity > 64:
87
- raise AttributeError("quantity must be between 1 and 64")
88
-
89
- def to_action_dict(self) -> dict:
90
- return {
91
- "inventory_command": [self.slot_from, self.slot_to, self.quantity],
92
- }
93
-
94
-
95
- class SymbolicSmeltAction(BaseModel):
96
- """Smelts an item and moves the result into a new slot"""
97
-
98
- slot_from: int
99
- slot_to: int
100
- quantity: int
101
- action_type: str = "smelt"
102
-
103
- @field_validator("action_type", mode="before")
104
- def fix_action_type(cls, value) -> str:
105
- return "smelt"
106
-
107
- @field_validator("slot_from", "slot_to", mode="before")
108
- def transform_str_to_int(cls, value) -> int:
109
- # if value is a string like [A1] or [I1], convert it to an integer
110
- if isinstance(value, str):
111
- try:
112
- return convert_to_slot_index(value)
113
- except ValueError:
114
- raise AttributeError(
115
- "slot_from and slot_to must be [0] or [A1] to [C3] or [I1] to [I36]"
116
- )
117
- return value
118
-
119
- @field_validator("quantity", mode="before")
120
- def transform_quantity(cls, value) -> int:
121
- if isinstance(value, str):
122
- try:
123
- return int(value)
124
- except ValueError:
125
- raise AttributeError("quantity must be an integer")
126
- return value
127
-
128
- @model_validator(mode="after")
129
- def validate(self):
130
- if self.slot_from == self.slot_to:
131
- raise AttributeError("slot_from and slot_to must be different")
132
- if self.slot_from < 0 or self.slot_from > 45:
133
- raise AttributeError("slot_from must be between 0 and 45")
134
- if self.slot_to < 1 or self.slot_to > 45:
135
- raise AttributeError("slot_to must be between 1 and 45")
136
- if self.quantity < 1 or self.quantity > 64:
137
- raise AttributeError("quantity must be between 1 and 64")
138
-
139
- def to_action_dict(self) -> dict:
140
- return {
141
- "smelt": [self.slot_from, self.slot_to, self.quantity],
142
- }
143
-
144
-
145
- class ThinkAction(BaseModel):
146
- """Think about the answer before answering"""
147
-
148
- thought: str
149
-
150
- def to_action_dict(self) -> dict:
151
- return {}
152
-
153
-
154
- class SearchAction(BaseModel):
155
- """Searches for a relevant document in the wiki"""
156
-
157
- search_string: str
158
-
159
- def to_action_dict(self) -> dict:
160
- return {
161
- "search": self.search_string,
162
- }
163
-
164
-
165
- class RealActionInteraction(BaseModel):
166
- mouse_direction_x: float = 0
167
- mouse_direction_y: float = 0
168
- right_click: bool = False
169
- left_click: bool = False
170
-
171
- @field_validator("mouse_direction_x", "mouse_direction_y")
172
- def prevent_zero(cls, v):
173
- if v > 10:
174
- return 10
175
- elif v < -10:
176
- return -10
177
- return v
178
-
179
- def to_action_dict(self) -> dict:
180
- return {
181
- "camera": [self.mouse_direction_x, self.mouse_direction_y],
182
- "use": int(self.right_click),
183
- "attack": int(self.left_click),
184
- }
185
-
186
-
187
- class StopAction(BaseModel):
188
- """
189
- Action that model can take to stop planning - decide impossible to continue
190
- Note: also known as the "impossible" action
191
- """
192
-
193
- reason: str = ""
194
-
195
-
196
- class NoOp(SymbolicMoveAction):
197
- """No operation action - special instance of move"""
198
-
199
- def __init__(self):
200
- super().__init__(slot_from=0, slot_to=1, quantity=1)
201
- self.slot_to = 0
202
-
203
- def __call__(self, *args, **kwargs):
204
- return None
205
-
206
- def __str__(self):
207
- return "NoOp"
208
-
209
-
210
- # when symbolic action is true, can either move objects around or smelt
211
- SymbolicAction = SymbolicMoveAction # | SymbolicSmeltAction
212
-
213
- # when symbolic action is false, then need to use mouse to move things around, but can use smelt action
214
- RealAction = RealActionInteraction | SymbolicSmeltAction
215
-
216
-
217
- class PydanticSymbolicAction(BaseModel):
218
- root: Union[SymbolicMoveAction, SymbolicSmeltAction]
@@ -1,315 +0,0 @@
1
- from typing import Sequence, Union
2
-
3
- import numpy as np
4
- import json
5
-
6
-
7
- try:
8
- from minerl.env import _singleagent
9
- from minerl.herobraine.env_specs.human_controls import HumanControlEnvSpec
10
- from minerl.herobraine.hero import handlers, mc, spaces
11
- from minerl.herobraine.hero.handler import Handler
12
- from minerl.herobraine.hero.handlers.agent.action import Action
13
- from minerl.herobraine.hero.handlers.agent.start import InventoryAgentStart
14
- from minerl.herobraine.hero.handlers.translation import TranslationHandler
15
- except ImportError as e:
16
- raise ImportError(
17
- "The 'minerl' package is required to use RealPlancraft. "
18
- "Please install it using 'pip install plancraft[full]' or 'pip install minerl'."
19
- ) from e
20
-
21
-
22
- from plancraft.environments.actions import RealAction
23
-
24
-
25
- class InventoryCommandAction(Action):
26
- """
27
- Handler which lets agents programmatically interact with an open container
28
-
29
- Using this - agents can move a chosen quantity of items from one slot to another.
30
- """
31
-
32
- def to_string(self):
33
- return "inventory_command"
34
-
35
- def xml_template(self) -> str:
36
- return str("<InventoryCommands/>")
37
-
38
- def __init__(self):
39
- self._command = "inventory_command"
40
- # first argument is the slot to take from
41
- # second is the slot to put into
42
- # third is the count to take
43
- super().__init__(
44
- self.command,
45
- spaces.Tuple(
46
- (
47
- spaces.Discrete(46),
48
- spaces.Discrete(46),
49
- spaces.Discrete(64),
50
- )
51
- ),
52
- )
53
-
54
- def from_universal(self, x):
55
- return np.array([0, 0, 0], dtype=np.int32)
56
-
57
-
58
- class SmeltCommandAction(Action):
59
- """
60
- An action handler for smelting an item
61
- We assume smelting is immediate.
62
- @TODO: might be interesting to explore using the smelting time as an additional planning parameter.
63
-
64
- Using this agents can smelt items in their inventory.
65
- """
66
-
67
- def __init__(self):
68
- self._command = "smelt"
69
- # first argument is the slot to take from
70
- # second is the slot to put into
71
- # third is the count to smelt
72
- super().__init__(
73
- self.command,
74
- spaces.Tuple(
75
- (
76
- spaces.Discrete(46),
77
- spaces.Discrete(46),
78
- spaces.Discrete(64),
79
- )
80
- ),
81
- )
82
-
83
- def to_string(self):
84
- return "smelt"
85
-
86
- def xml_template(self) -> str:
87
- return str("<SmeltCommands/>")
88
-
89
- def from_universal(self, x):
90
- return np.array([0, 0, 0], dtype=np.int32)
91
-
92
-
93
- class InventoryResetAction(Action):
94
- def __init__(self):
95
- self._command = "inventory_reset"
96
- super().__init__(self._command, spaces.Text([1]))
97
-
98
- def to_string(self) -> str:
99
- return "inventory_reset"
100
-
101
- def to_hero(self, inventory_items: list[dict]):
102
- return "{} {}".format(self._command, json.dumps(inventory_items))
103
-
104
- def xml_template(self) -> str:
105
- return "<InventoryResetCommands/>"
106
-
107
- def from_universal(self, x):
108
- return []
109
-
110
-
111
- MINUTE = 20 * 60
112
-
113
-
114
- class CustomInventoryAgentStart(InventoryAgentStart):
115
- def __init__(self, inventory: list[dict[str, Union[str, int]]]):
116
- super().__init__({item["slot"]: item for item in inventory})
117
-
118
-
119
- class CraftingTableOnly(Handler):
120
- def to_string(self):
121
- return "start_with_crafting_table"
122
-
123
- def xml_template(self) -> str:
124
- return "<CraftingTableOnly>true</CraftingTableOnly>"
125
-
126
-
127
- class InventoryObservation(TranslationHandler):
128
- """
129
- Handles GUI Workbench Observations for selected items
130
- """
131
-
132
- def to_string(self):
133
- return "inventory"
134
-
135
- def xml_template(self) -> str:
136
- return str("""<ObservationFromFullInventory flat="false"/>""")
137
-
138
- def __init__(self, item_list, _other="other"):
139
- item_list = sorted(item_list)
140
- super().__init__(
141
- spaces.Dict(
142
- spaces={
143
- k: spaces.Box(
144
- low=0,
145
- high=2304,
146
- shape=(),
147
- dtype=np.int32,
148
- normalizer_scale="log",
149
- )
150
- for k in item_list
151
- }
152
- )
153
- )
154
- self.num_items = len(item_list)
155
- self.items = item_list
156
-
157
- def add_to_mission_spec(self, mission_spec):
158
- pass
159
-
160
- def from_hero(self, info):
161
- return info["inventory"]
162
-
163
- def from_universal(self, obs):
164
- raise NotImplementedError(
165
- "from_universal not implemented in InventoryObservation"
166
- )
167
-
168
-
169
- class PlancraftBaseEnvSpec(HumanControlEnvSpec):
170
- def __init__(
171
- self,
172
- symbolic_action_space=False,
173
- symbolic_observation_space=False,
174
- max_episode_steps=2 * MINUTE,
175
- inventory: Sequence[dict] = (),
176
- preferred_spawn_biome: str = "plains",
177
- resolution=[260, 180],
178
- ):
179
- self.inventory = inventory
180
- self.preferred_spawn_biome = preferred_spawn_biome
181
- self.symbolic_action_space = symbolic_action_space
182
- self.symbolic_observation_space = symbolic_observation_space
183
-
184
- mode = "real"
185
- if symbolic_action_space:
186
- mode += "-symbolic-act"
187
- else:
188
- mode += "-real-act"
189
-
190
- if symbolic_observation_space:
191
- mode += "-symbolic-obs"
192
-
193
- if symbolic_action_space:
194
- cursor_size = 1
195
- else:
196
- cursor_size = 16
197
-
198
- name = f"plancraft-{mode}-v0"
199
- super().__init__(
200
- name=name,
201
- max_episode_steps=max_episode_steps,
202
- resolution=resolution,
203
- cursor_size_range=[cursor_size, cursor_size],
204
- )
205
-
206
- def create_agent_start(self) -> list[Handler]:
207
- base_agent_start_handlers = super().create_agent_start()
208
- return base_agent_start_handlers + [
209
- CustomInventoryAgentStart(self.inventory),
210
- handlers.PreferredSpawnBiome(self.preferred_spawn_biome),
211
- handlers.DoneOnDeath(),
212
- CraftingTableOnly(),
213
- ]
214
-
215
- def create_observables(self) -> list[TranslationHandler]:
216
- if self.symbolic_observation_space:
217
- return [
218
- handlers.POVObservation(self.resolution),
219
- InventoryObservation([item["slot"] for item in self.inventory]),
220
- ]
221
- return [handlers.POVObservation(self.resolution)]
222
-
223
- def create_server_world_generators(self) -> list[Handler]:
224
- # TODO the original biome forced is not implemented yet. Use this for now.
225
- return [handlers.DefaultWorldGenerator(force_reset=True)]
226
-
227
- def create_server_quit_producers(self) -> list[Handler]:
228
- return [
229
- handlers.ServerQuitFromTimeUp((self.max_episode_steps * mc.MS_PER_STEP)),
230
- handlers.ServerQuitWhenAnyAgentFinishes(),
231
- ]
232
-
233
- def create_server_initial_conditions(self) -> list[Handler]:
234
- return [
235
- handlers.TimeInitialCondition(allow_passage_of_time=False),
236
- handlers.SpawningInitialCondition(allow_spawning=True),
237
- ]
238
-
239
- def create_actionables(self) -> list[TranslationHandler]:
240
- """
241
- Symbolic env can move items around in the inventory using function
242
- Real env can use camera/keyboard
243
- """
244
- # Camera and mouse
245
- if self.symbolic_action_space:
246
- return [
247
- InventoryCommandAction(),
248
- SmeltCommandAction(),
249
- InventoryResetAction(),
250
- ]
251
- return [handlers.KeybasedCommandAction(v, v) for k, v in mc.KEYMAP.items()] + [
252
- handlers.CameraAction(),
253
- SmeltCommandAction(),
254
- InventoryResetAction(),
255
- ]
256
-
257
- def is_from_folder(self, folder: str) -> bool:
258
- return False
259
-
260
- def create_agent_handlers(self) -> list[Handler]:
261
- return []
262
-
263
- def create_mission_handlers(self):
264
- return []
265
-
266
- def create_monitors(self):
267
- return []
268
-
269
- def create_rewardables(self):
270
- return []
271
-
272
- def create_server_decorators(self) -> list[Handler]:
273
- return []
274
-
275
- def determine_success_from_rewards(self, rewards: list) -> bool:
276
- return False
277
-
278
- def get_docstring(self):
279
- return self.__class__.__doc__
280
-
281
-
282
- class RealPlancraft(_singleagent._SingleAgentEnv):
283
- def __init__(
284
- self,
285
- inventory: list[dict],
286
- preferred_spawn_biome="plains",
287
- symbolic_action_space=False,
288
- symbolic_observation_space=True,
289
- resolution=[512, 512],
290
- crop=True,
291
- ):
292
- # NOTE: crop is only supported for resolution 512x512 (default)
293
- self.crop = crop
294
- self.resolution = resolution
295
- env_spec = PlancraftBaseEnvSpec(
296
- symbolic_action_space=symbolic_action_space,
297
- symbolic_observation_space=symbolic_observation_space,
298
- preferred_spawn_biome=preferred_spawn_biome,
299
- inventory=inventory,
300
- resolution=resolution,
301
- )
302
- super(RealPlancraft, self).__init__(env_spec=env_spec)
303
- self.reset()
304
-
305
- def step(self, action: RealAction | dict):
306
- if not isinstance(action, dict):
307
- action = action.to_action_dict()
308
- obs, rew, done, info = super().step(action)
309
- if "pov" in obs and self.crop and self.resolution == [512, 512]:
310
- # crop at position x=174, y=170 with width=164 and height=173
311
- obs["pov"] = obs["pov"][174 : 174 + 164, 170 : 168 + 173]
312
- return obs, rew, done, info
313
-
314
- def fast_reset(self, new_inventory: list[dict]):
315
- super().step({"inventory_reset": new_inventory})