Skip to content

Add existing_annotations (replace, preserve, merge) to Project.autolabel and the CLI - #570

Merged
iurisilvio merged 4 commits into
mainfrom
iuri/autolabel-merge-existing
Oct 29, 2026
Merged

iurisilvio merged 4 commits into
mainfrom
iuri/autolabel-merge-existing

Conversation

@iurisilvio

@iurisilvio iurisilvio commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Description

Auto Label has three ways to handle images that already have annotations: replace them, preserve them and add every prediction, or merge (roboflow/roboflow#18427, in production since 2026-10-27). Merge keeps the existing annotations and adds only the predictions that don't overlap an existing annotation of the same class (IoU of at least 0.5), so objects that are already labeled aren't duplicated.

The SDK and the CLI take the mode as one parameter with the server's three values, instead of one boolean per mode:

  • Project.autolabel(..., existing_annotations="replace" | "preserve" | "merge"). None sends nothing, so the server default (replace) applies, as before.
  • roboflow autolabel start --existing-annotations replace|preserve|merge. An unknown value is a structured error (exit code 1) before any request.
  • rfapi.start_autolabel_job(..., existing_annotations=...) turns the mode into the API's booleans through existing_annotations_flags in roboflow/util/autolabel_utils.py. Merge sends preserveExistingAnnotations and mergeExistingAnnotations, the way the web app does, so a server without merge would still keep the annotations.

Existing callers keep working:

  • Project.autolabel(..., preserve_existing_annotations=True) still preserves and raises a DeprecationWarning. existing_annotations wins when both are set.
  • --preserve-existing is a hidden alias of --existing-annotations preserve.

CLI-COMMANDS.md and CHANGELOG.md (Unreleased: Added and Deprecated) describe the new option.

Type of change

  • New feature (non-breaking change which adds functionality)

How has this change been tested?

  • Tests for the mode-to-flags helper, the adapter body (and its rejection of an unknown mode before the request), Project.autolabel with the new parameter and with the deprecated flag, and the CLI option, the hidden alias and an unknown value.
  • python -m unittest on Python 3.12: 1277 tests OK (1 skipped).
  • ruff format --check, ruff check and mypy roboflow are clean.

Any specific deployment considerations

None. The API already accepts both flags in production. The MCP server gets the same existing_annotations parameter in roboflow/roboflow-mcp#266.

🤖 Generated with Claude Code

iurisilvio and others added 2 commits October 28, 2026 16:12
The Auto Label API takes mergeExistingAnnotations: keep the annotations
already on the batch images and add only the predictions that don't
overlap an existing annotation of the same class (IoU >= 0.5).
Project.autolabel(merge_existing_annotations=True) and
`roboflow autolabel start --merge-existing` send it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Project.autolabel takes existing_annotations="replace" | "preserve" |
"merge" and the CLI takes --existing-annotations, the same three modes
the server has. preserve_existing_annotations still works with a
DeprecationWarning, and --preserve-existing is a hidden alias.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@iurisilvio iurisilvio changed the title Add merge_existing_annotations to Project.autolabel and the CLI Add existing_annotations (replace, preserve, merge) to Project.autolabel and the CLI Oct 28, 2026
@iurisilvio
iurisilvio requested a review from a team October 28, 2026 16:51
@iurisilvio iurisilvio self-assigned this Oct 28, 2026
Comment thread roboflow/cli/handlers/autolabel.py Resolved
Comment thread roboflow/core/project.py Resolved
iurisilvio and others added 2 commits October 28, 2026 20:22
… to the value

An empty --existing-annotations (ex: an unset $MODE) now fails like any other
unknown mode instead of falling back to replace. preserve_existing_annotations=False
now points to existing_annotations="replace", not "preserve".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…existing

# Conflicts:
#	CHANGELOG.md
#	CLI-COMMANDS.md
#	roboflow/adapters/rfapi.py
#	roboflow/cli/handlers/autolabel.py
#	roboflow/core/project.py
#	tests/adapters/test_autolabel.py
#	tests/cli/test_autolabel_handler.py
#	tests/test_project_autolabel.py

@joaomarcoscrs joaomarcoscrs left a comment

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.

LGTM

@iurisilvio
iurisilvio merged commit f23c18d into main Oct 29, 2026
15 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.

2 participants