from __future__ import annotations
from typing import Any
import pytest
from witty_agent_server.infra.clients.base import ClientBase
from witty_agent_server.runtimes.opencode_runtime import OpenCodeRuntime
class _RecordingClient(ClientBase):
"""记录所有调用,便于验证 OpenCodeRuntime 的转调。"""
def __init__(self) -> None:
self.calls: list[tuple[str, dict[str, Any]]] = []
self._session_map: dict[str, str] = {}
def list_agents(self) -> dict[str, Any]:
self.calls.append(("list_agents", {}))
return {"defaultId": "main", "agents": []}
def list_sessions(self, *, agent_id: str) -> dict[str, Any]:
self.calls.append(("list_sessions", {"agent_id": agent_id}))
return {"sessions": [{"id": "s1"}, {"id": "s2"}]}
def get_agent(self, *, agent_id: str) -> dict[str, Any] | None:
raise NotImplementedError
def get_skills_status(self, *, agent_id: str | None = None) -> dict[str, Any]:
raise NotImplementedError
def create_session(self, *, session_key: str) -> None:
self.calls.append(("create_session", {"session_key": session_key}))
self._session_map[session_key] = f"opencode-id-{session_key}"
def delete_session(self, *, session_key: str) -> None:
self.calls.append(("delete_session", {"session_key": session_key}))
self._session_map.pop(session_key, None)
def abort_session(self, *, session_key: str) -> None:
self.calls.append(("abort_session", {"session_key": session_key}))
def stream_turn(self, *, session_key: str, message: str):
raise NotImplementedError
@pytest.mark.parametrize(
"method, session_key",
[
("create_session", "k1"),
("delete_session", "k2"),
("abort_session", "k3"),
],
)
def test_runtime_session_ops_delegate_to_client(method: str, session_key: str) -> None:
client = _RecordingClient()
runtime = OpenCodeRuntime(client=client)
getattr(runtime, method)(session_key=session_key)
assert client.calls == [(method, {"session_key": session_key})]
def test_runtime_list_sessions_delegates_and_unwraps_sessions_list() -> None:
client = _RecordingClient()
runtime = OpenCodeRuntime(client=client)
result = runtime.list_sessions(agent_id="ignored")
assert client.calls == [("list_sessions", {"agent_id": "ignored"})]
assert result == [{"id": "s1"}, {"id": "s2"}]
def test_runtime_list_sessions_returns_empty_when_payload_missing() -> None:
class _EmptyClient(_RecordingClient):
def list_sessions(self, *, agent_id: str) -> dict[str, Any]:
return {}
client = _EmptyClient()
runtime = OpenCodeRuntime(client=client)
assert runtime.list_sessions(agent_id="x") == []
def test_runtime_without_client_raises_on_session_ops() -> None:
runtime = OpenCodeRuntime(client=None)
with pytest.raises(RuntimeError):
runtime.create_session(session_key="k")
with pytest.raises(RuntimeError):
runtime.delete_session(session_key="k")
with pytest.raises(RuntimeError):
runtime.abort_session(session_key="k")
with pytest.raises(RuntimeError):
runtime.list_sessions(agent_id="x")