From 754d73a2518a4a4eaa8ba7ac815f403d7e7e0c45 Mon Sep 17 00:00:00 2001 From: He Wang Date: Thu, 21 May 2026 18:04:46 +0800 Subject: [PATCH] fix(examples): improve gemini.py CLI experience - Support --acp flag with --experimental-acp fallback for older versions - Suppress Gemini CLI stderr noise in non-debug mode - Drain stdin before terminating subprocess for cleaner shutdown - Catch KeyboardInterrupt in main() to avoid noisy traceback Co-Authored-By: Claude Sonnet 4 --- docs/quickstart.md | 4 ++-- examples/gemini.py | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index 5e79205..79a5a0e 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -16,7 +16,7 @@ Spin up a working ACP agent/client loop in minutes. Keep this page beside the te - Python 3.10–3.14 with `pip` or `uv` - An ACP-capable client such as Zed (recommended for validation) -- Optional: the Gemini CLI (`gemini --experimental-acp`) for the bridge example +- Optional: the Gemini CLI (`gemini --acp`; use `--experimental-acp` for older versions) for the bridge example ## Step 1 — Install the SDK @@ -145,7 +145,7 @@ Run it with `run_agent()` inside an async entrypoint and wire it to your client. - [`examples/echo_agent.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/echo_agent.py) for the smallest streaming agent - [`examples/agent.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/agent.py) for an implementation that negotiates capabilities and streams richer updates - [`examples/duet.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/duet.py) to see `spawn_agent_process` in action alongside the interactive client -- [`examples/gemini.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/gemini.py) to drive the Gemini CLI (`--acp`) directly from Python +- [`examples/gemini.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/gemini.py) to drive the Gemini CLI (`--acp`; use `--experimental-acp` for older versions) directly from Python Need builders for common payloads? `acp.helpers` mirrors the Go/TS helper APIs: diff --git a/examples/gemini.py b/examples/gemini.py index bc824af..85c862f 100644 --- a/examples/gemini.py +++ b/examples/gemini.py @@ -328,7 +328,8 @@ async def run(argv: list[str]) -> int: # noqa: C901 *cmd, stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE, - stderr=None, + # Suppress Gemini CLI diagnostic noise unless debugging + stderr=None if args.debug else asyncio.subprocess.DEVNULL, ) except FileNotFoundError as exc: print(f"Failed to start Gemini CLI: {exc}", file=sys.stderr) @@ -412,6 +413,10 @@ def _print_request_error(stage: str, err: RequestError) -> None: async def _shutdown(proc: asyncio.subprocess.Process, conn: ClientSideConnection) -> None: with contextlib.suppress(Exception): await asyncio.wait_for(conn.close(), timeout=2) + if proc.stdin is not None: + with contextlib.suppress(Exception): + proc.stdin.close() + await asyncio.wait_for(proc.stdin.wait_closed(), timeout=2) if proc.returncode is None: proc.terminate() try: @@ -424,7 +429,10 @@ async def _shutdown(proc: asyncio.subprocess.Process, conn: ClientSideConnection def main(argv: list[str] | None = None) -> int: args = sys.argv if argv is None else argv - return asyncio.run(run(list(args))) + try: + return asyncio.run(run(list(args))) + except KeyboardInterrupt: + return 1 if __name__ == "__main__":