Skip to content

Add --availability-model to truss train update - #2634

Open
johnnt849 wants to merge 3 commits into
mainfrom
claude/truss-queued-job-updates-793747
Open

Add --availability-model to truss train update#2634
johnnt849 wants to merge 3 commits into
mainfrom
claude/truss-queued-job-updates-793747

Conversation

@johnnt849

Copy link
Copy Markdown
Contributor

🚀 What

Lets a queued training job's capacity guarantee be changed in place:

truss train update --job-id <job_id> --availability-model spot

Previously a job queued on dedicated capacity had to be cancelled and resubmitted to run on spot. It can now be switched while it sits in the queue, alongside the existing --priority update. Priority and availability model can be set in one call.

The backing PATCH /v1/training_projects/{project_id}/jobs/{job_id} endpoint accepts availability_model (dedicated / spot); only queued jobs can be updated, and the server rejects anything else.

💻 How

Follows the same three layers as the existing --priority update:

  • truss/cli/train_commands.py — the --availability-model option on train update. Choices are derived from the AvailabilityModel enum rather than hardcoded, so they cannot drift from it. The "at least one field" guard now covers both fields.
  • truss/cli/train/core.pyupdate_training_job takes availability_model: Optional[AvailabilityModel] and unwraps it to its wire value at the API boundary.
  • truss/remote/baseten/api.py — adds availability_model to the PATCH body only when set, matching how priority is handled. Typed as str here rather than the enum, since truss/remote/ sits below truss_train in the layering.

A choice option rather than a bare --spot flag (as truss train push has), because an update also needs to switch a job back to dedicated.

🔬 Testing

56 tests pass; ruff check / ruff format clean; mypy clean via pre-commit.

  • truss/tests/remote/baseten/test_api.py — availability-only and priority+availability request bodies.
  • truss/tests/cli/train/test_train_cli_core.py — enum → wire-value conversion, both fields forwarded together, and the no-fields ValueError raised before any API call is made.

Verified truss train update --help renders the new option.

🤖 Generated with Claude Code

johnnt849 and others added 2 commits August 31, 2026 10:59
A queued training job's capacity guarantee can now be changed in place:

    truss train update --job-id <id> --availability-model spot

Previously a dedicated job blocked on full capacity had to be resubmitted to
run on spot. It can now be switched while it sits in the queue, alongside the
existing --priority update.

Follows the same three layers as the priority update: the option on the
`train update` command, the enum-typed parameter in cli/train/core.py, and the
PATCH body field in remote/baseten/api.py. Choices are derived from the
AvailabilityModel enum so they cannot drift from it, and a choice option rather
than a bare --spot flag (as `truss train push` has) since an update also needs
to switch a job back to dedicated.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
TestUpdateTrainingJob in truss-train/tests/test_recreate.py asserts the exact
kwargs passed to the API, so adding availability_model to the call broke
test_update_training_job_success.

Fix the assertion, and move the two availability-model cases from
truss/tests/cli/train/test_train_cli_core.py into TestUpdateTrainingJob beside
their siblings — the no-fields case there was an exact duplicate of one already
in that class. All five update_training_job call assertions now live in one
file, so a signature change can't pass one suite while breaking the other.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting reminder to also add this to https://github.com/basetenlabs/baseten-cli (unless you want to)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a PR for that in a bit!

test_recreate.py is about job recreation, and it lives in truss-train/tests/
even though it exercises truss.cli.train.core. TestUpdateTrainingJob moves to
truss/tests/cli/train/test_job_update.py, which names what it tests and sits in
the tree for the package under test.

All five update assertions stay together in the new file, so a change to the
call signature still can't pass one suite while breaking another.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants