|
Download docs/lifestack_env.md from s-b3/LifeStack: direct link, hf CLI and curl.
- Browser
- Download file 4.3 kB
-
https://huggingface.co/spaces/s-b3/LifeStack/resolve/main/docs/lifestack_env.md
- Command line
-
hf download hf://spaces/s-b3/LifeStack/docs/lifestack_env.md
-
curl -L -o lifestack_env.md https://huggingface.co/spaces/s-b3/LifeStack/resolve/main/docs/lifestack_env.md
4.3 kB
| # lifestack_env.py β Environment Reference | |
| `core/lifestack_env.py` β The main OpenEnv-compatible RL environment for LifeStack. | |
| --- | |
| ## Overview | |
| `LifeStackEnv` wraps the full simulation: metric cascades, world events, partial | |
| observability, route execution, milestone tracking, and reward calculation. | |
| Key classes in this file: | |
| | Class | Role | | |
| |---|---| | |
| | `LifeStackAction` | Pydantic action schema (metric_changes, resource_cost, action_type, β¦) | | |
| | `LifeStackObservation` | Pydantic observation schema (metrics, resources, step, done, reward, metadata) | | |
| | `LifeStackState` | Internal state (current_metrics, budget, task, world_state, hidden_state, β¦) | | |
| | `PartialObsFilter` | Converts full world state into the agent's partial observation | | |
| | `WorldEngine` | Fires deterministic/probabilistic ExoEvents each step | | |
| | `LifeStackEnv` | The environment itself β inherits from OpenEnv `Environment` | | |
| --- | |
| ## API | |
| ### `LifeStackEnv.__init__(seed, task, max_steps=30)` | |
| ```python | |
| env = LifeStackEnv() | |
| env = LifeStackEnv(seed=42, max_steps=50) | |
| ``` | |
| ### `LifeStackEnv.reset(...) -> LifeStackObservation` | |
| ```python | |
| obs = env.reset(task=my_task, episode_id="ep_001") | |
| ``` | |
| Parameters: | |
| - `task` β a `Task` object (from `core/task.py`). Defaults to `FlightCrisisTask()`. | |
| - `seed` β optional int for reproducibility. | |
| - `conflict` β legacy `ConflictEvent` for metric disruption on reset. | |
| - `budget` β dict with `time`, `money`, `energy` overrides. | |
| - `person` β optional `SimPerson` for personality-driven drift. | |
| ### `LifeStackEnv.step(action) -> LifeStackObservation` | |
| ```python | |
| obs = env.step(LifeStackAction(action_type="execute", target="rebook_premium")) | |
| ``` | |
| Supported `action_type` values: | |
| | Type | Effect | | |
| |---|---| | |
| | `inspect` | Reveals a hidden-state key into the observation | | |
| | `execute` | Attempts to activate a Route by `target` (route id) | | |
| | `wait` | Passes the step; triggers stress penalty after 4 consecutive waits | | |
| | `rollback` | Reverts metrics/budget to the previous step (one-time per episode) | | |
| | `plan` / `communicate` / `spend` / `delegate` | Apply `metric_changes` and `resource_cost` | | |
| ### `LifeStackEnv.render()` | |
| Prints a colour-coded terminal summary of the current state and task progress. | |
| --- | |
| ## PartialObsFilter | |
| ```python | |
| PartialObsFilter.filter(task, revealed_keys) -> dict | |
| ``` | |
| - Base: `task.visible_world` (always visible). | |
| - Keys in `revealed_keys` that exist in `task.mutable_world` β added as-is. | |
| - Keys in `revealed_keys` that exist in `task.hidden_state` β wrapped as | |
| `{"value": <val>, "source": "inspect"}` to signal the agent they came from inspect. | |
| --- | |
| ## Observation `metadata` fields | |
| ```python | |
| obs.metadata = { | |
| "world_state": dict, # partial view after filter | |
| "goal": str, | |
| "active_route": str | None, | |
| "milestones": list[str], | |
| "events": list[str], | |
| "success": bool, | |
| "failure": bool, | |
| "failure_reason": str, | |
| "routes_remaining": int, | |
| "breakdown": dict, # reward component breakdown | |
| "info": list[str], # step-level diagnostic messages | |
| } | |
| ``` | |
| Key `info` message prefixes: | |
| | Prefix | Meaning | | |
| |---|---| | |
| | `INSPECT_REVEALED:` | Key added to inspected list | | |
| | `INSPECT_REVEALED_HIDDEN:` | Key was in `hidden_state` β value included | | |
| | `INSPECT_REDUNDANT:` | Key already revealed, no-op | | |
| | `ROUTE_SUCCESS:` | Route executed and consequences applied | | |
| | `ROUTE_BLOCKED:` | Route was closed by a prior ExoEvent | | |
| | `PRECONDITIONS_FAILED:` | Route preconditions not met | | |
| | `MILESTONE_UNLOCKED:` | A milestone condition was met | | |
| | `EVENT_FIRED:` | An ExoEvent triggered this step | | |
| | `WAIT_CAP_EXCEEDED:` | 4+ consecutive waits β stress penalty applied | | |
| --- | |
| ## End Conditions | |
| | Condition | `done` | `success` | `failure` | | |
| |---|---|---|---| | |
| | `step_count >= max_steps` | β | depends | β | | |
| | All `success_conditions` met | β | β | β | | |
| | `failure_condition` met | β | β | β | | |
| | Any metric hits 0 | β | β | β | | |
| --- | |
| ## Change Log | |
| | Date | Change | | |
| |---|---| | |
| | 2026-04-23 | `PartialObsFilter.filter()` now reads `mutable_world` + `hidden_state` directly from `Task`; removed `world` param; hidden keys wrapped with `source: inspect`; `INSPECT_REVEALED_HIDDEN` info message added | | |