Skip to content

feat: BROS-194: Custom tags #8108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Aug 18, 2025
Merged

feat: BROS-194: Custom tags #8108

merged 28 commits into from
Aug 18, 2025

Conversation

hlomzik
Copy link
Collaborator

@hlomzik hlomzik commented Aug 6, 2025

Summary

Enable platform support for custom tags and add backend validation for Chat data. This PR provides backend validation and a feature-flag switch that allows downstream apps to register custom tags.

Key highlights in this PR

  • Allow to register custom tag

    • Introduce/enable custom-tag registration through the editor registry so downstream apps can wire a tag's model, view, and region in one call.
    • Relevant: web/libs/editor/src/core/Registry.ts (addCustomTag hooks into addTag, addObjectType, addRegionType).
  • Include registered items in all required places for a new tag to work

    • Registration wires the tag across the internal registries: models/views, object type mapping, and region type detection.
    • Deserialization is adjusted to avoid mis-detecting regions vs. classifications (see omitValueFields below), ensuring registered region types are detected correctly.
  • Utilize hideable param (previously unused in some UI paths)

    • Respect region.hideable/item.hideable when rendering visibility controls in Outliner and Details panel.
    • Relevant: web/libs/editor/src/components/SidePanels/OutlinerPanel/OutlinerTree.tsx, web/libs/editor/src/components/SidePanels/DetailsPanel/RegionItem.tsx.
  • Simplify omitValueFields to only address Text vs TextArea confusion

    • Narrowed logic to only strip value.text when it's an array (TextArea case) under FF_CUSTOM_TAGS, preventing conflicts that caused wrong region/classification detection.
    • Relevant: web/libs/editor/src/stores/Annotation/Annotation.js (omitValueFields).

Other Changes

  • Backend

    • Extend TaskValidator data types to include Chat so tasks with chat data validate correctly.
  • Feature flags

    • Enable FF_CUSTOM_TAGS override in development/OSS builds to allow experimentation and downstream registration of custom tags. No LS UI exposure in this PR.

Affected Files (high-level)

  • label_studio/tasks/validation.py
  • web/libs/core/src/lib/utils/feature-flags/ff.ts
  • web/libs/editor/src/core/Registry.ts
  • web/libs/editor/src/stores/Annotation/Annotation.js
  • web/libs/editor/src/components/SidePanels/OutlinerPanel/OutlinerTree.tsx
  • web/libs/editor/src/components/SidePanels/DetailsPanel/RegionItem.tsx

Feature Flags

  • FF_CUSTOM_TAGS: enabled by default in OSS/dev via override.

Why

  • Allow downstream applications to register and use custom tags. Add backend support for Chat-type task data so such data validates correctly when present. Editor changes are limited to plumbing for registration, honoring hideable, and deserialization safety; no new user-facing features in LS.

Testing

  1. Backend validation
    • Import/create tasks where labeling config includes a Chat object and task data contains chat content.
    • Verify tasks pass validation and can be imported.

Rollout / Risk

  • Additive backend and internal plumbing for custom tags; no new LS user-facing features.
  • No migrations required.

Docs

  • Custom tag registration is intended for downstream applications. No user-facing LS documentation changes are included here.

hlomzik added 4 commits August 6, 2025 18:18
Region/Result's `unselectRegion()` and connected code.
The whole `ImageRegion` is not in use.
- `forEach()` -> `for .. of` conversions.
  MST maps were not touched except for `keys()` access which is easier with `for .. of`.
- Bunch of optional chaining added to simplify code
- `Number.isNaN()` instead of `isNaN()`
We needed it only because of confusion between `text: string` for `Text` tag
and `text: string[]` for `TextArea` tag. We don't need to omit other values.
Copy link

netlify bot commented Aug 6, 2025

Deploy Preview for label-studio-docs-new-theme canceled.

Name Link
🔨 Latest commit f8f630c
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-docs-new-theme/deploys/68a2808fe42a050008fb63cc

Copy link

netlify bot commented Aug 6, 2025

Deploy Preview for label-studio-storybook ready!

Name Link
🔨 Latest commit f8f630c
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-storybook/deploys/68a2808fec08d50008164e70
😎 Deploy Preview https://deploy-preview-8108--label-studio-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link

netlify bot commented Aug 6, 2025

Deploy Preview for heartex-docs canceled.

Name Link
🔨 Latest commit f8f630c
🔍 Latest deploy log https://app.netlify.com/projects/heartex-docs/deploys/68a2808f5b50bf000826851b

Copy link

netlify bot commented Aug 6, 2025

Deploy Preview for label-studio-playground ready!

Name Link
🔨 Latest commit f8f630c
🔍 Latest deploy log https://app.netlify.com/projects/label-studio-playground/deploys/68a2808f1beb450008b72df5
😎 Deploy Preview https://deploy-preview-8108--label-studio-playground.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link

codecov bot commented Aug 6, 2025

Codecov Report

