Spaces:
Sleeping
Sleeping
File size: 3,029 Bytes
796da7c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | # How to add a new domain
PERMANENCE's framework is domain-agnostic. Adding a new domain (e.g. cloud
ops, robotics, financial ops) is a matter of creating one new folder under
`permanence/domains/` and implementing four small pieces. You should not
need to edit any file outside that folder.
## Checklist
```
permanence/domains/<your_domain>/
βββ __init__.py # `from . import register` (4 lines)
βββ register.py # calls core.register_domain(...)
βββ actions.py # action definitions
βββ tasks.py # task templates (TaskSpec + world_state_init_fn)
βββ simulators/ # (optional) stateful sandboxes like fs.py/git.py/db.py
```
Then add your domain to the import list in `permanence/domains/__init__.py`:
```python
from . import meridian # noqa: F401
from . import devtools # noqa: F401
from . import <your_domain> # noqa: F401
```
That's it. `import permanence` will now register your domain and
`permanence.core.get_registry().summary()` will list your actions + tasks.
## What each file holds
### `__init__.py`
```python
"""<Your domain> β one-line description."""
from . import register # noqa: F401
```
### `register.py`
```python
from ...core import register_domain
from .actions import ACTIONS # dict[str, ActionDefinition]
from .tasks import TASK_TEMPLATES # dict[str, TaskTemplate]
register_domain(
name="<your_domain>",
description="<one-line summary>",
actions=ACTIONS,
task_templates=TASK_TEMPLATES,
)
```
### `actions.py`
Define `ACTIONS: Dict[str, ActionDefinition]`. Each action needs:
- `action_id` β unique string (namespace with a prefix to avoid collisions)
- `r_level_fn(world_state, params) -> int` β returns 1-5 based on world state
- `consequences` β WorldStateMutation list (empty if domain owns mutations)
See `permanence.domains.devtools.actions.ACTIONS` for a working example.
### `tasks.py`
Define `TASK_TEMPLATES: Dict[str, TaskTemplate]`. Each template bundles:
- `TaskSpec` (task_id, narrative, max_steps, success_fn)
- `ScenarioGenerator` (parameter ranges for randomization)
- `world_state_init_fn(sampled, scenario_id) -> WorldState`
See `permanence.domains.devtools.tasks.task_templates()` for the DevTools
pattern including per-episode randomization.
### `simulators/` (optional)
If your domain needs stateful sandboxes (like DevTools' fs/git/db), put
them here. Attach simulator handles to `WorldState` via optional fields
(see `WorldState.fs`, `.git`, `.db`). Keep simulators isolated: no
`subprocess`, no network, no real disk writes. Unit tests must assert this.
## Keep it clean
- **Never import from another domain.** The whole point is independence.
- **Namespace your action ids.** `fs_rm`, `git_push`, `deploy_prod` β not
`rm`, `push`, `deploy`.
- **Ship unit tests.** Isolation tests + reversibility gradient tests.
- **Add a curriculum entry.** Update `CurriculumScheduler` to recognize
your domain string (``"devtools"``, ``"meridian"``, or your new one).
|