Spaces:
Running
Running
File size: 1,849 Bytes
0bcd0b1 | 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 | """
OpenEnv Pydantic models for the origami RL environment.
OrigamiAction — one fold per step
OrigamiObservation — everything the LLM and Three.js viewer need
OrigamiState — server-side episode tracking
"""
from __future__ import annotations
from typing import Any, Optional
from pydantic import Field
from openenv.core.env_server.types import Action, Observation, State
class OrigamiAction(Action):
"""One fold operation sent by the client each step."""
fold_type: str = Field(
default="valley",
description="'valley' | 'mountain' | 'pleat' | 'crimp' | 'stop'",
)
fold_line: dict[str, list[float]] = Field(
default_factory=lambda: {"start": [0.0, 0.5], "end": [1.0, 0.5]},
description="{'start': [x, y], 'end': [x, y]} normalized 0-1",
)
fold_angle: float = Field(
default=180.0,
description="Fold angle in degrees, 0-180",
)
layer_select: str = Field(
default="all",
description="'all' | 'top' | 'bottom'",
)
class OrigamiObservation(Observation):
"""Everything the LLM and Three.js viewer need.
paper_state contains FOLD-compatible geometry + physics data.
metrics contains all computed quality metrics.
No render_urls — the browser renders from paper_state directly.
"""
task: dict[str, Any] = Field(default_factory=dict)
paper_state: dict[str, Any] = Field(default_factory=dict)
metrics: dict[str, Any] = Field(default_factory=dict)
fold_history: list[dict[str, Any]] = Field(default_factory=list)
error: Optional[str] = Field(default=None)
class OrigamiState(State):
"""Server-side episode tracking."""
task_name: str = Field(default="")
num_folds_applied: int = Field(default=0)
is_valid: bool = Field(default=True)
total_reward: float = Field(default=0.0)
|