From d009791a3e3e6880ff4e58d8006474bef3457c5d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 18 Jul 2026 03:13:36 +0000 Subject: [PATCH 1/2] feat(cli): show fine-tune checkpoint artifact ids Co-authored-by: Blaine Kasten --- .../lib/cli/api/fine_tuning/list_checkpoints.py | 12 ++++++++++-- tests/cli/test_fine_tuning.py | 5 +++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/together/lib/cli/api/fine_tuning/list_checkpoints.py b/src/together/lib/cli/api/fine_tuning/list_checkpoints.py index fbca957ea..01990dedb 100644 --- a/src/together/lib/cli/api/fine_tuning/list_checkpoints.py +++ b/src/together/lib/cli/api/fine_tuning/list_checkpoints.py @@ -25,8 +25,10 @@ async def list_checkpoints( title="Checkpoints", empty_message=f"No checkpoints found for job {fine_tune_id}", ) - table.add_column("ID") + table.add_column("Download ID") table.add_column("Timestamp") + table.add_column("Artifact ID") + table.add_column("Revision ID") table.add_primary_column("Type") for checkpoint in checkpoints.data: @@ -35,7 +37,13 @@ async def list_checkpoints( if "intermediate" in checkpoint.checkpoint_type.lower() else fine_tune_id ) - table.add_row(name, format_timestamp(checkpoint.created_at), checkpoint.checkpoint_type) + table.add_row( + name, + format_timestamp(checkpoint.created_at), + checkpoint.object_id or "", + checkpoint.object_revision_id or "", + checkpoint.checkpoint_type, + ) console.print(table) if checkpoints.data: diff --git a/tests/cli/test_fine_tuning.py b/tests/cli/test_fine_tuning.py index 5a17a6fc1..2d9feda50 100644 --- a/tests/cli/test_fine_tuning.py +++ b/tests/cli/test_fine_tuning.py @@ -67,7 +67,10 @@ _FT_CHECKPOINT = { "checkpoint_type": "intermediate", + "checkpoint": "model", "created_at": "2024-01-01T00:00:00Z", + "object_id": "ml-checkpoint", + "object_revision_id": "rv-checkpoint", "path": "/p", "step": 5, } @@ -348,6 +351,8 @@ def test_list_checkpoints_table(self, respx_mock: MockRouter, cli_runner: CliRun result = cli_runner.invoke(["fine-tuning", "list-checkpoints", "ft-1"]) assert result.exit_code == 0 assert "ft-1:5" in result.output + assert "ml-checkpoint" in result.output + assert "rv-checkpoint" in result.output assert "intermediate" in result.output @pytest.mark.respx(base_url=base_url) From 7d765254c58f32130addefdd1551e6c6f13974bd Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 18 Jul 2026 03:15:15 +0000 Subject: [PATCH 2/2] fix(cli): keep fine-tune artifact ids copyable Co-authored-by: Blaine Kasten --- .../cli/api/fine_tuning/list_checkpoints.py | 21 +++++++++++++++---- tests/cli/test_fine_tuning.py | 4 ++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/together/lib/cli/api/fine_tuning/list_checkpoints.py b/src/together/lib/cli/api/fine_tuning/list_checkpoints.py index 01990dedb..e94555c6e 100644 --- a/src/together/lib/cli/api/fine_tuning/list_checkpoints.py +++ b/src/together/lib/cli/api/fine_tuning/list_checkpoints.py @@ -7,6 +7,12 @@ from together.lib.cli.components.list import ListTable +def _format_registry_artifact(object_id: str | None, revision_id: str | None) -> str: + if object_id and revision_id: + return f"{object_id}@{revision_id}" + return object_id or revision_id or "" + + async def list_checkpoints( fine_tune_id: str, *, @@ -27,25 +33,32 @@ async def list_checkpoints( ) table.add_column("Download ID") table.add_column("Timestamp") - table.add_column("Artifact ID") - table.add_column("Revision ID") + table.add_column("Registry Artifact", ratio=2) table.add_primary_column("Type") + registry_artifacts: list[tuple[str, str]] = [] for checkpoint in checkpoints.data: name = ( f"{fine_tune_id}:{checkpoint.step}" if "intermediate" in checkpoint.checkpoint_type.lower() else fine_tune_id ) + registry_artifact = _format_registry_artifact(checkpoint.object_id, checkpoint.object_revision_id) + if registry_artifact: + registry_artifacts.append((name, registry_artifact)) table.add_row( name, format_timestamp(checkpoint.created_at), - checkpoint.object_id or "", - checkpoint.object_revision_id or "", + registry_artifact, checkpoint.checkpoint_type, ) console.print(table) + if registry_artifacts: + console.print("\n[dim]Registry artifacts:[/dim]") + for name, registry_artifact in registry_artifacts: + console.print(f" [dim]{name}:[/dim] {registry_artifact}") + if checkpoints.data: console.print( "\n[bold dim]To download a checkpoint, use `together fine-tuning download \\[checkpoint-id]`[/bold dim]" diff --git a/tests/cli/test_fine_tuning.py b/tests/cli/test_fine_tuning.py index 2d9feda50..6653118d8 100644 --- a/tests/cli/test_fine_tuning.py +++ b/tests/cli/test_fine_tuning.py @@ -351,8 +351,8 @@ def test_list_checkpoints_table(self, respx_mock: MockRouter, cli_runner: CliRun result = cli_runner.invoke(["fine-tuning", "list-checkpoints", "ft-1"]) assert result.exit_code == 0 assert "ft-1:5" in result.output - assert "ml-checkpoint" in result.output - assert "rv-checkpoint" in result.output + assert "Registry artifacts" in result.output + assert "ml-checkpoint@rv-checkpoint" in result.output assert "intermediate" in result.output @pytest.mark.respx(base_url=base_url)