Skip to content

Commit a7aa7c3

Browse files
authored
fix: remove TerminalHandle (#56)
fix: Eliminate the usage of type casting by making Agent/Client side connection fully compatible with the protocol. Signed-off-by: Frost Ming <me@frostming.com>
1 parent 8509738 commit a7aa7c3

File tree

6 files changed

+19
-83
lines changed

6 files changed

+19
-83
lines changed

src/acp/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
Agent,
55
Client,
66
RequestError,
7-
TerminalHandle,
87
connect_to_agent,
98
run_agent,
109
)
@@ -133,7 +132,6 @@
133132
"RequestError",
134133
"Agent",
135134
"Client",
136-
"TerminalHandle",
137135
# stdio helper
138136
"stdio_streams",
139137
"spawn_stdio_connection",

src/acp/agent/connection.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
WriteTextFileRequest,
4040
WriteTextFileResponse,
4141
)
42-
from ..terminal import TerminalHandle
4342
from ..utils import compatible_class, notify_model, param_model, request_model, request_optional_model
4443
from .router import build_agent_router
4544

@@ -50,7 +49,9 @@
5049
@final
5150
@compatible_class
5251
class AgentSideConnection:
53-
"""Agent-side connection wrapper that dispatches JSON-RPC messages to a Client implementation."""
52+
"""Agent-side connection wrapper that dispatches JSON-RPC messages to a Client implementation.
53+
The agent can use this connection to communicate with the Client so it behaves like a Client.
54+
"""
5455

5556
def __init__(
5657
self,
@@ -62,7 +63,7 @@ def __init__(
6263
use_unstable_protocol: bool = False,
6364
**connection_kwargs: Any,
6465
) -> None:
65-
agent = to_agent(cast(Client, self)) if callable(to_agent) else to_agent
66+
agent = to_agent(self) if callable(to_agent) else to_agent
6667
if not isinstance(input_stream, asyncio.StreamWriter) or not isinstance(output_stream, asyncio.StreamReader):
6768
raise TypeError(_AGENT_CONNECTION_ERROR)
6869
handler = build_agent_router(cast(Agent, agent), use_unstable_protocol=use_unstable_protocol)
@@ -141,8 +142,8 @@ async def create_terminal(
141142
env: list[EnvVariable] | None = None,
142143
output_byte_limit: int | None = None,
143144
**kwargs: Any,
144-
) -> TerminalHandle:
145-
create_response = await request_model(
145+
) -> CreateTerminalResponse:
146+
return await request_model(
146147
self._conn,
147148
CLIENT_METHODS["terminal_create"],
148149
CreateTerminalRequest(
@@ -156,7 +157,6 @@ async def create_terminal(
156157
),
157158
CreateTerminalResponse,
158159
)
159-
return TerminalHandle(create_response.terminal_id, session_id, self._conn)
160160

161161
@param_model(TerminalOutputRequest)
162162
async def terminal_output(self, session_id: str, terminal_id: str, **kwargs: Any) -> TerminalOutputResponse:
@@ -214,3 +214,7 @@ async def __aenter__(self) -> AgentSideConnection:
214214

215215
async def __aexit__(self, exc_type, exc, tb) -> None:
216216
await self.close()
217+
218+
def on_connect(self, conn: Agent) -> None:
219+
# A dummy method to match the Client protocol
220+
pass

src/acp/client/connection.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@
5050
@final
5151
@compatible_class
5252
class ClientSideConnection:
53-
"""Client-side connection wrapper that dispatches JSON-RPC messages to an Agent implementation."""
53+
"""Client-side connection wrapper that dispatches JSON-RPC messages to an Agent implementation.
54+
The client can use this connection to communicate with the Agent so it behaves like an Agent.
55+
"""
5456

5557
def __init__(
5658
self,
@@ -63,7 +65,7 @@ def __init__(
6365
) -> None:
6466
if not isinstance(input_stream, asyncio.StreamWriter) or not isinstance(output_stream, asyncio.StreamReader):
6567
raise TypeError(_CLIENT_CONNECTION_ERROR)
66-
client = to_client(cast(Agent, self)) if callable(to_client) else to_client
68+
client = to_client(self) if callable(to_client) else to_client
6769
handler = build_client_router(cast(Client, client), use_unstable_protocol=use_unstable_protocol)
6870
self._conn = Connection(handler, input_stream, output_stream, **connection_kwargs)
6971
if on_connect := getattr(client, "on_connect", None):
@@ -221,3 +223,7 @@ async def __aenter__(self) -> ClientSideConnection:
221223

222224
async def __aexit__(self, exc_type, exc, tb) -> None:
223225
await self.close()
226+
227+
def on_connect(self, conn: Client) -> None:
228+
# A dummy method to match the Agent protocol
229+
pass

src/acp/core.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from .connection import Connection, JsonValue, MethodHandler
1515
from .exceptions import RequestError
1616
from .interfaces import Agent, Client
17-
from .terminal import TerminalHandle
1817

1918
__all__ = [
2019
"Agent",
@@ -25,7 +24,6 @@
2524
"JsonValue",
2625
"MethodHandler",
2726
"RequestError",
28-
"TerminalHandle",
2927
"connect_to_agent",
3028
"run_agent",
3129
]

src/acp/interfaces.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
WriteTextFileRequest,
6666
WriteTextFileResponse,
6767
)
68-
from .terminal import TerminalHandle
6968
from .utils import param_model
7069

7170
__all__ = ["Agent", "Client"]
@@ -114,7 +113,7 @@ async def create_terminal(
114113
env: list[EnvVariable] | None = None,
115114
output_byte_limit: int | None = None,
116115
**kwargs: Any,
117-
) -> CreateTerminalResponse | TerminalHandle: ...
116+
) -> CreateTerminalResponse: ...
118117

119118
@param_model(TerminalOutputRequest)
120119
async def terminal_output(self, session_id: str, terminal_id: str, **kwargs: Any) -> TerminalOutputResponse: ...

src/acp/terminal.py

Lines changed: 0 additions & 69 deletions
This file was deleted.

0 commit comments

Comments
 (0)