Skip to content

feat: Refactor the API to expose less types users need to import #30

@frostming

Description

@frostming

Problem statement

Taking from the quick start example:

import asyncio
import sys
from pathlib import Path

from acp import spawn_agent_process, text_block
from acp.interfaces import Client
from acp.schema import InitializeRequest, NewSessionRequest, PromptRequest, SessionNotification


class SimpleClient(Client):
    async def requestPermission(self, params):  # pragma: no cover - minimal stub
        return {"outcome": {"outcome": "cancelled"}}

    async def sessionUpdate(self, params: SessionNotification) -> None:
        print("update:", params.sessionId, params.update)


async def main() -> None:
    script = Path("examples/echo_agent.py")
    async with spawn_agent_process(lambda _agent: SimpleClient(), sys.executable, str(script)) as (conn, _proc):
        await conn.initialize(InitializeRequest(protocolVersion=1))
        session = await conn.newSession(NewSessionRequest(cwd=str(script.parent), mcpServers=[]))
        await conn.prompt(
            PromptRequest(
                sessionId=session.sessionId,
                prompt=[text_block("Hello from spawn!")],
            )
        )

asyncio.run(main())

connection.initialize takes a single parameter with a set fields defined, and users have to import that InitializeRequest to construct it. Same as connection.newSession() method.

It can be easily changed to the following API style:

connection.initialize(protocol_version=1)

(snake_case is also preferred)

Proposed solution

While this is a breaking change, we can add a compatibility layer on such methods, something like below:

@compat_params(InitializeRequest)
async def initialize(self, protocol_version: int) -> InitializeResponse:
        return await request_model(
            self._conn,
            AGENT_METHODS["initialize"],
            InitializeRequest(protocolVersion=protocol_version),
            InitializeResponse,
        )

Alternatives considered

If it's not easy to do over the codebase, in the worst case, we can add a acp._next package with the new APIs, and export all members in acp/__init__.py with proper deprecation warnings.

Additional context

No response

Can you help build it?

  • I can contribute code or docs for this request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions