Skip to content

bug: on_connect arg is AgentSideConnection at runtime while methods and params are different than Client #49

Description

@Nemtecl

Summary

Type Client and AgentSideConnection are not the same, while on_connect params is a Client, it is a AgentSideConnection at runtime (

conn = AgentSideConnection(
)

There is a cast forced here

https://github.com/agentclientprotocol/python-sdk/blob/main/src/acp/agent/connection.py#L64

When using Client, there are method such as create_terminal that does not return the same values nor property

I really like the move to snake case, but I think it added a lot of breaking changes, especially to load the Agent. Shouldn't this release have been a major ?

Reproduction steps

class ExampleAgent(Agent)
  #...

  @override
    def on_connect(self, conn: Client) -> None:
        self.client = conn
        # ^ this is AgentSideConnection at runtime
    terminal_handle = await client.create_terminal(...)
    print(terminal_handle.terminal_id)
    # ^ this break because terminal_handle is not `CreateTerminalResponse` with `terminal_id` but `TerminalHandle` with `id`

Also, having Client and AgentSideConnection being different type with no inheritence + AgenceSideConnection being now final make the test harder to write, especially when you need to stub AgentSideConnection

Expected result

Client and AgentSideConnection should have similar property so that the types expected at runtime are the same. I'd expect on_connect to receive an AgentSideConnection instead of Client which is a protocol

Actual result

class ExampleAgent(Agent)
  #...

  @override
    def on_connect(self, conn: Client) -> None:
        self.client = conn
        # ^ this is AgentSideConnection at runtime
    terminal_handle = await client.create_terminal(...)
    print(terminal_handle.terminal_id)
    # ^ this break because terminal_handle is not `CreateTerminalResponse` with `terminal_id` but `TerminalHandle` with `id`

Versions / environment

sdk 0.7.0, Python 3.12, macOS 15.7.3

Quick fix for now is to force cast Client into AgentSideConnection

Activity

  1. changed the title [-]bug: `on_connect` arg is `AgentSideConnection` at runtime but methods and params are different[/-] [+]bug: `on_connect` arg is `AgentSideConnection` at runtime while methods and params are different than `Client`[/+] on Dec 19, 2025
  2. benbrandt commented on Dec 19, 2025

    @benbrandt
    Member

    Small note: it is fairly common pre-1.0 to have the second slot of semver equal "major", so I think the versioning is correct here

  3. PsiACE commented on Dec 19, 2025

    @PsiACE
    Member

    I’ve shared a temporary fix in #50. I’ll try to include it in a near-term release.

  4. Nemtecl commented on Dec 21, 2025

    @Nemtecl
    ContributorAuthor

    Nice thank you 🙏 Looking forward to this future release 🚀

  5. Nemtecl commented on Dec 27, 2025

    @Nemtecl
    ContributorAuthor

    Hi @PsiACE 👋
    I saw that the PR was merged, awesome ! No rush at all, but do you have a rough estimate for when the next release with the fix might drop? Just curious for planning purposes! 😊

  6. PsiACE commented on Dec 28, 2025

    @PsiACE
    Member

    Hi @PsiACE 👋 I saw that the PR was merged, awesome ! No rush at all, but do you have a rough estimate for when the next release with the fix might drop? Just curious for planning purposes! 😊

    I'll double-check with @stdrc . He's been working on bumping the schema recently and might have a better solution.

    If we don't need #52 for now, I will release a 0.7.1 today for this fix.

  7. PsiACE commented on Dec 28, 2025

    @PsiACE
    Member

    https://github.com/agentclientprotocol/python-sdk/releases/tag/0.7.1

    A version containing #50 has been released, and the protocol schema has been upgraded to 0.10.2.

  8. stdrc commented on Dec 29, 2025

    @stdrc
    Contributor

    I feel that we should let the client.create_terminal return terminal ID, fully respect the protocol. Then provide another level of thin wrapper to implement the TerminalHandle abstraction. Does that look good to you?

  9. Nemtecl commented on Dec 29, 2025

    @Nemtecl
    ContributorAuthor

    I feel that we should let the client.create_terminal return terminal ID, fully respect the protocol. Then provide another level of thin wrapper to implement the TerminalHandle abstraction. Does that look good to you?

    I do not have any strong opinion on this ! 😄
    I'm totally fine with create_terminal strictly returning the ID like specified in the protocol

    I think ideally we should have AgentSideConnection extending Client so that we avoid casting when using on_connect, wdyt ?

  10. frostming commented on Jan 3, 2026

    @frostming
    Contributor

    I think ideally we should have AgentSideConnection extending Client so that we avoid casting when using on_connect, wdyt ?

    I hope that AgentSideConnection and ClientSideConnection are hidden from the user at runtime. And users shouldn't call properties or methods beyond the Client or Agent protocol. What do you want by casting the type? This sounds like an abstraction leakage to me.

  11. Nemtecl commented on Jan 7, 2026

    @Nemtecl
    ContributorAuthor

    Sorry if my comment was ambiguous
    What I meant by casting is that we enforce the casting from AgentSideConnection to Client here : https://github.com/agentclientprotocol/python-sdk/blob/main/src/acp/agent/connection.py#L65

    And because AgentSideConnection does not inherit from the Client Protocol, we are not 100% sure methods signatures are the same when using it, meaning that, at runtime, when you check the type of the parameters of on_connect, it's an AgentSideConnection (expected because it's what is sent but it also can lead to issues when same methods name has different signature, like what was done for create_terminal in 0.7.0)

    I would think that a way of fixing that and keeping the AgentSideConnection hidden for the users would be to avoid the casting line 65 and instead ensure signatures are the same by having AgentSideConnection extending Client, what do you think of that ?

  12. frostming commented on Jan 7, 2026

    @frostming
    Contributor

    Sorry if my comment was ambiguous
    What I meant by casting is that we enforce the casting from AgentSideConnection to Client here : https://github.com/agentclientprotocol/python-sdk/blob/main/src/acp/agent/connection.py#L65

    And because AgentSideConnection does not inherit from the Client Protocol, we are not 100% sure methods signatures are the same when using it, meaning that, at runtime, when you check the type of the parameters of on_connect, it's an AgentSideConnection (expected because it's what is sent but it also can lead to issues when same methods name has different signature, like what was done for create_terminal in 0.7.0)

    I would think that a way of fixing that and keeping the AgentSideConnection hidden for the users would be to avoid the casting line 65 and instead ensure signatures are the same by having AgentSideConnection extending Client, what do you think of that ?

    make sense, so the above fix needs to be improved

  13. frostming commented on Jan 8, 2026

    @frostming
    Contributor

    Then provide another level of thin wrapper to implement the TerminalHandle abstraction.

    I don't see how the thin wrapper should look like, because TerminalHandle holds an internal object conn from a private class AgentSideConnection, if AgentSideConnection.create_terminal strictly returns a CreateTerminalResponse, then there is no way for callers to construct the TerminalHandle themselves.

    BTW, I am aware that TerminalHandle offers some convenient helpers for managing the terminal; however, using them goes beyond the protocol, and abstraction leakage seems inevitable if we continue to rely on this class.

    Is there any real use case using TerminalHandle or should we remove it for now given there are equivalent in Client protocol for those helper methods? @stdrc @PsiACE

  14. PsiACE commented on Jan 8, 2026

    @PsiACE
    Member

    Is there any real use case using TerminalHandle or should we remove it for now given there are equivalent in Client protocol for those helper methods?

    I had some discussions with stdrc a few weeks ago, and I believe removal for now is a reliable option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions