From 00c9c6396fec86ccbba2d14930a016772ddba365 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 20 May 2026 16:45:40 +0000 Subject: [PATCH 1/2] feat(cli): show remediation instance names Co-authored-by: Blaine Kasten --- .../api/beta/clusters/remediations/list.py | 8 +++++- tests/cli/test_beta_clusters.py | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/together/lib/cli/api/beta/clusters/remediations/list.py b/src/together/lib/cli/api/beta/clusters/remediations/list.py index 22c70231..2c976570 100644 --- a/src/together/lib/cli/api/beta/clusters/remediations/list.py +++ b/src/together/lib/cli/api/beta/clusters/remediations/list.py @@ -44,7 +44,7 @@ async def list( for remediation in response.remediations: table.add_row( format_datetime(remediation.create_time) if remediation.create_time else "-", - remediation.instance_id, + _format_instance(remediation.instance_id, remediation.instance_name), remediation.mode.replace("REMEDIATION_MODE_", ""), _colorize(remediation.state), remediation.id, @@ -71,3 +71,9 @@ def _colorize(state: str) -> str: } color = state_colors[state] if state in state_colors else "white" return f"[{color}]{state}[/{color}]" + + +def _format_instance(instance_id: str, instance_name: str | None) -> str: + if not instance_name: + return instance_id + return f"{instance_name} ({instance_id})" diff --git a/tests/cli/test_beta_clusters.py b/tests/cli/test_beta_clusters.py index 1e204c49..0476c47a 100644 --- a/tests/cli/test_beta_clusters.py +++ b/tests/cli/test_beta_clusters.py @@ -321,6 +321,34 @@ def test_remediations_list_accepts_instance_id(self, respx_mock: MockRouter, cli assert cast(Call, route.calls[0]).request.url.path == "/compute/clusters/c1/instances/i1/remediations" assert result.exit_code == 0 + @pytest.mark.respx(base_url=base_url) + def test_remediations_list_table_uses_instance_name( + self, respx_mock: MockRouter, cli_runner: CliRunner + ) -> None: + payload = _remediation_list_body(_remediation_body(instance_name="gpu-node-a")) + respx_mock.get("/compute/clusters/c1/instances/-/remediations").mock( + return_value=httpx.Response(200, json=payload) + ) + + result = cli_runner.invoke(["beta", "clusters", "remediations", "list", "c1"]) + + assert "gpu-node-a (i1)" in result.output + assert result.exit_code == 0 + + @pytest.mark.respx(base_url=base_url) + def test_remediations_list_table_falls_back_to_instance_id( + self, respx_mock: MockRouter, cli_runner: CliRunner + ) -> None: + payload = _remediation_list_body(_remediation_body()) + respx_mock.get("/compute/clusters/c1/instances/-/remediations").mock( + return_value=httpx.Response(200, json=payload) + ) + + result = cli_runner.invoke(["beta", "clusters", "remediations", "list", "c1"]) + + assert "i1" in result.output + assert result.exit_code == 0 + @pytest.mark.respx(base_url=base_url) def test_remediations_retrieve_resolves_cluster_and_instance( self, respx_mock: MockRouter, cli_runner: CliRunner From f0cf15871c317dc8400567732f3a13e387ddb0f7 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 20 May 2026 17:02:08 +0000 Subject: [PATCH 2/2] Run formatter on remediation CLI changes Co-authored-by: Blaine Kasten --- src/together/lib/cli/api/beta/clusters/remediations/list.py | 4 +++- tests/cli/test_beta_clusters.py | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/together/lib/cli/api/beta/clusters/remediations/list.py b/src/together/lib/cli/api/beta/clusters/remediations/list.py index 58db1430..a25618b7 100644 --- a/src/together/lib/cli/api/beta/clusters/remediations/list.py +++ b/src/together/lib/cli/api/beta/clusters/remediations/list.py @@ -26,7 +26,9 @@ Parameter(help="Filter by remediation mode. Can be used multiple times."), ] RemediationStateParameter = Annotated[ - Optional[list[Literal["PENDING_APPROVAL", "PENDING", "RUNNING", "SUCCEEDED", "FAILED", "CANCELLED", "AUTO_RESOLVED"]]], + Optional[ + list[Literal["PENDING_APPROVAL", "PENDING", "RUNNING", "SUCCEEDED", "FAILED", "CANCELLED", "AUTO_RESOLVED"]] + ], Parameter(help="Filter by remediation state. Can be used multiple times."), ] RemediationTriggerParameter = Annotated[ diff --git a/tests/cli/test_beta_clusters.py b/tests/cli/test_beta_clusters.py index 5c73628c..ead92334 100644 --- a/tests/cli/test_beta_clusters.py +++ b/tests/cli/test_beta_clusters.py @@ -322,9 +322,7 @@ def test_remediations_list_accepts_instance_id(self, respx_mock: MockRouter, cli assert result.exit_code == 0 @pytest.mark.respx(base_url=base_url) - def test_remediations_list_table_uses_instance_name( - self, respx_mock: MockRouter, cli_runner: CliRunner - ) -> None: + def test_remediations_list_table_uses_instance_name(self, respx_mock: MockRouter, cli_runner: CliRunner) -> None: payload = _remediation_list_body(_remediation_body(instance_name="gpu-node-a")) respx_mock.get("/compute/clusters/c1/instances/-/remediations").mock( return_value=httpx.Response(200, json=payload)