Skip to content

Commit a9038dc

Browse files
committed
feat: env metadata
1 parent 4078161 commit a9038dc

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

src/core/env_server/http_server.py

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
State,
3232
StepRequest,
3333
StepResponse,
34+
EnvironmentMetadata,
3435
)
3536

3637

@@ -135,7 +136,11 @@ async def reset(
135136
if k in sig.parameters or has_kwargs:
136137
valid_kwargs[k] = v
137138

138-
observation = self.env.reset(**valid_kwargs)
139+
# Run synchronous reset in thread pool to avoid blocking event loop
140+
loop = asyncio.get_event_loop()
141+
observation = await loop.run_in_executor(
142+
self._executor, lambda: self.env.reset(**valid_kwargs)
143+
)
139144
return ResetResponse(**self._serialize_observation(observation))
140145

141146
@app.post(
@@ -217,8 +222,11 @@ async def step(request: StepRequest) -> StepResponse:
217222
if k in sig.parameters or has_kwargs:
218223
valid_kwargs[k] = v
219224

220-
# Execute step
221-
observation = self.env.step(action, **valid_kwargs)
225+
# Run synchronous step in thread pool to avoid blocking event loop
226+
loop = asyncio.get_event_loop()
227+
observation = await loop.run_in_executor(
228+
self._executor, lambda: self.env.step(action, **valid_kwargs)
229+
)
222230

223231
# Return serialized observation
224232
return StepResponse(**self._serialize_observation(observation))
@@ -239,6 +247,27 @@ async def get_state() -> State:
239247
"""State endpoint - returns current environment state."""
240248
return self.env.state
241249

250+
@app.get(
251+
"/metadata",
252+
response_model=EnvironmentMetadata,
253+
tags=["Environment Info"],
254+
summary="Get environment metadata",
255+
description="""
256+
Get metadata about this environment.
257+
258+
Returns information about the environment including name, description,
259+
version, author, and documentation links.
260+
""",
261+
)
262+
async def get_metadata() -> EnvironmentMetadata:
263+
"""
264+
Get metadata about this environment.
265+
266+
Returns information about the environment including name, description,
267+
version, author, and documentation links.
268+
"""
269+
return self.env.get_metadata()
270+
242271
@app.get(
243272
"/health",
244273
tags=["Health"],
@@ -473,6 +502,10 @@ def create_fastapi_app(
473502
"name": "State Management",
474503
"description": "Operations for inspecting environment state",
475504
},
505+
{
506+
"name": "Environment Info",
507+
"description": "Information about the environment",
508+
},
476509
{
477510
"name": "Schema",
478511
"description": "JSON Schema endpoints for actions, observations, and state",

src/core/env_server/interfaces.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from abc import ABC, abstractmethod
88
from typing import Any, Optional, Protocol, TypedDict
99

10-
from .types import Action, Observation, State
10+
from .types import Action, Observation, State, EnvironmentMetadata
1111

1212

1313
class Message(TypedDict):
@@ -121,6 +121,22 @@ def state(self) -> State:
121121
"""Get the current environment state."""
122122
pass
123123

124+
def get_metadata(self) -> EnvironmentMetadata:
125+
"""
126+
Get metadata about this environment.
127+
128+
Override this method to provide custom metadata for the environment.
129+
Default implementation returns basic metadata derived from class name.
130+
131+
Returns:
132+
EnvironmentMetadata with environment information
133+
"""
134+
return EnvironmentMetadata(
135+
name=self.__class__.__name__,
136+
description=f"{self.__class__.__name__} environment",
137+
version="1.0.0",
138+
)
139+
124140
def _apply_transform(self, observation: Observation) -> Observation:
125141
"""Apply transform if one is provided."""
126142
if self.transform is not None:

0 commit comments

Comments
 (0)