From c200ae69cb0122ece7da91a566a44c27475736a2 Mon Sep 17 00:00:00 2001 From: Ishika mishra Date: Wed, 16 Sep 2026 14:37:20 +0530 Subject: [PATCH] agents: add size_slug convenience property to AgentSession MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit harness-api now persists and returns the effective sandbox size a session actually booted at (session.size_slug, e.g. "mars-2vcpu-4gb"). pydo's hosted-agents layer is hand-written and untyped — SessionsOperations.get() returns the raw JSON dict verbatim — so the field already flows through unmodified. Add a size_slug property to AgentSession / AsyncAgentSession, mirroring the existing agent_kind accessor; None when absent (no sandbox yet, or a session predating the field). Co-Authored-By: Claude Sonnet 5 Co-authored-by: Cursor --- src/pydo/agents/session.py | 10 ++++++++ src/pydo/aio/agents/session.py | 10 ++++++++ tests/agents/test_session_highlevel.py | 34 ++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/pydo/agents/session.py b/src/pydo/agents/session.py index 1130d6d7..67241931 100644 --- a/src/pydo/agents/session.py +++ b/src/pydo/agents/session.py @@ -339,6 +339,16 @@ def agent_kind(self) -> Optional[str]: get = getattr(info, "get", None) return get("agent_kind") if get else None + @property + def size_slug(self) -> Optional[str]: + """The sandbox size slug this session's sandbox actually booted at + (e.g. ``"mars-2vcpu-4gb"``), or ``None`` if unknown (a session that has + not reached a sandbox yet, or one created before this field existed). + """ + info = self.info + get = getattr(info, "get", None) + return get("size_slug") if get else None + @property def openai_session_id(self) -> Optional[str]: info = self.info diff --git a/src/pydo/aio/agents/session.py b/src/pydo/aio/agents/session.py index a54c58a7..0f3db822 100644 --- a/src/pydo/aio/agents/session.py +++ b/src/pydo/aio/agents/session.py @@ -203,6 +203,16 @@ def agent_kind(self) -> Optional[str]: get = getattr(info, "get", None) return get("agent_kind") if get else None + @property + def size_slug(self) -> Optional[str]: + """The sandbox size slug this session's sandbox actually booted at + (e.g. ``"mars-2vcpu-4gb"``), or ``None`` if unknown (a session that has + not reached a sandbox yet, or one created before this field existed). + """ + info = self.info + get = getattr(info, "get", None) + return get("size_slug") if get else None + @property def openai_session_id(self) -> Optional[str]: info = self.info diff --git a/tests/agents/test_session_highlevel.py b/tests/agents/test_session_highlevel.py index 3419a8f1..2d76c35f 100644 --- a/tests/agents/test_session_highlevel.py +++ b/tests/agents/test_session_highlevel.py @@ -231,6 +231,31 @@ def test_hitl_none_leaves_prompt_unresolved(): assert sessions.resolved == [] +# --------------------------------------------------------------------------- +# Read-model properties +# --------------------------------------------------------------------------- + + +def test_size_slug_reads_from_session_info(): + agent = AgentSession( + _FakeSessions([]), + "s1", + raw={ + "session": { + "status": "ready", + "agent_kind": "AGENT_KIND_OPENCODE", + "size_slug": "mars-2vcpu-4gb", + } + }, + ) + assert agent.size_slug == "mars-2vcpu-4gb" + + +def test_size_slug_is_none_when_absent(): + agent = AgentSession(_FakeSessions([]), "s1", raw={"session": {"status": "ready"}}) + assert agent.size_slug is None + + # --------------------------------------------------------------------------- # Lifecycle # --------------------------------------------------------------------------- @@ -339,3 +364,12 @@ async def test_async_context_manager_destroys(): async with AsyncAgentSession(sessions, "s1") as agent: assert agent.session_id == "s1" assert sessions.destroyed + + +def test_async_size_slug_reads_from_session_info(): + agent = AsyncAgentSession( + _FakeAsyncSessions([]), + "s1", + raw={"session": {"status": "ready", "size_slug": "mv-8vcpu-16gb"}}, + ) + assert agent.size_slug == "mv-8vcpu-16gb"