Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9a8c60e
feat(api): add cluster config/OIDC/add-ons params, project filtering,…
stainless-app[bot] May 14, 2026
2109f0a
fix(types): correct status field to enum in cluster_storage model
stainless-app[bot] May 15, 2026
0f34ea4
feat(api): add h200-140gb gpu_type to jig deploy/update methods
stainless-app[bot] May 15, 2026
899752d
fix(api): make duration_days optional in clusters create, size_tib op…
stainless-app[bot] May 15, 2026
1caa5fa
feat: Sync deployments OpenAPI spec
stainless-app[bot] May 15, 2026
8c35457
docs(api): add parameter descriptions to storage methods and types
stainless-app[bot] May 15, 2026
029c3fd
feat(api): Add node remediation APIs to clusters sdks
stainless-app[bot] May 15, 2026
b5e42a0
feat(api): manual updates
stainless-app[bot] May 15, 2026
d6310d8
fix(api): remove trigger parameter from remediations list method
stainless-app[bot] May 15, 2026
f4de411
feat(api): manual updates
stainless-app[bot] May 15, 2026
877c44f
codegen metadata
stainless-app[bot] May 15, 2026
5ea2c1f
ENG-84365 tool jig deploy image should block jig build (#330)
dulaj-me May 18, 2026
85cf77b
fix(jig): honor uv default groups in autogenerated dockerfile (#301)
dulaj-me May 18, 2026
5ae0fbc
fix(api): remove error field, make request_id required in jig queue s…
stainless-app[bot] May 18, 2026
4e3a3cf
codegen metadata
stainless-app[bot] May 19, 2026
59ba233
Add beta cluster remediation CLI commands (#369)
blainekasten May 19, 2026
47e5c89
feat(jig): copy and use uv.lock if exists on autogenerated dockerfile…
dulaj-me May 20, 2026
997deea
feat(api): add trigger param, support multiple modes in remediations …
stainless-app[bot] May 20, 2026
a2d9e59
Add fancy Metrics plot to the together-py (#344)
artek0chumak May 20, 2026
4c7fc66
feat(api): add instance_name field to remediation model
stainless-app[bot] May 20, 2026
27e6c2d
feat(api): add disable_position_bias_correction, remove num_samples f…
stainless-app[bot] May 20, 2026
bc211eb
Expose new Jig SDK parameters in CLI (#371)
cursor[bot] May 20, 2026
939e1c7
lint and fmt fixes (#376)
artek0chumak May 20, 2026
1656759
feat(cli): add remediation list filters (#372)
cursor[bot] May 20, 2026
7a1a7c2
fix(types): remove node_name from ControlPlaneNode and GPUWorkerNode
stainless-app[bot] May 20, 2026
1edd32e
Show remediation instance names in CLI (#373)
cursor[bot] May 20, 2026
acf7bc9
Fix fine-tuning metrics CLI zero filters (#374)
cursor[bot] May 20, 2026
6d3e1e1
codegen metadata
stainless-app[bot] May 20, 2026
ac8482e
feat(cli): add eval compare bias correction flag (#375)
cursor[bot] May 20, 2026
05010fe
release: 2.15.0
stainless-app[bot] May 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "2.14.0"
".": "2.15.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 75
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/togetherai/togetherai-5f05c9669c67c3f4b0ebfe2317d2768cd96317424965ebb2acf06a7757a7d0ca.yml
openapi_spec_hash: 84f45151f4d0eed68551b5ffda61595a
config_hash: ec427df08d61d8888138f15cd53c6454
configured_endpoints: 81
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/togetherai/togetherai-ce108a2095d36552bb556506de04475674f512a13bc5aa099e9750993405be14.yml
openapi_spec_hash: 4763dd426dd805306bbb38a314158cd3
config_hash: b35d5968fb07cce1c1be735f874898b1
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
# Changelog

## 2.15.0 (2026-05-20)

Full Changelog: [v2.14.0...v2.15.0](https://github.com/togethercomputer/together-py/compare/v2.14.0...v2.15.0)

### Features

* **api:** add cluster config/OIDC/add-ons params, project filtering, update storage types ([9a8c60e](https://github.com/togethercomputer/together-py/commit/9a8c60eb51daba174c0a4761612b3dd51fb5bee5))
* **api:** add disable_position_bias_correction, remove num_samples from eval compare results ([27e6c2d](https://github.com/togethercomputer/together-py/commit/27e6c2db1e2549d8b2352f73265067f0eac9b44c))
* **api:** add h200-140gb gpu_type to jig deploy/update methods ([0f34ea4](https://github.com/togethercomputer/together-py/commit/0f34ea4e1441a08b014f19d99588902b17eda1be))
* **api:** add instance_name field to remediation model ([4c7fc66](https://github.com/togethercomputer/together-py/commit/4c7fc662363054f47d5e7a01353e3f0da98d8b6a))
* **api:** Add node remediation APIs to clusters sdks ([029c3fd](https://github.com/togethercomputer/together-py/commit/029c3fd79c22f130dab4a46bc62a6e1410908da4))
* **api:** add trigger param, support multiple modes in remediations list ([997deea](https://github.com/togethercomputer/together-py/commit/997deeae7c514b0ce2dc65394d262abe9bd35766))
* **api:** manual updates ([f4de411](https://github.com/togethercomputer/together-py/commit/f4de41192250b3c609e44da6bee18309db209f35))
* **api:** manual updates ([b5e42a0](https://github.com/togethercomputer/together-py/commit/b5e42a042c367dbe14021be3c6612155ac8f6fac))
* **cli:** add eval compare bias correction flag ([#375](https://github.com/togethercomputer/together-py/issues/375)) ([ac8482e](https://github.com/togethercomputer/together-py/commit/ac8482ebbf9fdf7e67973ff36a0178ce774963cb))
* **cli:** add get as alias for retrieve subcommands ([#367](https://github.com/togethercomputer/together-py/issues/367)) ([d283d11](https://github.com/togethercomputer/together-py/commit/d283d1192b1c75ad676420be4ea30137883d55a6))
* **cli:** add remediation list filters ([#372](https://github.com/togethercomputer/together-py/issues/372)) ([1656759](https://github.com/togethercomputer/together-py/commit/16567597382f3345aff0450bcf1a257976a97139))
* **jig:** copy and use uv.lock if exists on autogenerated dockerfile ([#370](https://github.com/togethercomputer/together-py/issues/370)) ([47e5c89](https://github.com/togethercomputer/together-py/commit/47e5c891ac2272b0d20c1c266d0e3a9527448019))
* Sync deployments OpenAPI spec ([1caa5fa](https://github.com/togethercomputer/together-py/commit/1caa5fa4c41dff79164d8edd7436e66747eab712))


### Bug Fixes

* **api:** make duration_days optional in clusters create, size_tib optional in storage update ([899752d](https://github.com/togethercomputer/together-py/commit/899752dbebed9a75433b9ab95245c3bf15237eb3))
* **api:** remove error field, make request_id required in jig queue submit response ([5ae0fbc](https://github.com/togethercomputer/together-py/commit/5ae0fbca3e592dafedc4638642582585f29098df))
* **api:** remove trigger parameter from remediations list method ([d6310d8](https://github.com/togethercomputer/together-py/commit/d6310d881cc12bb67132c9446d301d1663fd9f48))
* **jig:** honor uv default groups in autogenerated dockerfile ([#301](https://github.com/togethercomputer/together-py/issues/301)) ([85cf77b](https://github.com/togethercomputer/together-py/commit/85cf77b6dc8df8a4f5859deb543123195c484b5b))
* **types:** correct status field to enum in cluster_storage model ([2109f0a](https://github.com/togethercomputer/together-py/commit/2109f0a0c897a7d5659f700042ec97b0843b3228))
* **types:** remove node_name from ControlPlaneNode and GPUWorkerNode ([7a1a7c2](https://github.com/togethercomputer/together-py/commit/7a1a7c21f1cb0e898cf9c9cf12746964c5d1b978))


### Documentation

* **api:** add parameter descriptions to storage methods and types ([8c35457](https://github.com/togethercomputer/together-py/commit/8c35457b06dc6a58f0c1343accb8db09ad91b845))

## 2.14.0 (2026-05-12)

Full Changelog: [v2.13.0...v2.14.0](https://github.com/togethercomputer/together-py/compare/v2.13.0...v2.14.0)
Expand Down
23 changes: 20 additions & 3 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ from together.types.beta.jig import Volume, VolumeListResponse
Methods:

- <code title="post /deployments/storage/volumes">client.beta.jig.volumes.<a href="./src/together/resources/beta/jig/volumes.py">create</a>(\*\*<a href="src/together/types/beta/jig/volume_create_params.py">params</a>) -> <a href="./src/together/types/beta/jig/volume.py">Volume</a></code>
- <code title="get /deployments/storage/volumes/{id}">client.beta.jig.volumes.<a href="./src/together/resources/beta/jig/volumes.py">retrieve</a>(id) -> <a href="./src/together/types/beta/jig/volume.py">Volume</a></code>
- <code title="get /deployments/storage/volumes/{id}">client.beta.jig.volumes.<a href="./src/together/resources/beta/jig/volumes.py">retrieve</a>(id, \*\*<a href="src/together/types/beta/jig/volume_retrieve_params.py">params</a>) -> <a href="./src/together/types/beta/jig/volume.py">Volume</a></code>
- <code title="patch /deployments/storage/volumes/{id}">client.beta.jig.volumes.<a href="./src/together/resources/beta/jig/volumes.py">update</a>(id, \*\*<a href="src/together/types/beta/jig/volume_update_params.py">params</a>) -> <a href="./src/together/types/beta/jig/volume.py">Volume</a></code>
- <code title="get /deployments/storage/volumes">client.beta.jig.volumes.<a href="./src/together/resources/beta/jig/volumes.py">list</a>() -> <a href="./src/together/types/beta/jig/volume_list_response.py">VolumeListResponse</a></code>
- <code title="delete /deployments/storage/volumes/{id}">client.beta.jig.volumes.<a href="./src/together/resources/beta/jig/volumes.py">delete</a>(id) -> object</code>
Expand Down Expand Up @@ -87,10 +87,27 @@ Methods:
- <code title="post /compute/clusters">client.beta.clusters.<a href="./src/together/resources/beta/clusters/clusters.py">create</a>(\*\*<a href="src/together/types/beta/cluster_create_params.py">params</a>) -> <a href="./src/together/types/beta/cluster.py">Cluster</a></code>
- <code title="get /compute/clusters/{cluster_id}">client.beta.clusters.<a href="./src/together/resources/beta/clusters/clusters.py">retrieve</a>(cluster_id) -> <a href="./src/together/types/beta/cluster.py">Cluster</a></code>
- <code title="put /compute/clusters/{cluster_id}">client.beta.clusters.<a href="./src/together/resources/beta/clusters/clusters.py">update</a>(cluster_id, \*\*<a href="src/together/types/beta/cluster_update_params.py">params</a>) -> <a href="./src/together/types/beta/cluster.py">Cluster</a></code>
- <code title="get /compute/clusters">client.beta.clusters.<a href="./src/together/resources/beta/clusters/clusters.py">list</a>() -> <a href="./src/together/types/beta/cluster_list_response.py">ClusterListResponse</a></code>
- <code title="get /compute/clusters">client.beta.clusters.<a href="./src/together/resources/beta/clusters/clusters.py">list</a>(\*\*<a href="src/together/types/beta/cluster_list_params.py">params</a>) -> <a href="./src/together/types/beta/cluster_list_response.py">ClusterListResponse</a></code>
- <code title="delete /compute/clusters/{cluster_id}">client.beta.clusters.<a href="./src/together/resources/beta/clusters/clusters.py">delete</a>(cluster_id) -> <a href="./src/together/types/beta/cluster_delete_response.py">ClusterDeleteResponse</a></code>
- <code title="get /compute/regions">client.beta.clusters.<a href="./src/together/resources/beta/clusters/clusters.py">list_regions</a>() -> <a href="./src/together/types/beta/cluster_list_regions_response.py">ClusterListRegionsResponse</a></code>

### Remediations

Types:

```python
from together.types.beta.clusters import Remediation, RemediationListResponse
```

Methods:

- <code title="post /compute/clusters/{cluster_id}/instances/{instance_id}/remediations">client.beta.clusters.remediations.<a href="./src/together/resources/beta/clusters/remediations.py">create</a>(instance_id, \*, cluster_id, \*\*<a href="src/together/types/beta/clusters/remediation_create_params.py">params</a>) -> <a href="./src/together/types/beta/clusters/remediation.py">Remediation</a></code>
- <code title="get /compute/clusters/{cluster_id}/instances/{instance_id}/remediations/{remediation_id}">client.beta.clusters.remediations.<a href="./src/together/resources/beta/clusters/remediations.py">retrieve</a>(remediation_id, \*, cluster_id, instance_id) -> <a href="./src/together/types/beta/clusters/remediation.py">Remediation</a></code>
- <code title="get /compute/clusters/{cluster_id}/instances/{instance_id}/remediations">client.beta.clusters.remediations.<a href="./src/together/resources/beta/clusters/remediations.py">list</a>(instance_id, \*, cluster_id, \*\*<a href="src/together/types/beta/clusters/remediation_list_params.py">params</a>) -> <a href="./src/together/types/beta/clusters/remediation_list_response.py">RemediationListResponse</a></code>
- <code title="post /compute/clusters/{cluster_id}/instances/{instance_id}/remediations/{remediation_id}/approve">client.beta.clusters.remediations.<a href="./src/together/resources/beta/clusters/remediations.py">approve</a>(remediation_id, \*, cluster_id, instance_id, \*\*<a href="src/together/types/beta/clusters/remediation_approve_params.py">params</a>) -> <a href="./src/together/types/beta/clusters/remediation.py">Remediation</a></code>
- <code title="post /compute/clusters/{cluster_id}/instances/{instance_id}/remediations/{remediation_id}/cancel">client.beta.clusters.remediations.<a href="./src/together/resources/beta/clusters/remediations.py">cancel</a>(remediation_id, \*, cluster_id, instance_id) -> <a href="./src/together/types/beta/clusters/remediation.py">Remediation</a></code>
- <code title="post /compute/clusters/{cluster_id}/instances/{instance_id}/remediations/{remediation_id}/reject">client.beta.clusters.remediations.<a href="./src/together/resources/beta/clusters/remediations.py">reject</a>(remediation_id, \*, cluster_id, instance_id, \*\*<a href="src/together/types/beta/clusters/remediation_reject_params.py">params</a>) -> <a href="./src/together/types/beta/clusters/remediation.py">Remediation</a></code>

### Storage

Types:
Expand All @@ -104,7 +121,7 @@ Methods:
- <code title="post /compute/clusters/storage/volumes">client.beta.clusters.storage.<a href="./src/together/resources/beta/clusters/storage.py">create</a>(\*\*<a href="src/together/types/beta/clusters/storage_create_params.py">params</a>) -> <a href="./src/together/types/beta/clusters/cluster_storage.py">ClusterStorage</a></code>
- <code title="get /compute/clusters/storage/volumes/{volume_id}">client.beta.clusters.storage.<a href="./src/together/resources/beta/clusters/storage.py">retrieve</a>(volume_id) -> <a href="./src/together/types/beta/clusters/cluster_storage.py">ClusterStorage</a></code>
- <code title="put /compute/clusters/storage/volumes">client.beta.clusters.storage.<a href="./src/together/resources/beta/clusters/storage.py">update</a>(\*\*<a href="src/together/types/beta/clusters/storage_update_params.py">params</a>) -> <a href="./src/together/types/beta/clusters/cluster_storage.py">ClusterStorage</a></code>
- <code title="get /compute/clusters/storage/volumes">client.beta.clusters.storage.<a href="./src/together/resources/beta/clusters/storage.py">list</a>() -> <a href="./src/together/types/beta/clusters/storage_list_response.py">StorageListResponse</a></code>
- <code title="get /compute/clusters/storage/volumes">client.beta.clusters.storage.<a href="./src/together/resources/beta/clusters/storage.py">list</a>(\*\*<a href="src/together/types/beta/clusters/storage_list_params.py">params</a>) -> <a href="./src/together/types/beta/clusters/storage_list_response.py">StorageListResponse</a></code>
- <code title="delete /compute/clusters/storage/volumes/{volume_id}">client.beta.clusters.storage.<a href="./src/together/resources/beta/clusters/storage.py">delete</a>(volume_id) -> <a href="./src/together/types/beta/clusters/storage_delete_response.py">StorageDeleteResponse</a></code>

# Chat
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "together"
version = "2.14.0"
version = "2.15.0"
description = "The official Python library for the together API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/together/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "together"
__version__ = "2.14.0" # x-release-please-version
__version__ = "2.15.0" # x-release-please-version
46 changes: 46 additions & 0 deletions src/together/lib/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,12 @@
FINE_TUNING_DOWNLOAD_HELP_EXAMPLES,
BETA_CLUSTERS_STORAGE_HELP_EXAMPLES,
FILES_RETRIEVE_CONTENT_HELP_EXAMPLES,
FINE_TUNING_LIST_METRICS_HELP_EXAMPLES,
BETA_CLUSTERS_REMEDIATIONS_HELP_EXAMPLES,
BETA_CLUSTERS_STORAGE_CREATE_HELP_EXAMPLES,
BETA_CLUSTERS_STORAGE_UPDATE_HELP_EXAMPLES,
BETA_CLUSTERS_GET_CREDENTIALS_HELP_EXAMPLES,
BETA_CLUSTERS_REMEDIATIONS_CREATE_HELP_EXAMPLES,
)
from together.lib.cli.utils._help_formatter import help_formatter
from together.lib.cli.utils._preparse_tokens import preparse_tokens
Expand Down Expand Up @@ -380,6 +383,11 @@ async def run_command() -> None:
help_epilogue=FINE_TUNING_DOWNLOAD_HELP_EXAMPLES,
)
fine_tuning_app.command((f"{_CLI}.fine_tuning.delete:delete"), alias="-d", help="Delete a fine-tuning job")
fine_tuning_app.command(
(f"{_CLI}.fine_tuning.list_metrics:list_metrics"),
help="Retrieve training metrics for a fine-tuning job",
help_epilogue=FINE_TUNING_LIST_METRICS_HELP_EXAMPLES,
)

## Models API commands
models_app = app.command(App(name="models", help="List and upload models", help_epilogue=MODELS_HELP_EXAMPLES))
Expand Down Expand Up @@ -486,6 +494,44 @@ async def run_command() -> None:
)
storage_app.command((f"{_CLI}.beta.clusters.storage.delete:delete"), help="Delete a storage volume", alias="-d")

### Clusters > Remediations API commands
remediations_app = clusters_app.command(
App(
name="remediations",
help="Manage node remediations",
group="Subcommands",
help_epilogue=BETA_CLUSTERS_REMEDIATIONS_HELP_EXAMPLES,
)
)
remediations_app.command(
(f"{_CLI}.beta.clusters.remediations.create:create"),
alias="-c",
help="Create a node remediation",
help_epilogue=BETA_CLUSTERS_REMEDIATIONS_CREATE_HELP_EXAMPLES,
)
remediations_app.command(
(f"{_CLI}.beta.clusters.remediations.list:list"),
alias="ls",
help="List node remediations",
)
remediations_app.command(
(f"{_CLI}.beta.clusters.remediations.retrieve:retrieve"),
alias="get",
help="Get remediation details",
)
remediations_app.command(
(f"{_CLI}.beta.clusters.remediations.approve:approve"),
help="Approve a pending remediation",
)
remediations_app.command(
(f"{_CLI}.beta.clusters.remediations.cancel:cancel"),
help="Cancel a pending remediation",
)
remediations_app.command(
(f"{_CLI}.beta.clusters.remediations.reject:reject"),
help="Reject a pending remediation",
)

### Jig commands
jig_app = beta_app.command(
App(name="jig", help="Build, deploy, and manage custom containers", help_epilogue=JIG_HELP_EXAMPLES)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from __future__ import annotations

import sys

from together import omit
from together._types import Omit
from together.lib.cli.utils.config import CLIConfigParameter
from together.lib.cli.utils._console import console
from together.types.beta.clusters.remediation import Remediation


async def resolve_remediation(config: CLIConfigParameter, remediation_id: str) -> Remediation:
clusters = await config.client.beta.clusters.list()

for cluster in clusters.clusters:
page_token: str | Omit = omit
while True:
response = await config.client.beta.clusters.remediations.list(
"-",
cluster_id=cluster.cluster_id,
page_size=100,
page_token=page_token,
)
for remediation in response.remediations:
if remediation.id == remediation_id:
return remediation

if not response.has_next or not response.next_page_token:
break
page_token = response.next_page_token

console.print(f"[red]Error:[/red] Remediation not found: {remediation_id}")
sys.exit(1)
37 changes: 37 additions & 0 deletions src/together/lib/cli/api/beta/clusters/remediations/approve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from __future__ import annotations

from typing import Optional, Annotated

from cyclopts import Parameter

from together import omit
from together._utils._json import openapi_dumps
from together.lib.cli.utils.config import CLIConfigParameter
from together.lib.cli.utils._console import console
from together.lib.cli.components.loader import show_loading_status
from together.lib.cli.api.beta.clusters.remediations._resolve_remediation import resolve_remediation


async def approve(
remediation_id: str,
comment: Annotated[Optional[str], Parameter(help="Comment explaining the approval")] = None,
*,
config: CLIConfigParameter,
) -> None:
"""Approve a pending remediation."""
remediation = await show_loading_status("Finding remediation...", resolve_remediation(config, remediation_id))
response = await show_loading_status(
"Approving remediation...",
config.client.beta.clusters.remediations.approve(
remediation_id,
cluster_id=remediation.cluster_id,
instance_id=remediation.instance_id,
comment=comment or omit,
),
)

if config.json:
console.print_json(openapi_dumps(response).decode("utf-8"))
return

console.print(f"[blue]Remediation approved.[/blue] ({response.id})")
30 changes: 30 additions & 0 deletions src/together/lib/cli/api/beta/clusters/remediations/cancel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from __future__ import annotations

from together._utils._json import openapi_dumps
from together.lib.cli.utils.config import CLIConfigParameter
from together.lib.cli.utils._console import console
from together.lib.cli.components.loader import show_loading_status
from together.lib.cli.api.beta.clusters.remediations._resolve_remediation import resolve_remediation


async def cancel(
remediation_id: str,
*,
config: CLIConfigParameter,
) -> None:
"""Cancel a pending remediation."""
remediation = await show_loading_status("Finding remediation...", resolve_remediation(config, remediation_id))
response = await show_loading_status(
"Cancelling remediation...",
config.client.beta.clusters.remediations.cancel(
remediation_id,
cluster_id=remediation.cluster_id,
instance_id=remediation.instance_id,
),
)

if config.json:
console.print_json(openapi_dumps(response).decode("utf-8"))
return

console.print(f"[blue]Remediation cancelled.[/blue] ({response.id})")
Loading
Loading