From 6e700be30a343e5600d28cc8952b06d445b3a313 Mon Sep 17 00:00:00 2001 From: Wangmerlyn Date: Thu, 2 Jul 2026 08:57:52 +0000 Subject: [PATCH] fix(cli): include custom endpoint in start hints --- AGENTS.md | 2 ++ docs/guides/cli.md | 3 +++ src/keep_gpu/cli.py | 22 +++++++++++++++++++--- tests/test_cli_service_commands.py | 20 ++++++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 9ec3363..0ee8ea1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -256,6 +256,8 @@ This file defines how coding agents should work in this repository. before service RPC, daemon auto-start, stop-all fallback, or daemon ownership operations. JSON-output commands must return structured `{"error": "..."}` objects for invalid endpoints, not tracebacks. +- `keep-gpu start` follow-up status/stop/service-stop hints must target the + selected service endpoint while keeping default-endpoint hints concise. - Shared public endpoint validation belongs in `src/keep_gpu/utilities/endpoint_validation.py`; CLI and MCP entry points should only translate those `ValueError`s into their interface-specific error diff --git a/docs/guides/cli.md b/docs/guides/cli.md index 878d446..495bbfc 100644 --- a/docs/guides/cli.md +++ b/docs/guides/cli.md @@ -28,6 +28,9 @@ keep-gpu start --gpu-ids 0 --vram 1GiB --interval 60 --busy-threshold 25 - follow-up status/stop command hints, - daemon shutdown hint (`keep-gpu service-stop`). +When `--host` or `--port` selects a non-default endpoint, the printed +status/stop/service-stop hints include the same endpoint flags. + If this invocation auto-starts the service but session creation fails with an expected startup-unavailable error before a session is created, `start` best-effort stops the just-created daemon so it does not remain idle. diff --git a/src/keep_gpu/cli.py b/src/keep_gpu/cli.py index 11a6806..cb0e07a 100644 --- a/src/keep_gpu/cli.py +++ b/src/keep_gpu/cli.py @@ -135,6 +135,17 @@ def _service_command(host: str, port: int) -> List[str]: ] +def _service_hint_args(host: str, port: int) -> List[str]: + if host == DEFAULT_SERVICE_HOST and port == DEFAULT_SERVICE_PORT: + return [] + return ["--host", host, "--port", str(port)] + + +def _keep_gpu_hint_command(command: str, host: str, port: int, *args: str) -> str: + parts = ["keep-gpu", command, *_service_hint_args(host, port), *args] + return " ".join(shlex.quote(part) for part in parts) + + def _print_machine_json(data: Dict[str, Any]) -> None: console.file.write(f"{json.dumps(data, indent=2, allow_nan=False)}\n") console.file.flush() @@ -1295,11 +1306,16 @@ def start( f"[bold green]Started keep session[/bold green] job_id={result_job_id}" ) console.print(f"[cyan]Dashboard:[/cyan] http://{host}:{port}/") - console.print( - f"[dim]Next: keep-gpu status --job-id {result_job_id} | keep-gpu stop --job-id {result_job_id}[/dim]" + status_command = _keep_gpu_hint_command( + "status", host, port, "--job-id", result_job_id + ) + stop_command = _keep_gpu_hint_command( + "stop", host, port, "--job-id", result_job_id ) + service_stop_command = _keep_gpu_hint_command("service-stop", host, port) + console.print(f"[dim]Next: {status_command} | {stop_command}[/dim]") console.print( - "[dim]When all sessions are done, stop daemon with: keep-gpu service-stop[/dim]" + f"[dim]When all sessions are done, stop daemon with: {service_stop_command}[/dim]" ) except ServiceRPCError as exc: _rollback_auto_started_service_on_startup_unavailable( diff --git a/tests/test_cli_service_commands.py b/tests/test_cli_service_commands.py index 0e276e2..30bf831 100644 --- a/tests/test_cli_service_commands.py +++ b/tests/test_cli_service_commands.py @@ -2388,6 +2388,26 @@ def fake_rpc(method, params, host, port): assert "keep-gpu service-stop" in result.output +def test_start_prints_custom_endpoint_in_follow_up_hints(monkeypatch): + monkeypatch.setattr(cli, "_ensure_service_running", lambda *args, **kwargs: True) + monkeypatch.setattr(cli, "_rpc_call", lambda *args, **kwargs: {"job_id": "job-abc"}) + + result = runner.invoke(cli.app, ["start", "--host", "localhost", "--port", "9999"]) + + normalized_output = " ".join(result.output.split()) + assert result.exit_code == 0 + assert "Dashboard: http://localhost:9999/" in normalized_output + assert ( + "keep-gpu status --host localhost --port 9999 --job-id job-abc" + in normalized_output + ) + assert ( + "keep-gpu stop --host localhost --port 9999 --job-id job-abc" + in normalized_output + ) + assert "keep-gpu service-stop --host localhost --port 9999" in normalized_output + + def test_start_rolls_back_auto_started_service_on_startup_unavailable(monkeypatch): stopped = []