Skip to content

Add ability to mark jobs as discarded and also add scoring#1965

Merged
deep1401 merged 12 commits into
mainfrom
add/job-discard
May 4, 2026
Merged

Add ability to mark jobs as discarded and also add scoring#1965
deep1401 merged 12 commits into
mainfrom
add/job-discard

Conversation

@deep1401

@deep1401 deep1401 commented May 4, 2026

Copy link
Copy Markdown
Member
  • GUI: added a new dropdown action in the jobs list menu:

  • CLI: added lab job discard <job_id> and lab job discard <job_id> --undo to toggle score.discard.

  • Also improved the existing jobs filter by score by allowing asc and desc order and also placing other existing jobs at the end:

# Default descending by metric:
lab job list --score-metric eval/loss

# Explicit ascending:
lab job list --score-metric eval/loss --score-order asc

@netlify

netlify Bot commented May 4, 2026

Copy link
Copy Markdown

Deploy Preview for transformerlab canceled.

Name Link
🔨 Latest commit 8b4d591
🔍 Latest deploy log https://app.netlify.com/projects/transformerlab/deploys/69f8ce8ce0004b0008d631d4

@sentry

sentry Bot commented May 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 2.56410% with 38 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
api/transformerlab/routers/experiment/jobs.py 0.00% 25 Missing ⚠️
api/transformerlab/services/job_service.py 7.14% 13 Missing ⚠️

📢 Thoughts on this report? Let us know!

logger.debug("Trackio integration failed during finish()", exc_info=True)
if score is not None:
_run_async(self._job.update_job_data_field("score", score)) # type: ignore[union-attr]
resolved_score: Dict[str, Any] = {}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this is OK but just double checking:

We don't set score anywhere earlier? I just noticed that if you call finish without a score I think it will overwrite if there's anythign in there already. But I think that's fine?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No score is only set by finish, nowhere before that

filtered = {k: v for k, v in updates.items() if k in allowed_keys}

# Keep discard under job_data.score.discard to avoid introducing a new top-level field.
if "discard" in filtered:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Technically this is race. Not sure how important (not super worried about two people flipping discard on same job at the same time, but maybe UI and SDK fighting is possible).

OK I asked Claude for a simple fix and it said to create a function at service later and call from here if "discard" is passed. Something like this (note this is technically still a race, just narrower and cleaner):

async def job_update_job_data_score_field(job_id, score_key: str, value, experiment_id):
    """Merge a single key into job_data.score atomically."""
    resolved_id = await _resolve_full_job_id(str(job_id), str(experiment_id))
    actual_id = resolved_id or str(job_id)
    job = await Job.get(actual_id, experiment_id)

    # Read + merge + write within the same Job instance scope
    current = (await job.get_job_data()) or {}
    score = current.get("score") if isinstance(current, dict) else {}
    score = dict(score) if isinstance(score, dict) else {}
    score[score_key] = value
    await job.update_job_data_field("score", score)

    await cache.invalidate(f"job:{actual_id}")
    await cache.delete(_job_cache_key(actual_id))

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed now based on what you recommended


# Keep discard under job_data.score.discard to avoid introducing a new top-level field.
if "discard" in filtered:
discard_value = bool(filtered.pop("discard"))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Probably fine but as a note "false" will evaluate as true I think.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Okay fixed this and also found similar things in CLI and frontend, fixed both

Comment thread api/transformerlab/routers/experiment/jobs.py Outdated
Comment thread api/transformerlab/routers/experiment/jobs.py Outdated
Comment thread api/transformerlab/routers/experiment/jobs.py Outdated
@deep1401 deep1401 changed the title Add ability to mark jobs as discarded Add ability to mark jobs as discarded and also add scoring May 4, 2026
@deep1401 deep1401 requested a review from dadmobile May 4, 2026 15:55

@deep1401 deep1401 left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Improved the existing jobs filter by score by allowing asc and desc order and also placing other existing jobs at the end:

# Default descending by metric:
lab job list --score-metric eval/loss

# Explicit ascending:
lab job list --score-metric eval/loss --score-order asc

@deep1401 deep1401 merged commit fb4507a into main May 4, 2026
21 of 23 checks passed
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.

3 participants