Skip to content

Commit 7a882b8

Browse files
Make ResourceSessionFactory generic over its session type (#1007)
ResourceSessionFactory.create() was typed as returning the base ResourceSession, so callers lost the concrete session type and had to cast. Parameterize the factory over a SessionT bound to ResourceSession, so a subclass like OpenCodeSessionFactory(ResourceSessionFactory[OpenCodeSession]) types create() as returning OpenCodeSession. Subclassing without a type argument stays valid and behaves as before, so existing envs are unaffected.
1 parent e3c87ee commit 7a882b8

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

envs/opencode_env/harness.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def fetch_proxy_trace(self) -> list[dict[str, Any]]:
189189
return records
190190

191191

192-
class OpenCodeSessionFactory(ResourceSessionFactory):
192+
class OpenCodeSessionFactory(ResourceSessionFactory[OpenCodeSession]):
193193
"""Produce isolated per-rollout :class:`OpenCodeSession` instances.
194194
195195
The factory owns sandbox provisioning, opencode install, config injection,

src/openenv/core/harness/__init__.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import math
1313
from abc import ABC, abstractmethod
1414
from dataclasses import dataclass, field
15-
from typing import Any, Callable, Protocol
15+
from typing import Any, Callable, Generic, Protocol, TypeVar
1616

1717
from ..client_types import StepResult
1818
from ..env_server.mcp_types import JsonRpcErrorCode, JsonRpcResponse, Tool
@@ -141,16 +141,25 @@ def close(self) -> None:
141141
"""Release session resources."""
142142

143143

144-
class ResourceSessionFactory(ABC):
145-
"""Factory for producing isolated per-rollout sessions."""
144+
SessionT = TypeVar("SessionT", bound=ResourceSession)
145+
146+
147+
class ResourceSessionFactory(ABC, Generic[SessionT]):
148+
"""Factory for producing isolated per-rollout sessions.
149+
150+
Generic over the concrete session type it creates, so a subclass such as
151+
``OpenCodeSessionFactory(ResourceSessionFactory[OpenCodeSession])`` types
152+
``create`` as returning ``OpenCodeSession``. Subclassing without a type
153+
argument stays valid and behaves as before.
154+
"""
146155

147156
@abstractmethod
148157
def create(
149158
self,
150159
task: Any,
151160
seed: int | None = None,
152161
episode_id: str | None = None,
153-
) -> ResourceSession:
162+
) -> SessionT:
154163
"""Create one isolated resource session for a rollout."""
155164

156165

0 commit comments

Comments
 (0)