Skip to content

[HA] Integrate BrowserAnnotationProvider with annotation framework#7268

Merged
tom-vx51 merged 4 commits intodevelopfrom
feat/browser-annotation-integration
Apr 2, 2026
Merged

[HA] Integrate BrowserAnnotationProvider with annotation framework#7268
tom-vx51 merged 4 commits intodevelopfrom
feat/browser-annotation-integration

Conversation

@tom-vx51
Copy link
Copy Markdown
Member

@tom-vx51 tom-vx51 commented Mar 30, 2026

🔗 Related Issues

📋 What changes are proposed in this pull request?

Integrates the interfaces set up in #7213 with the browser-based inference added in #7192 and subsequent PRs.

🧪 How is this patch tested? If it is not, please explain why.

unit tests

📝 Release Notes

Is this a user-facing change that should be mentioned in the release notes?

  • No. You can skip the rest of this section.
  • Yes. Give a description of this change to be included in the release
    notes for FiftyOne users.

What areas of FiftyOne does this PR affect?

  • App: FiftyOne application changes
  • Build: Build and test infrastructure changes
  • Core: Core fiftyone Python library changes
  • Documentation: FiftyOne documentation changes
  • Other

Summary by CodeRabbit

  • New Features

    • Browser-based SAM2 segmentation agent with positive/negative point prompts and model metadata; registered by default.
  • Improvements

    • Robust lazy initialization with retry and concurrent-infer handling; proper abort/dispose semantics.
    • Unified sample descriptor exposing media URL so annotation tools reliably receive current media.
  • Tests

    • Comprehensive test coverage for agent behavior, prompt handling, lifecycle, error propagation, and capability listings.

@tom-vx51 tom-vx51 requested a review from a team as a code owner March 30, 2026 23:09
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

Walkthrough

Adds a new SAM2BrowserAnnotationAgent implementing AnnotationAgent for SEGMENT tasks using a BrowserAnnotationProvider. infer() requires sampleDescriptor.mediaUrl, performs concurrency-safe lazy initialization, converts positive/negative points into provider prompts, forwards abort/dispose to the provider, and returns synchronous segmentation InferenceResults with mask, mask_width, mask_height, and bounding_box. Registers the agent in the built-in registry, re-exports it, adds comprehensive Vitest coverage, introduces useSampleDescriptor and useModalMediaPath hooks, and makes SampleDescriptor.mediaUrl required.

Sequence Diagram

sequenceDiagram
    participant Client
    participant SAM2Agent as SAM2BrowserAnnotationAgent
    participant Provider as BrowserAnnotationProvider
    participant Worker as Web Worker (SAM2 Model)

    Client->>SAM2Agent: infer(context with sampleDescriptor.mediaUrl + points)
    activate SAM2Agent
    alt provider not initialized
        SAM2Agent->>SAM2Agent: ensureInitialized()
        SAM2Agent->>Provider: initialize()
        activate Provider
        Provider->>Worker: load model
        Worker-->>Provider: model ready
        Provider-->>SAM2Agent: initialize complete
        deactivate Provider
    end
    SAM2Agent->>SAM2Agent: map positive/negative -> points[]
    SAM2Agent->>Provider: infer({ imageUrl, points })
    activate Provider
    Provider->>Worker: run inference
    Worker-->>Provider: segmentation {mask, bbox:{x,y,w,h}, width, height}
    Provider-->>SAM2Agent: segmentation result
    deactivate Provider
    SAM2Agent-->>Client: Promise<InferenceResult sync {mask, mask_width, mask_height, bounding_box:[x,y,w,h]}>
    deactivate SAM2Agent
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: integrating BrowserAnnotationProvider with the annotation framework.
Description check ✅ Passed The description follows the template, includes related issues reference, explains the proposed changes, mentions unit tests, and correctly selects the user-facing impact.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/browser-annotation-integration

Comment @coderabbitai help to get the list of available commands and usage tips.

@tom-vx51 tom-vx51 changed the title Feat/browser annotation integration [HA] Integrate BrowserAnnotationProvider with annotation framework Mar 30, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/packages/annotation/src/agents/SAM2BrowserAnnotationAgent.ts`:
- Around line 44-53: The class currently requires callers to call the
non-interface method setImageUrl() before infer(), which is an out-of-contract
mutable side channel; remove that precondition and accept the image URL via the
inference request context instead. Update SAM2BrowserAnnotationAgent.infer to
read the image URL from the provided AnnotationContext (add a required property
or typed field on AnnotationContext or create a small typed request object) and
eliminate reliance on the instance field this.imageUrl and the setImageUrl
method; delete or deprecate setImageUrl and any runtime throw for missing
this.imageUrl, and adjust callers/tests to pass the image URL through the
AnnotationContext passed into infer. Ensure function/class names referenced:
setImageUrl, infer, AnnotationContext, SAM2BrowserAnnotationAgent, and
AnnotationAgent.
- Around line 51-63: The infer() method can race with setImageUrl() because
this.imageUrl is read after an await; fix by reading and validating the URL into
a local const before any await (e.g. const imageUrl = this.imageUrl; if
(!imageUrl) throw ...), then use that local imageUrl for building prompt points
and for the call to this.provider.infer; if buildPromptPoints currently reads
this.imageUrl, change it to accept an imageUrl parameter (or inline point
construction using the local imageUrl) so all operations in infer() use the
captured value rather than this.imageUrl.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: fe19f685-cfc7-416d-9b5f-e2d3ca7ac9c6

📥 Commits

Reviewing files that changed from the base of the PR and between 14c9ad2 and 6b87972.

📒 Files selected for processing (5)
  • app/packages/annotation/src/agents/SAM2BrowserAnnotationAgent.test.ts
  • app/packages/annotation/src/agents/SAM2BrowserAnnotationAgent.ts
  • app/packages/annotation/src/agents/hooks/useAgentRegistry.ts
  • app/packages/annotation/src/agents/index.ts
  • app/packages/annotation/src/providers/index.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/packages/annotation/src/agents/types.ts (1)

54-60: ⚠️ Potential issue | 🟠 Major

Fix TypeScript compilation error in OperatorAnnotationAgent.test.ts where sampleDescriptor is missing the required mediaUrl field.

The SampleDescriptor type now requires mediaUrl: string, but OperatorAnnotationAgent.test.ts:22 constructs it without this field, causing a compilation error. Add the missing field or update the test helper to properly mock the URL.

(Note: SAM2BrowserAnnotationAgent.test.ts:86 intentionally omits mediaUrl to test error handling, which is valid and properly uses as SampleDescriptor to test the agent's validation.)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/packages/annotation/src/agents/types.ts` around lines 54 - 60, The test
fails because the SampleDescriptor type now requires mediaUrl; update the test
so the sampleDescriptor constructed in OperatorAnnotationAgent.test.ts includes
a valid mediaUrl string (or update the test helper that builds the sample
descriptor to populate mediaUrl) so it matches the exported SampleDescriptor
type; locate the sampleDescriptor variable in OperatorAnnotationAgent.test.ts
(or the test helper it uses) and add a realistic mediaUrl value (e.g.,
"http://example.com/media.mp4") to satisfy the type without changing the
production type.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/packages/annotation/src/agents/hooks/useSampleDescriptor.ts`:
- Around line 12-24: The hook useSampleDescriptor currently claims to return a
fully-populated SampleDescriptor while using values from useCurrentDatasetName,
useCurrentSampleId, and useModalMediaPath which can be null; change
useSampleDescriptor to return null until all three values are non-null (make the
return type SampleDescriptor | null), i.e., check datasetId, sampleId, and
mediaUrl and return null if any are falsy, otherwise return the memoized
descriptor; update callers (e.g., useAgentContext and any usage in
SAM2BrowserAnnotationAgent.infer) to handle the nullable return instead of
relying on this hook to supply non-null fields.

In `@app/packages/annotation/src/agents/SAM2BrowserAnnotationAgent.ts`:
- Around line 116-145: The ensureInitialized()/dispose() race can let a pending
provider.initialize() resolve after dispose() and incorrectly set
this.initialized = true; fix by adding a lifecycle token: capture a local token
(e.g. const token = ++this.initEpoch) before calling this.provider.initialize()
in ensureInitialized(), and only set this.initialized = true and
this.initializing$ = null if token === this.initEpoch; update dispose() to
increment/clear that token (and still call this.provider.dispose() and set
initializing$ = null), and add a regression test "dispose during initialize"
that starts initialize(), calls dispose() while pending, then asserts that
infer() triggers a fresh initialize rather than using a disposed provider.
Ensure references: ensureInitialized(), dispose(), initializing$, initialized,
provider.initialize(), infer().

---

Outside diff comments:
In `@app/packages/annotation/src/agents/types.ts`:
- Around line 54-60: The test fails because the SampleDescriptor type now
requires mediaUrl; update the test so the sampleDescriptor constructed in
OperatorAnnotationAgent.test.ts includes a valid mediaUrl string (or update the
test helper that builds the sample descriptor to populate mediaUrl) so it
matches the exported SampleDescriptor type; locate the sampleDescriptor variable
in OperatorAnnotationAgent.test.ts (or the test helper it uses) and add a
realistic mediaUrl value (e.g., "http://example.com/media.mp4") to satisfy the
type without changing the production type.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 161ca1ca-f8d4-4e4c-94b2-e79a09674b50

📥 Commits

Reviewing files that changed from the base of the PR and between 6b87972 and 2eaeb36.

📒 Files selected for processing (7)
  • app/packages/annotation/src/agents/SAM2BrowserAnnotationAgent.test.ts
  • app/packages/annotation/src/agents/SAM2BrowserAnnotationAgent.ts
  • app/packages/annotation/src/agents/hooks/index.ts
  • app/packages/annotation/src/agents/hooks/useAnnotationAgent.ts
  • app/packages/annotation/src/agents/hooks/useSampleDescriptor.ts
  • app/packages/annotation/src/agents/types.ts
  • app/packages/state/src/accessors/modal.ts

@lanzhenw lanzhenw self-requested a review April 1, 2026 19:00
Copy link
Copy Markdown
Member

@lanzhenw lanzhenw left a comment

Choose a reason for hiding this comment

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

LGTM~

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/packages/annotation/src/agents/SAM2BrowserAnnotationAgent.ts`:
- Around line 136-143: ensureInitialized() currently resolves even when the
provider reports not ready, allowing infer() to call provider.infer() in an
invalid state; update ensureInitialized() to check provider.isInitialized()
after any async initialization completes and explicitly reject/throw (or set
initialized = false and throw an InitializationError) when the provider is still
not ready so callers (like infer()) cannot proceed; also ensure the
initializing$ field is nulled only after failure and that initialized remains
accurate (references: ensureInitialized(), initializing$, initialized,
provider.isInitialized(), provider.infer(), infer()).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2eec2b4e-de18-4b61-b8b7-7e6896cb27d2

📥 Commits

Reviewing files that changed from the base of the PR and between 2eaeb36 and 935f70c.

📒 Files selected for processing (2)
  • app/packages/annotation/src/agents/SAM2BrowserAnnotationAgent.test.ts
  • app/packages/annotation/src/agents/SAM2BrowserAnnotationAgent.ts

@tom-vx51 tom-vx51 enabled auto-merge April 1, 2026 23:58
@tom-vx51 tom-vx51 merged commit 6c6e234 into develop Apr 2, 2026
19 checks passed
@tom-vx51 tom-vx51 deleted the feat/browser-annotation-integration branch April 2, 2026 00:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants