From cf1309709a4f29f397de01ca67e7179fef909605 Mon Sep 17 00:00:00 2001 From: Marcel Canu Date: Thu, 27 Nov 2025 18:20:26 -0300 Subject: [PATCH 01/32] Added show_ground_truth_always field in project and handle next_task --- label_studio/projects/api.py | 1 + label_studio/projects/functions/next_task.py | 30 +++++++++++------- .../0034_project_show_ground_truth_always.py | 31 +++++++++++++++++++ label_studio/projects/models.py | 6 ++++ label_studio/projects/serializers.py | 1 + label_studio/tasks/models.py | 3 +- .../tests/data_manager/columns.tavern.yml | 2 +- .../src/config/ApiConfig.example.js | 1 + web/apps/labelstudio/src/types/Project.d.ts | 1 + 9 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 label_studio/projects/migrations/0034_project_show_ground_truth_always.py diff --git a/label_studio/projects/api.py b/label_studio/projects/api.py index 53c98bc95afc..16499048f839 100644 --- a/label_studio/projects/api.py +++ b/label_studio/projects/api.py @@ -308,6 +308,7 @@ def get_queryset(self): 'total_predictions_number': 0, 'sampling': 'Sequential sampling', 'show_ground_truth_first': True, + 'show_ground_truth_always': False, 'show_overlap_first': True, 'overlap_cohort_percentage': 100, 'task_data_login': 'user', diff --git a/label_studio/projects/functions/next_task.py b/label_studio/projects/functions/next_task.py index 635b6b598532..50c65155a414 100644 --- a/label_studio/projects/functions/next_task.py +++ b/label_studio/projects/functions/next_task.py @@ -59,10 +59,7 @@ def _get_first_unlocked(tasks_query: QuerySet[Task], user) -> Union[Task, None]: def _try_ground_truth(tasks: QuerySet[Task], project: Project, user: User) -> Union[Task, None]: """Returns task from ground truth set""" - ground_truth = Annotation.objects.filter(task=OuterRef('pk'), ground_truth=True) - not_solved_tasks_with_ground_truths = tasks.annotate(has_ground_truths=Exists(ground_truth)).filter( - has_ground_truths=True - ) + not_solved_tasks_with_ground_truths = _annotate_has_ground_truths(tasks).filter(has_ground_truths=True) if not_solved_tasks_with_ground_truths.exists(): if project.sampling == project.SEQUENCE: return _get_first_unlocked(not_solved_tasks_with_ground_truths, user) @@ -81,10 +78,10 @@ def _try_tasks_with_overlap(tasks: QuerySet[Task]) -> Tuple[Union[Task, None], Q def _try_breadth_first(tasks: QuerySet[Task], user: User, project: Project) -> Union[Task, None]: """Try to find tasks with maximum amount of annotations, since we are trying to label tasks as fast as possible""" - # Exclude ground truth annotations from the count when not in onboarding mode + # Exclude ground truth annotations from the count when not in onboarding mode or show_ground_truth_always mode # to prevent GT tasks from being prioritized via breadth-first logic annotation_filter = ~Q(annotations__completed_by=user) - if not project.show_ground_truth_first: + if not project.show_ground_truth_first and not project.show_ground_truth_always: annotation_filter &= ~Q(annotations__ground_truth=True) tasks = tasks.annotate(annotations_count=Count('annotations', filter=annotation_filter)) @@ -158,6 +155,11 @@ def _try_uncertainty_sampling( return next_task +def _annotate_has_ground_truths(tasks: QuerySet[Task]) -> QuerySet[Task]: + ground_truth = Annotation.objects.filter(task=OuterRef('pk'), ground_truth=True) + return tasks.annotate(has_ground_truths=Exists(ground_truth)) + + def get_not_solved_tasks_qs( user: User, project: Project, @@ -197,9 +199,9 @@ def get_not_solved_tasks_qs( ) capacity_pred = Q(annotators__lt=F('overlap') + (lse_project.max_additional_annotators_assignable or 0)) - if project.show_ground_truth_first: - gt_subq = Annotation.objects.filter(task=OuterRef('pk'), ground_truth=True) - qs = qs.annotate(has_ground_truths=Exists(gt_subq)) + # Always include ground truth tasks in the query + if project.show_ground_truth_first or project.show_ground_truth_always: + qs = _annotate_has_ground_truths(qs) # Keep all GT tasks + apply low-agreement+capacity to the rest. For sure, we can do: # - if user.solved_tasks_array.count < lse_project.annotator_evaluation_minimum_tasks # - else, apply low-agreement+capacity to the rest (maybe performance will be better) @@ -212,9 +214,14 @@ def get_not_solved_tasks_qs( # otherwise, filtering out completed tasks is sufficient else: - # ignore tasks that are already labeled when GT-first is NOT allowed if not allow_gt_first: - not_solved_tasks = not_solved_tasks.filter(is_labeled=False) + if project.show_ground_truth_always: + # Include ground truth tasks in the query if show_ground_truth_always is enabled + not_solved_tasks = _annotate_has_ground_truths(not_solved_tasks) + not_solved_tasks = not_solved_tasks.filter(Q(is_labeled=False) | Q(has_ground_truths=True)) + # ignore tasks that are already labeled when GT-first is NOT allowed and no need to include GT tasks always + else: + not_solved_tasks = not_solved_tasks.filter(is_labeled=False) if not flag_set('fflag_fix_back_lsdv_4523_show_overlap_first_order_27022023_short'): # show tasks with overlap > 1 first (unless tasks are already prioritized on agreement) @@ -453,6 +460,7 @@ def get_next_task( 'skip_queue': project.skip_queue, 'sampling': project.sampling, 'show_ground_truth_first': project.show_ground_truth_first, + 'show_ground_truth_always': project.show_ground_truth_always, 'show_overlap_first': project.show_overlap_first, 'overlap_cohort_percentage': project.overlap_cohort_percentage, 'project_id': project.id, diff --git a/label_studio/projects/migrations/0034_project_show_ground_truth_always.py b/label_studio/projects/migrations/0034_project_show_ground_truth_always.py new file mode 100644 index 000000000000..50b61f973fca --- /dev/null +++ b/label_studio/projects/migrations/0034_project_show_ground_truth_always.py @@ -0,0 +1,31 @@ +# Generated by Django 5.1.14 on 2025-11-27 21:06 + +from django.db import migrations, models + +def set_defaults_based_on_mode(apps, schema_editor): + """ + For existing projects with show_ground_truth_first=True (Onboarding mode), + set show_ground_truth_always=True. + """ + Project = apps.get_model("projects", "Project") + Project.objects.filter(show_ground_truth_first=True).update(show_ground_truth_always=True) + +class Migration(migrations.Migration): + + dependencies = [ + ("projects", "0033_projects_soft_delete_indexes_async"), + ] + + operations = [ + migrations.AddField( + model_name="project", + name="show_ground_truth_always", + field=models.BooleanField( + default=False, + help_text="When enabled, ground truth tasks will be shown to all annotators regardless of overlap", + null=True, + verbose_name="show ground truth always", + ), + ), + migrations.RunPython(set_defaults_based_on_mode, reverse_code=migrations.RunPython.noop), + ] diff --git a/label_studio/projects/models.py b/label_studio/projects/models.py index da46a19fa37e..33c1f0a2f49c 100644 --- a/label_studio/projects/models.py +++ b/label_studio/projects/models.py @@ -322,6 +322,12 @@ class SkipQueue(models.TextChoices): default=False, help_text='Onboarding mode (true): show ground truth tasks first in the labeling stream', ) + show_ground_truth_always = models.BooleanField( + _('show ground truth always'), + default=False, + null=True, + help_text='When enabled, ground truth tasks will be shown to all annotators regardless of overlap', + ) show_overlap_first = models.BooleanField(_('show overlap first'), default=False) overlap_cohort_percentage = models.IntegerField(_('overlap_cohort_percentage'), default=100) diff --git a/label_studio/projects/serializers.py b/label_studio/projects/serializers.py index a0da9d1cb150..bf605694f73f 100644 --- a/label_studio/projects/serializers.py +++ b/label_studio/projects/serializers.py @@ -236,6 +236,7 @@ class Meta: 'total_predictions_number', 'sampling', 'show_ground_truth_first', + 'show_ground_truth_always', 'show_overlap_first', 'overlap_cohort_percentage', 'task_data_login', diff --git a/label_studio/tasks/models.py b/label_studio/tasks/models.py index 904282b4133b..2994e065fe93 100644 --- a/label_studio/tasks/models.py +++ b/label_studio/tasks/models.py @@ -283,9 +283,10 @@ def has_lock(self, user=None): """ from projects.functions.next_task import get_next_task_logging_level - if self.project.show_ground_truth_first: + if self.project.show_ground_truth_first or self.project.show_ground_truth_always: # in show_ground_truth_first mode(onboarding) # we ignore overlap setting for ground_truth tasks + # in show_ground_truth_always mode we ignore overlap setting for ground_truth tasks # https://humansignal.atlassian.net/browse/LEAP-1963 if self.annotations.filter(ground_truth=True).exists(): return False diff --git a/label_studio/tests/data_manager/columns.tavern.yml b/label_studio/tests/data_manager/columns.tavern.yml index 2949382dc911..77db054e0ec2 100644 --- a/label_studio/tests/data_manager/columns.tavern.yml +++ b/label_studio/tests/data_manager/columns.tavern.yml @@ -42,7 +42,7 @@ stages: "start_training_on_annotation_update": false, "show_collab_predictions": true, "num_tasks_with_annotations": null, "task_number": null, "useful_annotation_number": null, "ground_truth_number": null, "skipped_annotations_number": null, "total_annotations_number": null, "total_predictions_number": null, "sampling": "Sequential sampling", - "show_ground_truth_first": false, "show_overlap_first": false, "overlap_cohort_percentage": 100, + "show_ground_truth_first": false, "show_ground_truth_always": false, "show_overlap_first": false, "overlap_cohort_percentage": 100, "task_data_login": null, "task_data_password": null, "control_weights": {"label": {"overall": 1.0, "type": "Choices", "labels": {"pos": 1.0, "neg": 1.0}}}, "parsed_label_config": { diff --git a/web/apps/labelstudio/src/config/ApiConfig.example.js b/web/apps/labelstudio/src/config/ApiConfig.example.js index 26fcd3facf00..f51ed96e5135 100644 --- a/web/apps/labelstudio/src/config/ApiConfig.example.js +++ b/web/apps/labelstudio/src/config/ApiConfig.example.js @@ -52,6 +52,7 @@ export const API_CONFIG = { total_predictions_number: 100, sampling: "Sequential sampling", show_ground_truth_first: false, + show_ground_truth_always: false, show_overlap_first: false, overlap_cohort_percentage: 100, task_data_login: null, diff --git a/web/apps/labelstudio/src/types/Project.d.ts b/web/apps/labelstudio/src/types/Project.d.ts index 733a00682afc..1b8f8e4057af 100644 --- a/web/apps/labelstudio/src/types/Project.d.ts +++ b/web/apps/labelstudio/src/types/Project.d.ts @@ -73,6 +73,7 @@ declare type APIProject = { total_predictions_number?: string; sampling?: "Sequential sampling" | "Uniform sampling" | "Uncertainty sampling" | null; show_ground_truth_first?: boolean; + show_ground_truth_always?: boolean; show_overlap_first?: boolean; overlap_cohort_percentage?: number; From 7148a0661470a80ea43f3b2bbe6e026bf31b4429 Mon Sep 17 00:00:00 2001 From: Marcel Canu Date: Thu, 27 Nov 2025 18:32:11 -0300 Subject: [PATCH 02/32] Modified migration --- .../migrations/0034_project_show_ground_truth_always.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/label_studio/projects/migrations/0034_project_show_ground_truth_always.py b/label_studio/projects/migrations/0034_project_show_ground_truth_always.py index 50b61f973fca..9fc28473556c 100644 --- a/label_studio/projects/migrations/0034_project_show_ground_truth_always.py +++ b/label_studio/projects/migrations/0034_project_show_ground_truth_always.py @@ -2,13 +2,6 @@ from django.db import migrations, models -def set_defaults_based_on_mode(apps, schema_editor): - """ - For existing projects with show_ground_truth_first=True (Onboarding mode), - set show_ground_truth_always=True. - """ - Project = apps.get_model("projects", "Project") - Project.objects.filter(show_ground_truth_first=True).update(show_ground_truth_always=True) class Migration(migrations.Migration): @@ -27,5 +20,4 @@ class Migration(migrations.Migration): verbose_name="show ground truth always", ), ), - migrations.RunPython(set_defaults_based_on_mode, reverse_code=migrations.RunPython.noop), ] From 11b16972661d8f534667137f19d5b72d9d495502 Mon Sep 17 00:00:00 2001 From: Marcel Canu Date: Thu, 27 Nov 2025 18:53:09 -0300 Subject: [PATCH 03/32] Fix migration default --- .../migrations/0034_project_show_ground_truth_always.py | 3 +-- label_studio/projects/models.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/label_studio/projects/migrations/0034_project_show_ground_truth_always.py b/label_studio/projects/migrations/0034_project_show_ground_truth_always.py index 9fc28473556c..51a9eb4e5881 100644 --- a/label_studio/projects/migrations/0034_project_show_ground_truth_always.py +++ b/label_studio/projects/migrations/0034_project_show_ground_truth_always.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.14 on 2025-11-27 21:06 +# Generated by Django 5.1.14 on 2025-11-27 21:52 from django.db import migrations, models @@ -16,7 +16,6 @@ class Migration(migrations.Migration): field=models.BooleanField( default=False, help_text="When enabled, ground truth tasks will be shown to all annotators regardless of overlap", - null=True, verbose_name="show ground truth always", ), ), diff --git a/label_studio/projects/models.py b/label_studio/projects/models.py index 33c1f0a2f49c..14749790aecf 100644 --- a/label_studio/projects/models.py +++ b/label_studio/projects/models.py @@ -325,7 +325,6 @@ class SkipQueue(models.TextChoices): show_ground_truth_always = models.BooleanField( _('show ground truth always'), default=False, - null=True, help_text='When enabled, ground truth tasks will be shown to all annotators regardless of overlap', ) show_overlap_first = models.BooleanField(_('show overlap first'), default=False) From cf65c8f642fe26a5a0ccf2a8c7d1b083ffdbd58f Mon Sep 17 00:00:00 2001 From: Marcel Canu Date: Fri, 28 Nov 2025 12:47:25 -0300 Subject: [PATCH 04/32] Fixed migration --- .../migrations/0034_project_show_ground_truth_always.py | 3 ++- label_studio/projects/models.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/label_studio/projects/migrations/0034_project_show_ground_truth_always.py b/label_studio/projects/migrations/0034_project_show_ground_truth_always.py index 51a9eb4e5881..3edae82c905a 100644 --- a/label_studio/projects/migrations/0034_project_show_ground_truth_always.py +++ b/label_studio/projects/migrations/0034_project_show_ground_truth_always.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.14 on 2025-11-27 21:52 +# Generated by Django 5.1.14 on 2025-11-28 15:45 from django.db import migrations, models @@ -14,6 +14,7 @@ class Migration(migrations.Migration): model_name="project", name="show_ground_truth_always", field=models.BooleanField( + db_default=False, default=False, help_text="When enabled, ground truth tasks will be shown to all annotators regardless of overlap", verbose_name="show ground truth always", diff --git a/label_studio/projects/models.py b/label_studio/projects/models.py index 14749790aecf..4b3480122d7c 100644 --- a/label_studio/projects/models.py +++ b/label_studio/projects/models.py @@ -325,6 +325,7 @@ class SkipQueue(models.TextChoices): show_ground_truth_always = models.BooleanField( _('show ground truth always'), default=False, + db_default=False, help_text='When enabled, ground truth tasks will be shown to all annotators regardless of overlap', ) show_overlap_first = models.BooleanField(_('show overlap first'), default=False) From 736dddedcc636be1122b137967ebd56862a095a1 Mon Sep 17 00:00:00 2001 From: nass600 Date: Thu, 4 Dec 2025 09:59:16 +0000 Subject: [PATCH 05/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/19924849173 --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index aeba24c9ba05..b2d06270dee7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. [[package]] name = "annotated-types" @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "9b72a9525c98ecbf36c816d30365380033ee80e1.zip", hash = "sha256:95d6b0b968a779b6216a6c5bf94ae7461c3decf53066ebeee1442627f7ff51a1"}, + {file = "c6857e92b44143f1aba234471632891490777856.zip", hash = "sha256:6b8ca9a1c3c93c1d8726e0f1434f3faac410a6f98aee222419dd9e6b704e6605"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/9b72a9525c98ecbf36c816d30365380033ee80e1.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/c6857e92b44143f1aba234471632891490777856.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5105,4 +5105,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "46f607014fe7c51f64b807475fac8edd5a2c7211d81da09fd1c99cf72f5a5b60" +content-hash = "b3a445d40bb867cedd338d0cc2e0042323754f1a41bf96f4cddba2332a0fff1d" diff --git a/pyproject.toml b/pyproject.toml index 56706357fd42..17737e6a6124 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/9b72a9525c98ecbf36c816d30365380033ee80e1.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/c6857e92b44143f1aba234471632891490777856.zip", ## HumanSignal repo dependencies :end ] From 655fe5d90da42b2ee0dfe1b6f46f55da5a7ebf65 Mon Sep 17 00:00:00 2001 From: Ignacio Velazquez Date: Thu, 4 Dec 2025 17:13:22 +0100 Subject: [PATCH 06/32] added warning badge --- web/libs/ui/src/shad/components/ui/badge.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/libs/ui/src/shad/components/ui/badge.tsx b/web/libs/ui/src/shad/components/ui/badge.tsx index 7a30a94bf538..073ad155c507 100644 --- a/web/libs/ui/src/shad/components/ui/badge.tsx +++ b/web/libs/ui/src/shad/components/ui/badge.tsx @@ -12,6 +12,8 @@ const badgeVariants = cva( secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", success: "border-transparent bg-positive-background text-positive-content hover:bg-positive-background/80", + warning: + "bg-warning-background border-warning-border-subtlest text-warning-content hover:bg-warning-background/80", info: "bg-primary-background border-primary-emphasis text-accent-grape-dark font-normal", outline: "text-neutral-content border-neutral-border", beta: "bg-accent-plum-subtle text-accent-plum-dark font-medium border-transparent", From a3fa9b06204dc3ebfcfc71d01a8a6c4d64357a53 Mon Sep 17 00:00:00 2001 From: Ignacio Velazquez Date: Thu, 4 Dec 2025 17:27:17 +0100 Subject: [PATCH 07/32] added icons --- web/libs/ui/src/assets/icons/index.ts | 4 ++++ web/libs/ui/src/assets/icons/move-down.svg | 3 +++ web/libs/ui/src/assets/icons/move-left.svg | 3 +++ web/libs/ui/src/assets/icons/move-right.svg | 3 +++ web/libs/ui/src/assets/icons/move-up.svg | 3 +++ 5 files changed, 16 insertions(+) create mode 100644 web/libs/ui/src/assets/icons/move-down.svg create mode 100644 web/libs/ui/src/assets/icons/move-left.svg create mode 100644 web/libs/ui/src/assets/icons/move-right.svg create mode 100644 web/libs/ui/src/assets/icons/move-up.svg diff --git a/web/libs/ui/src/assets/icons/index.ts b/web/libs/ui/src/assets/icons/index.ts index 1456428bad45..7138c401861d 100644 --- a/web/libs/ui/src/assets/icons/index.ts +++ b/web/libs/ui/src/assets/icons/index.ts @@ -177,6 +177,10 @@ export { ReactComponent as IconMinus } from "./minus.svg"; export { ReactComponent as IconModel } from "./model.svg"; export { ReactComponent as IconModels } from "./models.svg"; export { ReactComponent as IconModelVersion } from "./model-version.svg"; +export { ReactComponent as IconMoveLeft } from "./move-left.svg"; +export { ReactComponent as IconMoveRight } from "./move-right.svg"; +export { ReactComponent as IconMoveUp } from "./move-up.svg"; +export { ReactComponent as IconMoveDown } from "./move-down.svg"; export { ReactComponent as IconMoveTool } from "./move-tool.svg"; export { ReactComponent as IconNext } from "./next-step.svg"; export { ReactComponent as IconOctagonAlert } from "./octagon-alert.svg"; diff --git a/web/libs/ui/src/assets/icons/move-down.svg b/web/libs/ui/src/assets/icons/move-down.svg new file mode 100644 index 000000000000..0c676f0e31a0 --- /dev/null +++ b/web/libs/ui/src/assets/icons/move-down.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/web/libs/ui/src/assets/icons/move-left.svg b/web/libs/ui/src/assets/icons/move-left.svg new file mode 100644 index 000000000000..621e893da44c --- /dev/null +++ b/web/libs/ui/src/assets/icons/move-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/web/libs/ui/src/assets/icons/move-right.svg b/web/libs/ui/src/assets/icons/move-right.svg new file mode 100644 index 000000000000..3fb180ecedd3 --- /dev/null +++ b/web/libs/ui/src/assets/icons/move-right.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/web/libs/ui/src/assets/icons/move-up.svg b/web/libs/ui/src/assets/icons/move-up.svg new file mode 100644 index 000000000000..d131df2540af --- /dev/null +++ b/web/libs/ui/src/assets/icons/move-up.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file From d8dc179811bb98733f7860a2fed9d0ebcb8448a3 Mon Sep 17 00:00:00 2001 From: Marcel Canu Date: Thu, 4 Dec 2025 20:13:38 -0300 Subject: [PATCH 08/32] Added new fields --- ...t_annotator_evaluation_enabled_and_more.py | 33 +++++++++++++++++++ label_studio/projects/models.py | 18 ++++++++++ label_studio/projects/serializers.py | 2 ++ 3 files changed, 53 insertions(+) create mode 100644 label_studio/projects/migrations/0035_project_annotator_evaluation_enabled_and_more.py diff --git a/label_studio/projects/migrations/0035_project_annotator_evaluation_enabled_and_more.py b/label_studio/projects/migrations/0035_project_annotator_evaluation_enabled_and_more.py new file mode 100644 index 000000000000..d87c41c636dc --- /dev/null +++ b/label_studio/projects/migrations/0035_project_annotator_evaluation_enabled_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 5.1.14 on 2025-12-04 23:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("projects", "0034_project_show_ground_truth_always"), + ] + + operations = [ + migrations.AddField( + model_name="project", + name="annotator_evaluation_enabled", + field=models.BooleanField( + db_default=False, + default=False, + help_text="Enable annotator evaluation for the project", + verbose_name="annotator evaluation enabled", + ), + ), + migrations.AddField( + model_name="project", + name="annotator_evaluation_onboarding_tasks", + field=models.PositiveIntegerField( + db_default=0, + default=0, + help_text="Number of onboarding tasks for annotator evaluation", + verbose_name="annotator evaluation onboarding tasks", + ), + ), + ] diff --git a/label_studio/projects/models.py b/label_studio/projects/models.py index 3ea1034dd548..57dc83f77520 100644 --- a/label_studio/projects/models.py +++ b/label_studio/projects/models.py @@ -313,17 +313,35 @@ class SkipQueue(models.TextChoices): skip_queue = models.CharField( max_length=100, choices=SkipQueue.choices, null=True, default=SkipQueue.REQUEUE_FOR_OTHERS ) + + # Deprecated show_ground_truth_first = models.BooleanField( _('show ground truth first'), default=False, help_text='Onboarding mode (true): show ground truth tasks first in the labeling stream', ) + + # TODO: Remove this show_ground_truth_always = models.BooleanField( _('show ground truth always'), default=False, db_default=False, help_text='When enabled, ground truth tasks will be shown to all annotators regardless of overlap', ) + + annotator_evaluation_enabled = models.BooleanField( + _('annotator evaluation enabled'), + default=False, + db_default=False, + help_text='Enable annotator evaluation for the project', + ) + annotator_evaluation_onboarding_tasks = models.PositiveIntegerField( + _('annotator evaluation onboarding tasks'), + default=0, + db_default=0, + help_text='Number of onboarding tasks for annotator evaluation', + ) + show_overlap_first = models.BooleanField(_('show overlap first'), default=False) overlap_cohort_percentage = models.IntegerField(_('overlap_cohort_percentage'), default=100) diff --git a/label_studio/projects/serializers.py b/label_studio/projects/serializers.py index bf605694f73f..ee113914fedf 100644 --- a/label_studio/projects/serializers.py +++ b/label_studio/projects/serializers.py @@ -237,6 +237,8 @@ class Meta: 'sampling', 'show_ground_truth_first', 'show_ground_truth_always', + 'annotator_evaluation_enabled', + 'annotator_evaluation_onboarding_tasks', 'show_overlap_first', 'overlap_cohort_percentage', 'task_data_login', From a995df7ab8acd215f1ea2ecda6c527fbc2335492 Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Fri, 5 Dec 2025 18:52:55 +0000 Subject: [PATCH 09/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/19972821374 --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 226623e24804..00bb34e40955 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. [[package]] name = "annotated-types" @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "4a5949e554a5574377c79294a14296a6efec8b02.zip", hash = "sha256:5995187277e84df0b3f387198a2dc848e2a603dc2e389dbd3f87fac33a4bd436"}, + {file = "92c775aeb089f455120de1d10919a0f7c22e8cf2.zip", hash = "sha256:64ea7342500f165cc228ef50f63e965f06e4462fb8d70d0aa1a3ef3d8e3df316"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/4a5949e554a5574377c79294a14296a6efec8b02.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/92c775aeb089f455120de1d10919a0f7c22e8cf2.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "e90a64f555392a21cadd2c78b0f85a835e4a683e01738675a4cb5a54ddb3bccf" +content-hash = "f3901adacfba428041bd392fea01985872068f5fd50a1e1f5fcda86bc77aeae3" diff --git a/pyproject.toml b/pyproject.toml index 410881b28b9a..3e0911302afe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/4a5949e554a5574377c79294a14296a6efec8b02.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/92c775aeb089f455120de1d10919a0f7c22e8cf2.zip", ## HumanSignal repo dependencies :end ] From fc8aabc22ce9cecbfc66ef85c46ddfeddb73b303 Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Fri, 5 Dec 2025 19:07:48 +0000 Subject: [PATCH 10/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/19972907652 --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 00bb34e40955..228e7d61442a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "92c775aeb089f455120de1d10919a0f7c22e8cf2.zip", hash = "sha256:64ea7342500f165cc228ef50f63e965f06e4462fb8d70d0aa1a3ef3d8e3df316"}, + {file = "a4d603fc48ee9ddb632b35cb4c3a55fb73ec55be.zip", hash = "sha256:822fae74e0da2ad5190fd816fcd3a43e804da31f0c8cb851134a5f6d8e4a3833"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/92c775aeb089f455120de1d10919a0f7c22e8cf2.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/a4d603fc48ee9ddb632b35cb4c3a55fb73ec55be.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "f3901adacfba428041bd392fea01985872068f5fd50a1e1f5fcda86bc77aeae3" +content-hash = "54ec839b45af999b9e384b0022731e43ea18e3c42a7d1bdc90dc45287e5ff38b" diff --git a/pyproject.toml b/pyproject.toml index 3e0911302afe..86621332232a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/92c775aeb089f455120de1d10919a0f7c22e8cf2.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/a4d603fc48ee9ddb632b35cb4c3a55fb73ec55be.zip", ## HumanSignal repo dependencies :end ] From cdc89b6d4dabb3c0dc4f6a1e5f84d41bf9a441b9 Mon Sep 17 00:00:00 2001 From: Marcel Canu Date: Fri, 5 Dec 2025 16:42:27 -0300 Subject: [PATCH 11/32] Using new fields --- label_studio/projects/api.py | 2 +- label_studio/projects/functions/next_task.py | 50 +++++++++---------- ...4_project_annotator_evaluation_enabled.py} | 8 +-- ...t_annotator_evaluation_enabled_and_more.py | 33 ------------ label_studio/projects/models.py | 14 ------ label_studio/projects/serializers.py | 2 - label_studio/tasks/models.py | 7 +-- .../tests/data_manager/columns.tavern.yml | 2 +- .../src/config/ApiConfig.example.js | 2 +- web/apps/labelstudio/src/types/Project.d.ts | 2 +- 10 files changed, 33 insertions(+), 89 deletions(-) rename label_studio/projects/migrations/{0034_project_show_ground_truth_always.py => 0034_project_annotator_evaluation_enabled.py} (59%) delete mode 100644 label_studio/projects/migrations/0035_project_annotator_evaluation_enabled_and_more.py diff --git a/label_studio/projects/api.py b/label_studio/projects/api.py index 35c5c0d5f420..9219a1324d52 100644 --- a/label_studio/projects/api.py +++ b/label_studio/projects/api.py @@ -308,7 +308,7 @@ def get_queryset(self): 'total_predictions_number': 0, 'sampling': 'Sequential sampling', 'show_ground_truth_first': True, - 'show_ground_truth_always': False, + 'annotator_evaluation_enabled': False, 'show_overlap_first': True, 'overlap_cohort_percentage': 100, 'task_data_login': 'user', diff --git a/label_studio/projects/functions/next_task.py b/label_studio/projects/functions/next_task.py index 50c65155a414..9f5a8f9d5b18 100644 --- a/label_studio/projects/functions/next_task.py +++ b/label_studio/projects/functions/next_task.py @@ -17,14 +17,14 @@ # Hook for GT-first gating (Enterprise can override via settings) -def _oss_should_attempt_gt_first(user: User, project: Project) -> bool: - # Open-source default: if project enables GT-first, allow it without onboarding gates - return bool(project.show_ground_truth_first) +def _lso_should_attempt_gt_first(user: User, project: Project) -> bool: + # Open-source default: if project enables annotator evaluation, allow it without onboarding gates + return bool(project.annotator_evaluation_enabled) get_tasks_agreement_queryset = load_func(settings.GET_TASKS_AGREEMENT_QUERYSET) should_attempt_ground_truth_first = ( - load_func(settings.SHOULD_ATTEMPT_GROUND_TRUTH_FIRST) or _oss_should_attempt_gt_first + load_func(settings.SHOULD_ATTEMPT_GROUND_TRUTH_FIRST) or _lso_should_attempt_gt_first ) @@ -78,10 +78,10 @@ def _try_tasks_with_overlap(tasks: QuerySet[Task]) -> Tuple[Union[Task, None], Q def _try_breadth_first(tasks: QuerySet[Task], user: User, project: Project) -> Union[Task, None]: """Try to find tasks with maximum amount of annotations, since we are trying to label tasks as fast as possible""" - # Exclude ground truth annotations from the count when not in onboarding mode or show_ground_truth_always mode + # Exclude ground truth annotations from the count when not in annotator evaluation mode # to prevent GT tasks from being prioritized via breadth-first logic annotation_filter = ~Q(annotations__completed_by=user) - if not project.show_ground_truth_first and not project.show_ground_truth_always: + if not project.annotator_evaluation_enabled: annotation_filter &= ~Q(annotations__ground_truth=True) tasks = tasks.annotate(annotations_count=Count('annotations', filter=annotation_filter)) @@ -166,7 +166,7 @@ def get_not_solved_tasks_qs( prepared_tasks: QuerySet[Task], assigned_flag: Union[bool, None], queue_info: str, - allow_gt_first: bool, + attempt_gt_first: bool, ) -> Tuple[QuerySet[Task], List[int], str, bool]: user_solved_tasks_array = user.annotations.filter(project=project, task__isnull=False) user_solved_tasks_array = user_solved_tasks_array.distinct().values_list('task__pk', flat=True) @@ -190,7 +190,6 @@ def get_not_solved_tasks_qs( and get_tasks_agreement_queryset and user.is_project_annotator(project) ): - # Onboarding mode (GT-first) should keep GT tasks eligible regardless of is_labeled/agreement qs = get_tasks_agreement_queryset(not_solved_tasks) qs = qs.annotate(annotators=Count('annotations__completed_by', distinct=True)) @@ -199,13 +198,10 @@ def get_not_solved_tasks_qs( ) capacity_pred = Q(annotators__lt=F('overlap') + (lse_project.max_additional_annotators_assignable or 0)) - # Always include ground truth tasks in the query - if project.show_ground_truth_first or project.show_ground_truth_always: + if project.annotator_evaluation_enabled: + # Include ground truth tasks in the query if annotator evaluation is enabled qs = _annotate_has_ground_truths(qs) - # Keep all GT tasks + apply low-agreement+capacity to the rest. For sure, we can do: - # - if user.solved_tasks_array.count < lse_project.annotator_evaluation_minimum_tasks - # - else, apply low-agreement+capacity to the rest (maybe performance will be better) - # but it's a question - what is better here. This version is simpler at least from the code perspective. + # Keep all GT tasks + apply low-agreement+capacity to the rest. not_solved_tasks = qs.filter(Q(has_ground_truths=True) | (low_agreement_pred & capacity_pred)) else: not_solved_tasks = qs.filter(low_agreement_pred & capacity_pred) @@ -214,13 +210,14 @@ def get_not_solved_tasks_qs( # otherwise, filtering out completed tasks is sufficient else: - if not allow_gt_first: - if project.show_ground_truth_always: - # Include ground truth tasks in the query if show_ground_truth_always is enabled + if not attempt_gt_first: + # Outside of onboarding window + if project.annotator_evaluation_enabled: + # Include ground truth tasks in the query if outside of onboarding window and annotator evaluation is enabled not_solved_tasks = _annotate_has_ground_truths(not_solved_tasks) not_solved_tasks = not_solved_tasks.filter(Q(is_labeled=False) | Q(has_ground_truths=True)) - # ignore tasks that are already labeled when GT-first is NOT allowed and no need to include GT tasks always else: + # Ignore tasks that are already labeled when outside of onboarding window and annotator evaluation is not enabled not_solved_tasks = not_solved_tasks.filter(is_labeled=False) if not flag_set('fflag_fix_back_lsdv_4523_show_overlap_first_order_27022023_short'): @@ -251,7 +248,7 @@ def get_next_task_without_dm_queue( not_solved_tasks: QuerySet, assigned_flag: Union[bool, None], prioritized_low_agreement: bool, - allow_gt_first: bool, + attempt_gt_first: bool, ) -> Tuple[Union[Task, None], bool, str]: next_task = None use_task_lock = True @@ -272,8 +269,8 @@ def get_next_task_without_dm_queue( use_task_lock = False queue_info += (' & ' if queue_info else '') + 'Task lock' - # Ground truth: use precomputed gating for GT-first - if not next_task and allow_gt_first: + # Ground truth: attempt to label ground truth tasks in onboarding window + if not next_task and attempt_gt_first: logger.debug(f'User={user} tries ground truth from prepared tasks') next_task = _try_ground_truth(not_solved_tasks, project, user) if next_task: @@ -385,16 +382,16 @@ def get_next_task( use_task_lock = True queue_info = '' - # Ground truth: label GT first only during onboarding window for user (gated by min tasks and min score) - allow_gt_first = should_attempt_ground_truth_first(user, project) + # Ground truth: label GT first only during onboarding window for user (gated by onboarding task number) + attempt_gt_first = should_attempt_ground_truth_first(user, project) not_solved_tasks, user_solved_tasks_array, queue_info, prioritized_low_agreement = get_not_solved_tasks_qs( - user, project, prepared_tasks, assigned_flag, queue_info, allow_gt_first + user, project, prepared_tasks, assigned_flag, queue_info, attempt_gt_first ) if not dm_queue: next_task, use_task_lock, queue_info = get_next_task_without_dm_queue( - user, project, not_solved_tasks, assigned_flag, prioritized_low_agreement, allow_gt_first + user, project, not_solved_tasks, assigned_flag, prioritized_low_agreement, attempt_gt_first ) if flag_set('fflag_fix_back_lsdv_4523_show_overlap_first_order_27022023_short'): @@ -459,8 +456,7 @@ def get_next_task( 'maximum_annotations': project.maximum_annotations, 'skip_queue': project.skip_queue, 'sampling': project.sampling, - 'show_ground_truth_first': project.show_ground_truth_first, - 'show_ground_truth_always': project.show_ground_truth_always, + 'annotator_evaluation_enabled': project.annotator_evaluation_enabled, 'show_overlap_first': project.show_overlap_first, 'overlap_cohort_percentage': project.overlap_cohort_percentage, 'project_id': project.id, diff --git a/label_studio/projects/migrations/0034_project_show_ground_truth_always.py b/label_studio/projects/migrations/0034_project_annotator_evaluation_enabled.py similarity index 59% rename from label_studio/projects/migrations/0034_project_show_ground_truth_always.py rename to label_studio/projects/migrations/0034_project_annotator_evaluation_enabled.py index 3edae82c905a..832336d58722 100644 --- a/label_studio/projects/migrations/0034_project_show_ground_truth_always.py +++ b/label_studio/projects/migrations/0034_project_annotator_evaluation_enabled.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.14 on 2025-11-28 15:45 +# Generated by Django 5.1.14 on 2025-12-05 19:24 from django.db import migrations, models @@ -12,12 +12,12 @@ class Migration(migrations.Migration): operations = [ migrations.AddField( model_name="project", - name="show_ground_truth_always", + name="annotator_evaluation_enabled", field=models.BooleanField( db_default=False, default=False, - help_text="When enabled, ground truth tasks will be shown to all annotators regardless of overlap", - verbose_name="show ground truth always", + help_text="Enable annotator evaluation for the project", + verbose_name="annotator evaluation enabled", ), ), ] diff --git a/label_studio/projects/migrations/0035_project_annotator_evaluation_enabled_and_more.py b/label_studio/projects/migrations/0035_project_annotator_evaluation_enabled_and_more.py deleted file mode 100644 index d87c41c636dc..000000000000 --- a/label_studio/projects/migrations/0035_project_annotator_evaluation_enabled_and_more.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 5.1.14 on 2025-12-04 23:11 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("projects", "0034_project_show_ground_truth_always"), - ] - - operations = [ - migrations.AddField( - model_name="project", - name="annotator_evaluation_enabled", - field=models.BooleanField( - db_default=False, - default=False, - help_text="Enable annotator evaluation for the project", - verbose_name="annotator evaluation enabled", - ), - ), - migrations.AddField( - model_name="project", - name="annotator_evaluation_onboarding_tasks", - field=models.PositiveIntegerField( - db_default=0, - default=0, - help_text="Number of onboarding tasks for annotator evaluation", - verbose_name="annotator evaluation onboarding tasks", - ), - ), - ] diff --git a/label_studio/projects/models.py b/label_studio/projects/models.py index 57dc83f77520..a3aa31eec689 100644 --- a/label_studio/projects/models.py +++ b/label_studio/projects/models.py @@ -321,26 +321,12 @@ class SkipQueue(models.TextChoices): help_text='Onboarding mode (true): show ground truth tasks first in the labeling stream', ) - # TODO: Remove this - show_ground_truth_always = models.BooleanField( - _('show ground truth always'), - default=False, - db_default=False, - help_text='When enabled, ground truth tasks will be shown to all annotators regardless of overlap', - ) - annotator_evaluation_enabled = models.BooleanField( _('annotator evaluation enabled'), default=False, db_default=False, help_text='Enable annotator evaluation for the project', ) - annotator_evaluation_onboarding_tasks = models.PositiveIntegerField( - _('annotator evaluation onboarding tasks'), - default=0, - db_default=0, - help_text='Number of onboarding tasks for annotator evaluation', - ) show_overlap_first = models.BooleanField(_('show overlap first'), default=False) overlap_cohort_percentage = models.IntegerField(_('overlap_cohort_percentage'), default=100) diff --git a/label_studio/projects/serializers.py b/label_studio/projects/serializers.py index ee113914fedf..efd8ad9fa9fb 100644 --- a/label_studio/projects/serializers.py +++ b/label_studio/projects/serializers.py @@ -236,9 +236,7 @@ class Meta: 'total_predictions_number', 'sampling', 'show_ground_truth_first', - 'show_ground_truth_always', 'annotator_evaluation_enabled', - 'annotator_evaluation_onboarding_tasks', 'show_overlap_first', 'overlap_cohort_percentage', 'task_data_login', diff --git a/label_studio/tasks/models.py b/label_studio/tasks/models.py index 815106545019..dd49d7799255 100644 --- a/label_studio/tasks/models.py +++ b/label_studio/tasks/models.py @@ -289,11 +289,8 @@ def has_lock(self, user=None): """ from projects.functions.next_task import get_next_task_logging_level - if self.project.show_ground_truth_first or self.project.show_ground_truth_always: - # in show_ground_truth_first mode(onboarding) - # we ignore overlap setting for ground_truth tasks - # in show_ground_truth_always mode we ignore overlap setting for ground_truth tasks - # https://humansignal.atlassian.net/browse/LEAP-1963 + if self.project.annotator_evaluation_enabled: + # In annotator evaluation mode, ignore overlap setting for ground truth tasks if self.annotations.filter(ground_truth=True).exists(): return False diff --git a/label_studio/tests/data_manager/columns.tavern.yml b/label_studio/tests/data_manager/columns.tavern.yml index 77db054e0ec2..0f83f1a8cec2 100644 --- a/label_studio/tests/data_manager/columns.tavern.yml +++ b/label_studio/tests/data_manager/columns.tavern.yml @@ -42,7 +42,7 @@ stages: "start_training_on_annotation_update": false, "show_collab_predictions": true, "num_tasks_with_annotations": null, "task_number": null, "useful_annotation_number": null, "ground_truth_number": null, "skipped_annotations_number": null, "total_annotations_number": null, "total_predictions_number": null, "sampling": "Sequential sampling", - "show_ground_truth_first": false, "show_ground_truth_always": false, "show_overlap_first": false, "overlap_cohort_percentage": 100, + "show_ground_truth_first": false, "annotator_evaluation_enabled": false, "show_overlap_first": false, "overlap_cohort_percentage": 100, "task_data_login": null, "task_data_password": null, "control_weights": {"label": {"overall": 1.0, "type": "Choices", "labels": {"pos": 1.0, "neg": 1.0}}}, "parsed_label_config": { diff --git a/web/apps/labelstudio/src/config/ApiConfig.example.js b/web/apps/labelstudio/src/config/ApiConfig.example.js index f51ed96e5135..6edf71e4ba91 100644 --- a/web/apps/labelstudio/src/config/ApiConfig.example.js +++ b/web/apps/labelstudio/src/config/ApiConfig.example.js @@ -52,7 +52,7 @@ export const API_CONFIG = { total_predictions_number: 100, sampling: "Sequential sampling", show_ground_truth_first: false, - show_ground_truth_always: false, + annotator_evaluation_enabled: false, show_overlap_first: false, overlap_cohort_percentage: 100, task_data_login: null, diff --git a/web/apps/labelstudio/src/types/Project.d.ts b/web/apps/labelstudio/src/types/Project.d.ts index 1b8f8e4057af..f57eeaba7c0c 100644 --- a/web/apps/labelstudio/src/types/Project.d.ts +++ b/web/apps/labelstudio/src/types/Project.d.ts @@ -73,7 +73,7 @@ declare type APIProject = { total_predictions_number?: string; sampling?: "Sequential sampling" | "Uniform sampling" | "Uncertainty sampling" | null; show_ground_truth_first?: boolean; - show_ground_truth_always?: boolean; + annotator_evaluation_enabled?: boolean; show_overlap_first?: boolean; overlap_cohort_percentage?: number; From 2ae8516b8471dfcd376d887d880df544fae5d680 Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Fri, 5 Dec 2025 19:50:24 +0000 Subject: [PATCH 12/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/19974215346 --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 228e7d61442a..c3d88ca72a25 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "a4d603fc48ee9ddb632b35cb4c3a55fb73ec55be.zip", hash = "sha256:822fae74e0da2ad5190fd816fcd3a43e804da31f0c8cb851134a5f6d8e4a3833"}, + {file = "36011f32cfdcf21be69a479957c0a1e013ed4306.zip", hash = "sha256:deabe71793d8756028d0f0db8c0a5125099c1d278f93e43b16d00d9208551213"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/a4d603fc48ee9ddb632b35cb4c3a55fb73ec55be.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/36011f32cfdcf21be69a479957c0a1e013ed4306.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "54ec839b45af999b9e384b0022731e43ea18e3c42a7d1bdc90dc45287e5ff38b" +content-hash = "1732dc97f0ca47e8f000fb3882c4a8604b03bcbbff664bae0e6aeadf8ecec1d9" diff --git a/pyproject.toml b/pyproject.toml index 86621332232a..d8bc47da3dad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/a4d603fc48ee9ddb632b35cb4c3a55fb73ec55be.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/36011f32cfdcf21be69a479957c0a1e013ed4306.zip", ## HumanSignal repo dependencies :end ] From 9788e19de288958c27cc66f0a2899d96c68ad379 Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Fri, 5 Dec 2025 20:07:04 +0000 Subject: [PATCH 13/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/19974288596 --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index c3d88ca72a25..39ebc845e469 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "36011f32cfdcf21be69a479957c0a1e013ed4306.zip", hash = "sha256:deabe71793d8756028d0f0db8c0a5125099c1d278f93e43b16d00d9208551213"}, + {file = "cd6c6d98845167a0fbf636b374de38f805925f7e.zip", hash = "sha256:89e14e532c6f6ebe2e493cc2aaddcec7fccb8d290ce31886a4319276b682ad00"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/36011f32cfdcf21be69a479957c0a1e013ed4306.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/cd6c6d98845167a0fbf636b374de38f805925f7e.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "1732dc97f0ca47e8f000fb3882c4a8604b03bcbbff664bae0e6aeadf8ecec1d9" +content-hash = "044e1a17fafcf0411a85710519aafbc990826be1d7c4586822cef4c5a4a7310c" diff --git a/pyproject.toml b/pyproject.toml index d8bc47da3dad..d0c062e095ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/36011f32cfdcf21be69a479957c0a1e013ed4306.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/cd6c6d98845167a0fbf636b374de38f805925f7e.zip", ## HumanSignal repo dependencies :end ] From 764e408a9a5f12b0e9fcb9248db6d407b2da2e57 Mon Sep 17 00:00:00 2001 From: mcanu Date: Mon, 8 Dec 2025 14:20:23 +0000 Subject: [PATCH 14/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20031202667 From 2c0d2cf4c33ead9c04af7facd07683f70b78caf8 Mon Sep 17 00:00:00 2001 From: Marcel Canu Date: Mon, 8 Dec 2025 19:08:05 -0300 Subject: [PATCH 15/32] Deprecated show_ground_truth_first --- docs/source/guide/webhook_reference.md | 7 ------- label_studio/projects/api.py | 3 +-- label_studio/projects/functions/next_task.md | 6 ++---- label_studio/projects/functions/next_task.py | 10 ++++++---- .../0034_project_annotator_evaluation_enabled.py | 6 +++--- label_studio/projects/models.py | 4 ++-- label_studio/projects/serializers.py | 2 ++ label_studio/tests/data_manager/columns.tavern.yml | 2 +- web/apps/labelstudio/src/config/ApiConfig.example.js | 3 +-- web/apps/labelstudio/src/types/Project.d.ts | 1 - 10 files changed, 18 insertions(+), 26 deletions(-) diff --git a/docs/source/guide/webhook_reference.md b/docs/source/guide/webhook_reference.md index 0bdebad2f1e4..080f984d4cb1 100644 --- a/docs/source/guide/webhook_reference.md +++ b/docs/source/guide/webhook_reference.md @@ -129,7 +129,6 @@ The webhook payload includes the name of the action and some additional task dat "created_at": "2021-08-17T13:49:34.326416Z", "updated_at": "2021-08-17T13:49:35.911271Z", "sampling": "Sequential sampling", - "show_ground_truth_first": true, "show_overlap_first": true, "overlap_cohort_percentage": 100, "task_data_login": null, @@ -219,7 +218,6 @@ Sent when a task is deleted from Label Studio. See how to [set up a webhook for "created_at": "2021-08-17T13:49:34.326416Z", "updated_at": "2021-08-17T13:52:09.334425Z", "sampling": "Sequential sampling", - "show_ground_truth_first": true, "show_overlap_first": true, "overlap_cohort_percentage": 100, "task_data_login": null, @@ -328,7 +326,6 @@ The webhook payload includes the name of the action and some additional annotati "created_at": "2021-08-17T13:49:34.326416Z", "updated_at": "2021-08-17T13:52:09.334425Z", "sampling": "Sequential sampling", - "show_ground_truth_first": true, "show_overlap_first": true, "overlap_cohort_percentage": 100, "task_data_login": null, @@ -463,7 +460,6 @@ The webhook payload includes the name of the action and some additional annotati "created_at": "2021-08-12T14:15:01.744507Z", "updated_at": "2021-08-17T13:35:25.697471Z", "sampling": "Sequential sampling", - "show_ground_truth_first": true, "show_overlap_first": true, "overlap_cohort_percentage": 100, "task_data_login": null, @@ -538,7 +534,6 @@ Sent when an annotation is deleted. See how to [set up a webhook for this event] "created_at": "2021-08-17T13:49:34.326416Z", "updated_at": "2021-08-17T13:52:09.334425Z", "sampling": "Sequential sampling", - "show_ground_truth_first": true, "show_overlap_first": true, "overlap_cohort_percentage": 100, "task_data_login": null, @@ -603,7 +598,6 @@ The webhook payload includes the name of the action and some additional project "created_at": "2021-08-17T13:55:58.809065Z", "updated_at": "2021-08-17T13:55:58.809098Z", "sampling": "Sequential sampling", - "show_ground_truth_first": true, "show_overlap_first": true, "overlap_cohort_percentage": 100, "task_data_login": null, @@ -674,7 +668,6 @@ The webhook payload includes the name of the action and some additional project "created_at": "2021-08-12T14:15:01.744507Z", "updated_at": "2021-08-17T13:39:14.054849Z", "sampling": "Sequential sampling", - "show_ground_truth_first": true, "show_overlap_first": true, "overlap_cohort_percentage": 100, "task_data_login": null, diff --git a/label_studio/projects/api.py b/label_studio/projects/api.py index 9219a1324d52..0b5232f944d1 100644 --- a/label_studio/projects/api.py +++ b/label_studio/projects/api.py @@ -307,8 +307,7 @@ def get_queryset(self): 'total_annotations_number': 10, 'total_predictions_number': 0, 'sampling': 'Sequential sampling', - 'show_ground_truth_first': True, - 'annotator_evaluation_enabled': False, + 'annotator_evaluation_enabled': True, 'show_overlap_first': True, 'overlap_cohort_percentage': 100, 'task_data_login': 'user', diff --git a/label_studio/projects/functions/next_task.md b/label_studio/projects/functions/next_task.md index 15b5154722e4..f5d4b983db4d 100644 --- a/label_studio/projects/functions/next_task.md +++ b/label_studio/projects/functions/next_task.md @@ -21,7 +21,7 @@ flowchart TD B3 -- no --> B4{"LSE low-agreement path?
fflag OPTIC-161
agreement_threshold set
user is annotator"} B4 -- yes --> B6["Filter by agreement threshold
and annotator capacity"] --> B7[Optionally prioritize by low agreement] - B4 -- no --> B8{"Evaluation mode?
fflag ALL-LEAP-1825
show_ground_truth_first"} + B4 -- no --> B8{"Evaluation mode?
fflag ALL-LEAP-1825
annotator_evaluation_enabled"} B8 -- yes --> B7 B8 -- no --> B9[Filter: is_labeled=false] --> B7 end @@ -69,9 +69,7 @@ flowchart TD ### GT-first gating - `should_attempt_ground_truth_first(user, project)` returns true when: - - `show_ground_truth_first=True` and either no `lse_project` or `annotator_evaluation_minimum_tasks` is not set, or - - the user's completed GT-equipped tasks < `annotator_evaluation_minimum_tasks`, or - - minimum tasks reached but the user's GT agreement score is missing or below `annotator_evaluation_minimum_score` (percent). + - `annotator_evaluation_enabled=True` and `annotator_evaluation_onboarding_tasks > 0` and the user's completed GT-equipped tasks < `annotator_evaluation_onboarding_tasks`. - Otherwise returns false (GT-first disabled; proceed via low-agreement/overlap/sampling). ## Queue labels appended to response diff --git a/label_studio/projects/functions/next_task.py b/label_studio/projects/functions/next_task.py index 9f5a8f9d5b18..6d5163cf3e36 100644 --- a/label_studio/projects/functions/next_task.py +++ b/label_studio/projects/functions/next_task.py @@ -75,13 +75,15 @@ def _try_tasks_with_overlap(tasks: QuerySet[Task]) -> Tuple[Union[Task, None], Q return None, tasks.filter(overlap=1) -def _try_breadth_first(tasks: QuerySet[Task], user: User, project: Project) -> Union[Task, None]: +def _try_breadth_first( + tasks: QuerySet[Task], user: User, project: Project, attempt_gt_first: bool = False +) -> Union[Task, None]: """Try to find tasks with maximum amount of annotations, since we are trying to label tasks as fast as possible""" - # Exclude ground truth annotations from the count when not in annotator evaluation mode + # Exclude ground truth annotations from the count when not in onboarding window # to prevent GT tasks from being prioritized via breadth-first logic annotation_filter = ~Q(annotations__completed_by=user) - if not project.annotator_evaluation_enabled: + if not attempt_gt_first: annotation_filter &= ~Q(annotations__ground_truth=True) tasks = tasks.annotate(annotations_count=Count('annotations', filter=annotation_filter)) @@ -287,7 +289,7 @@ def get_next_task_without_dm_queue( if not next_task and project.maximum_annotations > 1: # if there are already labeled tasks, but task.overlap still < project.maximum_annotations, randomly sampling from them logger.debug(f'User={user} tries depth first from prepared tasks') - next_task = _try_breadth_first(not_solved_tasks, user, project) + next_task = _try_breadth_first(not_solved_tasks, user, project, attempt_gt_first) if next_task: queue_info += (' & ' if queue_info else '') + 'Breadth first queue' diff --git a/label_studio/projects/migrations/0034_project_annotator_evaluation_enabled.py b/label_studio/projects/migrations/0034_project_annotator_evaluation_enabled.py index 832336d58722..54cc5c02beb5 100644 --- a/label_studio/projects/migrations/0034_project_annotator_evaluation_enabled.py +++ b/label_studio/projects/migrations/0034_project_annotator_evaluation_enabled.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.14 on 2025-12-05 19:24 +# Generated by Django 5.1.14 on 2025-12-08 18:59 from django.db import migrations, models @@ -14,8 +14,8 @@ class Migration(migrations.Migration): model_name="project", name="annotator_evaluation_enabled", field=models.BooleanField( - db_default=False, - default=False, + db_default=True, + default=True, help_text="Enable annotator evaluation for the project", verbose_name="annotator evaluation enabled", ), diff --git a/label_studio/projects/models.py b/label_studio/projects/models.py index faaf5c3630e5..f1df498232eb 100644 --- a/label_studio/projects/models.py +++ b/label_studio/projects/models.py @@ -323,8 +323,8 @@ class SkipQueue(models.TextChoices): annotator_evaluation_enabled = models.BooleanField( _('annotator evaluation enabled'), - default=False, - db_default=False, + default=True, + db_default=True, help_text='Enable annotator evaluation for the project', ) diff --git a/label_studio/projects/serializers.py b/label_studio/projects/serializers.py index efd8ad9fa9fb..f0717ef7d9a0 100644 --- a/label_studio/projects/serializers.py +++ b/label_studio/projects/serializers.py @@ -3,6 +3,7 @@ import bleach from constants import SAFE_HTML_ATTRIBUTES, SAFE_HTML_TAGS from django.db.models import Q +from drf_spectacular.utils import extend_schema_serializer from fsm.serializer_fields import FSMStateField from label_studio_sdk.label_interface import LabelInterface from label_studio_sdk.label_interface.control_tags import ( @@ -43,6 +44,7 @@ def __call__(self, serializer_field): return serializer_field.context.get('created_by') +@extend_schema_serializer(deprecate_fields=['show_ground_truth_first']) class ProjectSerializer(FlexFieldsModelSerializer): """Serializer get numbers from project queryset annotation, make sure, that you use correct one(Project.objects.with_counts()) diff --git a/label_studio/tests/data_manager/columns.tavern.yml b/label_studio/tests/data_manager/columns.tavern.yml index 0f83f1a8cec2..bb1be9aacfef 100644 --- a/label_studio/tests/data_manager/columns.tavern.yml +++ b/label_studio/tests/data_manager/columns.tavern.yml @@ -42,7 +42,7 @@ stages: "start_training_on_annotation_update": false, "show_collab_predictions": true, "num_tasks_with_annotations": null, "task_number": null, "useful_annotation_number": null, "ground_truth_number": null, "skipped_annotations_number": null, "total_annotations_number": null, "total_predictions_number": null, "sampling": "Sequential sampling", - "show_ground_truth_first": false, "annotator_evaluation_enabled": false, "show_overlap_first": false, "overlap_cohort_percentage": 100, + "show_ground_truth_first": false, "annotator_evaluation_enabled": true, "show_overlap_first": false, "overlap_cohort_percentage": 100, "task_data_login": null, "task_data_password": null, "control_weights": {"label": {"overall": 1.0, "type": "Choices", "labels": {"pos": 1.0, "neg": 1.0}}}, "parsed_label_config": { diff --git a/web/apps/labelstudio/src/config/ApiConfig.example.js b/web/apps/labelstudio/src/config/ApiConfig.example.js index 6edf71e4ba91..a94738cbef14 100644 --- a/web/apps/labelstudio/src/config/ApiConfig.example.js +++ b/web/apps/labelstudio/src/config/ApiConfig.example.js @@ -51,8 +51,7 @@ export const API_CONFIG = { total_annotations_number: 300, total_predictions_number: 100, sampling: "Sequential sampling", - show_ground_truth_first: false, - annotator_evaluation_enabled: false, + annotator_evaluation_enabled: true, show_overlap_first: false, overlap_cohort_percentage: 100, task_data_login: null, diff --git a/web/apps/labelstudio/src/types/Project.d.ts b/web/apps/labelstudio/src/types/Project.d.ts index f57eeaba7c0c..c2363ad5b5e9 100644 --- a/web/apps/labelstudio/src/types/Project.d.ts +++ b/web/apps/labelstudio/src/types/Project.d.ts @@ -72,7 +72,6 @@ declare type APIProject = { /** Total predictions number in project including skipped_annotations_number and ground_truth_number. */ total_predictions_number?: string; sampling?: "Sequential sampling" | "Uniform sampling" | "Uncertainty sampling" | null; - show_ground_truth_first?: boolean; annotator_evaluation_enabled?: boolean; show_overlap_first?: boolean; overlap_cohort_percentage?: number; From ebce42e73863d59a3945841a57895234ebd3cbfc Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Mon, 8 Dec 2025 22:16:34 +0000 Subject: [PATCH 16/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20044558200 --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 39ebc845e469..49b0a8220069 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "cd6c6d98845167a0fbf636b374de38f805925f7e.zip", hash = "sha256:89e14e532c6f6ebe2e493cc2aaddcec7fccb8d290ce31886a4319276b682ad00"}, + {file = "fc84d067c5dcddfde2282bbb96f42e82bd35d087.zip", hash = "sha256:cdde12fa23c2c81d0cc90ea465b308fbbbd241a73c981e1379249c98012702c2"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/cd6c6d98845167a0fbf636b374de38f805925f7e.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/fc84d067c5dcddfde2282bbb96f42e82bd35d087.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "044e1a17fafcf0411a85710519aafbc990826be1d7c4586822cef4c5a4a7310c" +content-hash = "e36a9f230c952d94b37382f4806503ea53e8473a10d1c80e912cdd82795f9ded" diff --git a/pyproject.toml b/pyproject.toml index d0c062e095ba..c5197ee92ea6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/cd6c6d98845167a0fbf636b374de38f805925f7e.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/fc84d067c5dcddfde2282bbb96f42e82bd35d087.zip", ## HumanSignal repo dependencies :end ] From da019ac1378387543939d07e562f6e184aa0d8ba Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Mon, 8 Dec 2025 22:20:13 +0000 Subject: [PATCH 17/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20044652944 --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 49b0a8220069..b4256da74c9c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "fc84d067c5dcddfde2282bbb96f42e82bd35d087.zip", hash = "sha256:cdde12fa23c2c81d0cc90ea465b308fbbbd241a73c981e1379249c98012702c2"}, + {file = "f3856927a45d83b655045b35f042af84e7d91b6c.zip", hash = "sha256:85bd9d6020a1479c93879b53beaedf3ff038d2b677ac0d6c7d33c9c588c8e14b"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/fc84d067c5dcddfde2282bbb96f42e82bd35d087.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/f3856927a45d83b655045b35f042af84e7d91b6c.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "e36a9f230c952d94b37382f4806503ea53e8473a10d1c80e912cdd82795f9ded" +content-hash = "1fa0079e32bc3b6c7cab29217e997badcafdeded3612f4db03856c9ef761577a" diff --git a/pyproject.toml b/pyproject.toml index c5197ee92ea6..6fb206d09041 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/fc84d067c5dcddfde2282bbb96f42e82bd35d087.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/f3856927a45d83b655045b35f042af84e7d91b6c.zip", ## HumanSignal repo dependencies :end ] From 7af4a7ea4e3894365ccbfdefedfb318683edcaec Mon Sep 17 00:00:00 2001 From: Marcel Canu Date: Mon, 8 Dec 2025 19:31:06 -0300 Subject: [PATCH 18/32] Fix test --- label_studio/tests/data_export.tavern.yml | 1 + label_studio/tests/shared_stages.yml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/label_studio/tests/data_export.tavern.yml b/label_studio/tests/data_export.tavern.yml index 7550e99396a0..13b7ae90a15c 100644 --- a/label_studio/tests/data_export.tavern.yml +++ b/label_studio/tests/data_export.tavern.yml @@ -265,6 +265,7 @@ stages: label_config: title: Test Draft 1 show_collab_predictions: true + annotator_evaluation_enabled: true method: POST url: '{django_live_url}/api/projects' response: diff --git a/label_studio/tests/shared_stages.yml b/label_studio/tests/shared_stages.yml index 90a4bebb9c12..fe35d1ba315f 100644 --- a/label_studio/tests/shared_stages.yml +++ b/label_studio/tests/shared_stages.yml @@ -40,6 +40,7 @@ stages: value="pos"/> title: Test Draft 1 show_collab_predictions: true + annotator_evaluation_enabled: true method: POST url: '{django_live_url}/api/projects' response: @@ -54,6 +55,7 @@ stages: label_config: title: Test Draft 1 show_collab_predictions: true + annotator_evaluation_enabled: true method: POST url: '{django_live_url}/api/projects' response: From 3e5ee9a7a6eaa8a5c8bde457dfb4d5cafe908459 Mon Sep 17 00:00:00 2001 From: mcanu Date: Mon, 8 Dec 2025 22:34:40 +0000 Subject: [PATCH 19/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20045038930 From 12275ef534dd663df9f22013d2324d4e82c33756 Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Mon, 8 Dec 2025 22:44:48 +0000 Subject: [PATCH 20/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20045264167 --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index b4256da74c9c..0332aa4bdcce 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "f3856927a45d83b655045b35f042af84e7d91b6c.zip", hash = "sha256:85bd9d6020a1479c93879b53beaedf3ff038d2b677ac0d6c7d33c9c588c8e14b"}, + {file = "ec55c3a7d9dbdc5c5df7fe64db03539a86612ef0.zip", hash = "sha256:fe6eb16b93a54d24748870b3f976e8eee3f944f8632a04217ea0fb672bac940a"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/f3856927a45d83b655045b35f042af84e7d91b6c.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/ec55c3a7d9dbdc5c5df7fe64db03539a86612ef0.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "1fa0079e32bc3b6c7cab29217e997badcafdeded3612f4db03856c9ef761577a" +content-hash = "facc38aba5df712c801d8e66954393b8e612ffb9e85d312b5ec034171d63a5f4" diff --git a/pyproject.toml b/pyproject.toml index 6fb206d09041..5218917eb679 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/f3856927a45d83b655045b35f042af84e7d91b6c.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/ec55c3a7d9dbdc5c5df7fe64db03539a86612ef0.zip", ## HumanSignal repo dependencies :end ] From 256b4b0f7b24d4017a7507b92b8d4708063cbd06 Mon Sep 17 00:00:00 2001 From: mcanu Date: Tue, 9 Dec 2025 00:56:19 +0000 Subject: [PATCH 21/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20048026880 From 719e00eda3521e365ba0046f29f97de3e849a67a Mon Sep 17 00:00:00 2001 From: Marcel Canu Date: Tue, 9 Dec 2025 18:41:57 -0300 Subject: [PATCH 22/32] annotator_evaluation_enabled default to False --- label_studio/projects/api.py | 2 +- .../migrations/0034_project_annotator_evaluation_enabled.py | 6 +++--- label_studio/projects/models.py | 6 +++--- label_studio/tests/data_export.tavern.yml | 1 - label_studio/tests/data_manager/columns.tavern.yml | 2 +- label_studio/tests/shared_stages.yml | 1 - web/apps/labelstudio/src/config/ApiConfig.example.js | 2 +- 7 files changed, 9 insertions(+), 11 deletions(-) diff --git a/label_studio/projects/api.py b/label_studio/projects/api.py index 0b5232f944d1..f4cc192bc231 100644 --- a/label_studio/projects/api.py +++ b/label_studio/projects/api.py @@ -307,7 +307,7 @@ def get_queryset(self): 'total_annotations_number': 10, 'total_predictions_number': 0, 'sampling': 'Sequential sampling', - 'annotator_evaluation_enabled': True, + 'annotator_evaluation_enabled': False, 'show_overlap_first': True, 'overlap_cohort_percentage': 100, 'task_data_login': 'user', diff --git a/label_studio/projects/migrations/0034_project_annotator_evaluation_enabled.py b/label_studio/projects/migrations/0034_project_annotator_evaluation_enabled.py index 54cc5c02beb5..6159714e9815 100644 --- a/label_studio/projects/migrations/0034_project_annotator_evaluation_enabled.py +++ b/label_studio/projects/migrations/0034_project_annotator_evaluation_enabled.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.14 on 2025-12-08 18:59 +# Generated by Django 5.1.14 on 2025-12-09 21:37 from django.db import migrations, models @@ -14,8 +14,8 @@ class Migration(migrations.Migration): model_name="project", name="annotator_evaluation_enabled", field=models.BooleanField( - db_default=True, - default=True, + db_default=False, + default=False, help_text="Enable annotator evaluation for the project", verbose_name="annotator evaluation enabled", ), diff --git a/label_studio/projects/models.py b/label_studio/projects/models.py index 53bb8750874c..ef908c641ea1 100644 --- a/label_studio/projects/models.py +++ b/label_studio/projects/models.py @@ -316,7 +316,7 @@ class SkipQueue(models.TextChoices): max_length=100, choices=SkipQueue.choices, null=True, default=SkipQueue.REQUEUE_FOR_OTHERS ) - # Deprecated + # Deprecated in favor of annotator_evaluation_enabled show_ground_truth_first = models.BooleanField( _('show ground truth first'), default=False, @@ -325,8 +325,8 @@ class SkipQueue(models.TextChoices): annotator_evaluation_enabled = models.BooleanField( _('annotator evaluation enabled'), - default=True, - db_default=True, + default=False, + db_default=False, help_text='Enable annotator evaluation for the project', ) diff --git a/label_studio/tests/data_export.tavern.yml b/label_studio/tests/data_export.tavern.yml index 13b7ae90a15c..7550e99396a0 100644 --- a/label_studio/tests/data_export.tavern.yml +++ b/label_studio/tests/data_export.tavern.yml @@ -265,7 +265,6 @@ stages: label_config: title: Test Draft 1 show_collab_predictions: true - annotator_evaluation_enabled: true method: POST url: '{django_live_url}/api/projects' response: diff --git a/label_studio/tests/data_manager/columns.tavern.yml b/label_studio/tests/data_manager/columns.tavern.yml index bb1be9aacfef..0f83f1a8cec2 100644 --- a/label_studio/tests/data_manager/columns.tavern.yml +++ b/label_studio/tests/data_manager/columns.tavern.yml @@ -42,7 +42,7 @@ stages: "start_training_on_annotation_update": false, "show_collab_predictions": true, "num_tasks_with_annotations": null, "task_number": null, "useful_annotation_number": null, "ground_truth_number": null, "skipped_annotations_number": null, "total_annotations_number": null, "total_predictions_number": null, "sampling": "Sequential sampling", - "show_ground_truth_first": false, "annotator_evaluation_enabled": true, "show_overlap_first": false, "overlap_cohort_percentage": 100, + "show_ground_truth_first": false, "annotator_evaluation_enabled": false, "show_overlap_first": false, "overlap_cohort_percentage": 100, "task_data_login": null, "task_data_password": null, "control_weights": {"label": {"overall": 1.0, "type": "Choices", "labels": {"pos": 1.0, "neg": 1.0}}}, "parsed_label_config": { diff --git a/label_studio/tests/shared_stages.yml b/label_studio/tests/shared_stages.yml index fe35d1ba315f..261ff0229b1b 100644 --- a/label_studio/tests/shared_stages.yml +++ b/label_studio/tests/shared_stages.yml @@ -55,7 +55,6 @@ stages: label_config: title: Test Draft 1 show_collab_predictions: true - annotator_evaluation_enabled: true method: POST url: '{django_live_url}/api/projects' response: diff --git a/web/apps/labelstudio/src/config/ApiConfig.example.js b/web/apps/labelstudio/src/config/ApiConfig.example.js index a94738cbef14..b9de7c1f9ba7 100644 --- a/web/apps/labelstudio/src/config/ApiConfig.example.js +++ b/web/apps/labelstudio/src/config/ApiConfig.example.js @@ -51,7 +51,7 @@ export const API_CONFIG = { total_annotations_number: 300, total_predictions_number: 100, sampling: "Sequential sampling", - annotator_evaluation_enabled: true, + annotator_evaluation_enabled: false, show_overlap_first: false, overlap_cohort_percentage: 100, task_data_login: null, From efda0eefcfb89ed56eba319d364ec6543b3a7536 Mon Sep 17 00:00:00 2001 From: Marcel Canu Date: Tue, 9 Dec 2025 18:58:45 -0300 Subject: [PATCH 23/32] Fix columns test --- label_studio/tests/shared_stages.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/label_studio/tests/shared_stages.yml b/label_studio/tests/shared_stages.yml index 261ff0229b1b..90a4bebb9c12 100644 --- a/label_studio/tests/shared_stages.yml +++ b/label_studio/tests/shared_stages.yml @@ -40,7 +40,6 @@ stages: value="pos"/> title: Test Draft 1 show_collab_predictions: true - annotator_evaluation_enabled: true method: POST url: '{django_live_url}/api/projects' response: From 5ce366e3bedec4ea0c6d2088e92fe96ce0411cca Mon Sep 17 00:00:00 2001 From: mcanu Date: Wed, 10 Dec 2025 13:43:35 +0000 Subject: [PATCH 24/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20100599882 From 31f3007195efa7d5714933c2e4aeac0c664b33ab Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Wed, 10 Dec 2025 13:51:24 +0000 Subject: [PATCH 25/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20100847806 --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index abbb326f0443..65685e99b4ed 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. [[package]] name = "annotated-types" @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "ec55c3a7d9dbdc5c5df7fe64db03539a86612ef0.zip", hash = "sha256:fe6eb16b93a54d24748870b3f976e8eee3f944f8632a04217ea0fb672bac940a"}, + {file = "7f25518859cb682d3a4df049afc11660e7187aab.zip", hash = "sha256:e8b8191e34db3284c0ed914c53887d92dea976be3a810d9d2d96f014296c8121"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/ec55c3a7d9dbdc5c5df7fe64db03539a86612ef0.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/7f25518859cb682d3a4df049afc11660e7187aab.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "facc38aba5df712c801d8e66954393b8e612ffb9e85d312b5ec034171d63a5f4" +content-hash = "1d0eb16ea9c33df9a83b777f187c3e23894625da570feff7ad296ba31ffb7f80" diff --git a/pyproject.toml b/pyproject.toml index 5218917eb679..05cd61129a1f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/ec55c3a7d9dbdc5c5df7fe64db03539a86612ef0.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/7f25518859cb682d3a4df049afc11660e7187aab.zip", ## HumanSignal repo dependencies :end ] From 798c8d0a470a3c1c3c888509c58c48d0e368f109 Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Wed, 10 Dec 2025 13:55:06 +0000 Subject: [PATCH 26/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20100945769 --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 65685e99b4ed..90fb42c07c22 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "7f25518859cb682d3a4df049afc11660e7187aab.zip", hash = "sha256:e8b8191e34db3284c0ed914c53887d92dea976be3a810d9d2d96f014296c8121"}, + {file = "350e218a71ae2ea899e2362bee66aa32f6f595d0.zip", hash = "sha256:d9b5cb3144fa2cf62d7c6fa7060e0009f198e4d914f787bed0a7739822fd4f93"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/7f25518859cb682d3a4df049afc11660e7187aab.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/350e218a71ae2ea899e2362bee66aa32f6f595d0.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "1d0eb16ea9c33df9a83b777f187c3e23894625da570feff7ad296ba31ffb7f80" +content-hash = "b78e60751e595a41460d2bda5235191a6364b7e9602bedb34bd7ea564865498d" diff --git a/pyproject.toml b/pyproject.toml index 05cd61129a1f..ad13e003b49b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/7f25518859cb682d3a4df049afc11660e7187aab.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/350e218a71ae2ea899e2362bee66aa32f6f595d0.zip", ## HumanSignal repo dependencies :end ] From 254b3aff5742c4e048e389b936aa11bbabe5544c Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Thu, 11 Dec 2025 19:36:48 +0000 Subject: [PATCH 27/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20145073906 --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 90fb42c07c22..302618f7425c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "350e218a71ae2ea899e2362bee66aa32f6f595d0.zip", hash = "sha256:d9b5cb3144fa2cf62d7c6fa7060e0009f198e4d914f787bed0a7739822fd4f93"}, + {file = "c0a1a5b50feb9b058c30ec98192a0c908910a68e.zip", hash = "sha256:59160fb730fc8b7e4bdb98929070ca3924fc503e8d4aaffaa18a042288d21cbd"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/350e218a71ae2ea899e2362bee66aa32f6f595d0.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/c0a1a5b50feb9b058c30ec98192a0c908910a68e.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "b78e60751e595a41460d2bda5235191a6364b7e9602bedb34bd7ea564865498d" +content-hash = "b06e834ba4e5db44a4874d94e1e5ba98c998da96161067d1d7aed3339c40d19c" diff --git a/pyproject.toml b/pyproject.toml index ad13e003b49b..5ab35b6881cc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/350e218a71ae2ea899e2362bee66aa32f6f595d0.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/c0a1a5b50feb9b058c30ec98192a0c908910a68e.zip", ## HumanSignal repo dependencies :end ] From 86598f53a8a57036ee2e7ae311b2b8f0bc3fdaf3 Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Thu, 11 Dec 2025 19:45:04 +0000 Subject: [PATCH 28/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20145278941 --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 302618f7425c..ae92903db379 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "c0a1a5b50feb9b058c30ec98192a0c908910a68e.zip", hash = "sha256:59160fb730fc8b7e4bdb98929070ca3924fc503e8d4aaffaa18a042288d21cbd"}, + {file = "b0001d22d9ade6aa5dedeabdaa2bf57ffa3feb85.zip", hash = "sha256:2b53cd605d1b8edbf323dc87e7505d45db8bb739a1b3340cb87f204e5c1a631c"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/c0a1a5b50feb9b058c30ec98192a0c908910a68e.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/b0001d22d9ade6aa5dedeabdaa2bf57ffa3feb85.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "b06e834ba4e5db44a4874d94e1e5ba98c998da96161067d1d7aed3339c40d19c" +content-hash = "59f187fd5733570152f54b535788ff9db60907b57a9cff91a202a722895fe151" diff --git a/pyproject.toml b/pyproject.toml index 5ab35b6881cc..fc5071abde23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/c0a1a5b50feb9b058c30ec98192a0c908910a68e.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/b0001d22d9ade6aa5dedeabdaa2bf57ffa3feb85.zip", ## HumanSignal repo dependencies :end ] From b94d723b82d792ca6551b51d8099dea3e27649d3 Mon Sep 17 00:00:00 2001 From: mcanu Date: Fri, 12 Dec 2025 21:29:16 +0000 Subject: [PATCH 29/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20180337188 From 862d4b41c654ba29169ec7ae0a2acf8b863c2ca8 Mon Sep 17 00:00:00 2001 From: mcanu Date: Mon, 15 Dec 2025 13:47:18 +0000 Subject: [PATCH 30/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20234412494 From 9cee6e3aa14a99124c3c924a593abd120076bab2 Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Mon, 15 Dec 2025 19:15:08 +0000 Subject: [PATCH 31/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/20244404085 --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index ae92903db379..9e66a74d6350 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "b0001d22d9ade6aa5dedeabdaa2bf57ffa3feb85.zip", hash = "sha256:2b53cd605d1b8edbf323dc87e7505d45db8bb739a1b3340cb87f204e5c1a631c"}, + {file = "4295cf623e7d9381fccde297f2e2a79a5a3244e8.zip", hash = "sha256:97e881c5a2dc866042757e68302386ce9a92defa45764ca29e3754279ca10116"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/b0001d22d9ade6aa5dedeabdaa2bf57ffa3feb85.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/4295cf623e7d9381fccde297f2e2a79a5a3244e8.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "59f187fd5733570152f54b535788ff9db60907b57a9cff91a202a722895fe151" +content-hash = "c7ce0ffd5c557b08dfe02772db18b8fcfb5903779ee39eb3fd69f5a2fc2dbcd6" diff --git a/pyproject.toml b/pyproject.toml index fc5071abde23..df904f042ac2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/b0001d22d9ade6aa5dedeabdaa2bf57ffa3feb85.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/4295cf623e7d9381fccde297f2e2a79a5a3244e8.zip", ## HumanSignal repo dependencies :end ] From ad9e9517ca3fa9b9e7af42f09c44e4d16cd837e5 Mon Sep 17 00:00:00 2001 From: robot-ci-heartex Date: Tue, 16 Dec 2025 14:02:23 +0000 Subject: [PATCH 32/32] Sync Follow Merge dependencies Workflow run: https://github.com/HumanSignal/label-studio-enterprise/actions/runs/20270438305 --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9e66a74d6350..4ba10021b07d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. [[package]] name = "annotated-types" @@ -2131,7 +2131,7 @@ optional = false python-versions = ">=3.9,<4" groups = ["main"] files = [ - {file = "4295cf623e7d9381fccde297f2e2a79a5a3244e8.zip", hash = "sha256:97e881c5a2dc866042757e68302386ce9a92defa45764ca29e3754279ca10116"}, + {file = "8ce1b4f80f12780da5d07184e4bea25a5c05fe96.zip", hash = "sha256:30336a2d65c5ae4c2d9d7fdc9c22e24b1d285155c93c56ad47a7c34ebc4bfef7"}, ] [package.dependencies] @@ -2159,7 +2159,7 @@ xmljson = "0.2.1" [package.source] type = "url" -url = "https://github.com/HumanSignal/label-studio-sdk/archive/4295cf623e7d9381fccde297f2e2a79a5a3244e8.zip" +url = "https://github.com/HumanSignal/label-studio-sdk/archive/8ce1b4f80f12780da5d07184e4bea25a5c05fe96.zip" [[package]] name = "launchdarkly-server-sdk" @@ -5110,4 +5110,4 @@ uwsgi = ["pyuwsgi", "uwsgitop"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "c7ce0ffd5c557b08dfe02772db18b8fcfb5903779ee39eb3fd69f5a2fc2dbcd6" +content-hash = "8f10d0178c0fe4f6a56ed63e0be4ab1635f8bde65cab0ecc4a2442c960c8e27d" diff --git a/pyproject.toml b/pyproject.toml index df904f042ac2..ca6bf9033cac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dependencies = [ "tldextract (>=5.1.3)", "uuid-utils (>=0.11.0,<1.0.0)", ## HumanSignal repo dependencies :start - "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/4295cf623e7d9381fccde297f2e2a79a5a3244e8.zip", + "label-studio-sdk @ https://github.com/HumanSignal/label-studio-sdk/archive/8ce1b4f80f12780da5d07184e4bea25a5c05fe96.zip", ## HumanSignal repo dependencies :end ]