❌ Patch coverage is 52.27273% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.45%. Comparing base (603b16c) to head (f8f630c).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
web/libs/editor/src/core/Registry.ts 28.57% 5 Missing ⚠️
...eb/libs/editor/src/stores/Annotation/Annotation.js 54.54% 5 Missing ⚠️
web/libs/editor/src/regions/Result.js 50.00% 4 Missing ⚠️
web/libs/editor/src/regions/Area.js 33.33% 2 Missing ⚠️
label_studio/projects/models.py 50.00% 1 Missing ⚠️
web/libs/editor/src/components/Node/Node.tsx 0.00% 1 Missing ⚠️
web/libs/editor/src/regions/index.js 0.00% 1 Missing ⚠️
web/libs/editor/src/tags/visual/Collapse.jsx 0.00% 1 Missing ⚠️
web/libs/editor/src/tags/visual/View.jsx 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #8108      +/-   ##
===========================================
+ Coverage    70.02%   70.45%   +0.43%     
===========================================
  Files          684      720      +36     
  Lines        51061    52178    +1117     
  Branches      8628     8823     +195     
===========================================
+ Hits         35753    36763    +1010     
- Misses       15308    15412     +104     
- Partials         0        3       +3     
Flag Coverage Δ
lsf-e2e 59.72% <52.38%> (+1.19%) ⬆️
lsf-integration 55.56% <52.38%> (-0.02%) ⬇️
lsf-unit 9.43% <15.78%> (?)
pytests 78.33% <50.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hlomzik hlomzik changed the title Fb bros 194/custom tag feat: BROS-194: Custom tags Aug 8, 2025
@hlomzik
Copy link
Collaborator Author

hlomzik commented Aug 11, 2025

/git merge

Workflow run
Successfully merged: create mode 100644 web/libs/editor/src/lib/AudioUltra/Visual/Renderer/ResizeRenderer.ts

@hlomzik hlomzik force-pushed the fb-bros-194/custom-tag branch from b434bf0 to ace272f Compare August 13, 2025 18:27
@hlomzik hlomzik requested review from a team as code owners August 13, 2025 18:27
@hlomzik hlomzik force-pushed the fb-bros-194/custom-tag branch from ace272f to b434bf0 Compare August 13, 2025 18:36
hlomzik and others added 5 commits August 13, 2025 19:38
The main usage of this component was in `_renderAll()` and we don't use it
anymore.
The only usage left is in old UI which will be removed soon, so we basically
don't use `Segment` component.
moving to separate var for better performance

Co-authored-by: Nick Skriabin <767890+nick-skriabin@users.noreply.github.com>
@@ -80,14 +81,21 @@ const hotkeys = Hotkey("Annotations", "Annotations");
* @param value {Object} object to fix
* @returns {Object} new object without value fields
*/
function omitValueFields(value) {
const omitValueFields = ff.isActive(ff.FF_CUSTOM_TAGS) ? (value) => {
// @todo describe that we only omit `text` from TextArea
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this true? The original code looks like it is possibly omitting far more 🤯

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, we needed it only because of this confusion. I added some info into commit message (60ca64c), but will write a comment here as well.

Copy link
Collaborator

@Gondragos Gondragos Aug 17, 2025

Choose a reason for hiding this comment

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

We have a point in the code where the serialized result is deserialized, and at this point all result data is duplicated both in value and at the top level. Because in RichText we decided to store the text in the serialized result, and both RichText region and TextArea use the "text" field to store their data, when passing it to the top level, we have to filter the "text" field to avoid type conflicts. After determining the type, we add this value "manually" using applyAdditionalDataFromResult.

However, yes, this is the only detected case at the moment.

(I really hope I remember the reason of this function correctly)

@niklub
Copy link
Collaborator

niklub commented Aug 14, 2025

/git merge

Workflow run
Successfully merged: create mode 100644 docs/themes/v2/source/images/project/project_members_dashboard.png

toggleCollapsed={toggleCollapsed}
/>
{item.hideable && (
<RegionControls
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure we really want to remove all controls under this condition. There's functionality like "Copy Region Link", and I don't yet understand whether it requires removal or will operate as intended if retained.


addCustomTag(tag: string, definition: CustomTag) {
this.addTag(tag.toLowerCase(), definition.model, definition.view);
this.addObjectType(definition.model);
Copy link
Collaborator

Choose a reason for hiding this comment

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

It looks like we won't be able to add something different from the object tag to the Custom tags.
Is it expectable behaviour?

@hlomzik
Copy link
Collaborator Author

hlomzik commented Aug 18, 2025

/git merge

Workflow run
Successfully merged: create mode 100644 web/libs/editor/tests/integration/e2e/control_tags/text-with-dual-taxonomy.cy.ts

@robot-ci-heartex robot-ci-heartex merged commit fc26d71 into develop Aug 18, 2025
52 of 53 checks passed
@robot-ci-heartex robot-ci-heartex deleted the fb-bros-194/custom-tag branch August 18, 2025 04:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants