Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Develop custom FiftyOne plugins (operators and panels) from scratch. Use when user wants to create a new plugin, extend FiftyOne with custom operators, build interactive panels, or integrate external APIs into FiftyOne. Guides through requirements, design, coding, testing, and iteration.
.claude/skills/aiskillstore-fiftyone-develop-plugin/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | -37% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 49% | 0% |
| case-18 | ✗→✓ | ▲ Improved | -61% | 0% |
| case-19 | ✗→✓ | ▲ Improved | 12% | 0% |
| case-20 | ✗→✓ | ▲ Improved | -58% | 0% |
Create custom FiftyOne plugins with full lifecycle support: requirements gathering, code generation, local testing, and iterative refinement.
Use this skill when:
pip install fiftyone)ALWAYS follow these rules:
Ask clarifying questions. Never assume what the plugin should do.
Present file structure and design. Get user approval before generating code.
pythonlist_plugins(enabled=True) list_operators(builtin_only=False) get_operator_schema(operator_uri="@voxel51/brain/compute_similarity")
Install plugin and verify it works in FiftyOne App.
Refine until the plugin works as expected.
Ask these questions:
@org/plugin-name)See PLUGIN-STRUCTURE.md for file formats.
Create these files:
| File | Required | Purpose | |------|----------|---------| | fiftyone.yml | Yes | Plugin manifest | | __init__.py | Yes | Python operators/panels | | requirements.txt | If deps | Python dependencies | | package.json | JS only | Node.js metadata | | src/index.tsx | JS only | React components |
Reference docs:
bash# Find plugins directory python -c "import fiftyone as fo; print(fo.config.plugins_dir)" # Copy plugin cp -r ./my-plugin ~/.fiftyone/plugins/ # Verify detection python -c "import fiftyone as fo; print(fo.plugins.list_plugins())"
Test in App:
pythonlaunch_app(dataset_name="test-dataset") # Press Cmd/Ctrl + ` to open operator browser # Search for your operator
| Type | Language | Use Case | |------|----------|----------| | Operator | Python | Data processing, computations | | Panel | Python | Simple interactive UI | | Panel | JavaScript | Rich React-based UI |
| Option | Effect | |--------|--------| | dynamic=True | Recalculate inputs on change | | execute_as_generator=True | Stream progress | | allow_delegated_execution=True | Background execution | | unlisted=True | Hide from browser |
| Type | Method | |------|--------| | Text | inputs.str() | | Number | inputs.int() / inputs.float() | | Boolean | inputs.bool() | | Dropdown | inputs.enum() | | File | inputs.file() | | View | inputs.view_target() |
fiftyone.yml:
yamlname: "@myorg/hello-world" type: plugin operators: - hello_world
__init__.py:
pythonimport fiftyone.operators as foo import fiftyone.operators.types as types class HelloWorld(foo.Operator): @property def config(self): return foo.OperatorConfig( name="hello_world", label="Hello World" ) def resolve_input(self, ctx): inputs = types.Object() inputs.str("message", label="Message", default="Hello!") return types.Property(inputs) def execute(self, ctx): print(ctx.params["message"]) return {"status": "done"} def register(p): p.register(HelloWorld)
Plugin not appearing:
fiftyone.yml exists in plugin root~/.fiftyone/plugins/Operator not found:
fiftyone.ymlregister() functionlist_operators() to debugSecrets not available:
fiftyone.yml under secrets:Copyright 2017-2025, Voxel51, Inc. Apache 2.0 License
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 17,273 | 4,258 | -75% | 1 | 1 | 0% | 3,364 | 2,135 | -37% | 0 | 0 | — |
case-02 | fail→fail | 20,677 | 15,571 | -25% | 1 | 1 | 0% | 3,929 | 4,758 | +21% | 0 | 0 | — |
case-03 | fail→fail | 18,145 | 5,358 | -70% | 1 | 1 | 0% | 3,591 | 2,316 | -36% | 0 | 0 | — |
case-04 | pass→pass | 5,749 | 6,523 | +13% | 1 | 1 | 0% | 939 | 2,564 | +173% | 0 | 0 | — |
case-05 | pass→pass | 6,914 | 4,979 | -28% | 1 | 1 | 0% | 1,356 | 2,216 | +63% | 0 | 0 | — |
case-06 | pass→pass | 10,641 | 5,100 | -52% | 1 | 1 | 0% | 1,815 | 2,352 | +30% | 0 | 0 | — |
case-07 | pass→pass | 6,778 | 2,812 | -59% | 1 | 1 | 0% | 1,169 | 1,865 | +60% | 0 | 0 | — |
case-08 | pass→pass | 10,449 | 5,662 | -46% | 1 | 1 | 0% | 2,071 | 2,397 | +16% | 0 | 0 | — |
case-21 | pass→pass | 8,873 | 6,045 | -32% | 1 | 1 | 0% | 1,569 | 2,475 | +58% | 0 | 0 | — |
case-09 | pass→pass | 6,766 | 2,943 | -57% | 1 | 1 | 0% | 1,160 | 1,958 | +69% | 0 | 0 | — |
case-10 | pass→pass | 7,275 | 5,822 | -20% | 1 | 1 | 0% | 1,331 | 2,415 | +81% | 0 | 0 | — |
case-11 | pass→pass | 4,184 | 3,070 | -27% | 1 | 1 | 0% | 751 | 1,985 | +164% | 0 | 0 | — |
case-12 | pass→pass | 4,022 | 2,651 | -34% | 1 | 1 | 0% | 710 | 1,827 | +157% | 0 | 0 | — |
case-13 | pass→pass | 10,823 | 5,852 | -46% | 1 | 1 | 0% | 2,026 | 2,434 | +20% | 0 | 0 | — |
case-14 | fail→pass | 7,569 | 4,079 | -46% | 1 | 1 | 0% | 1,470 | 2,184 | +49% | 0 | 0 | — |
case-15 | pass→pass | 13,933 | 10,428 | -25% | 1 | 1 | 0% | 2,422 | 3,103 | +28% | 0 | 0 | — |
case-16 | pass→pass | 11,438 | 6,732 | -41% | 1 | 1 | 0% | 2,030 | 2,655 | +31% | 0 | 0 | — |
case-17 | pass→pass | 6,680 | 3,152 | -53% | 1 | 1 | 0% | 1,268 | 1,926 | +52% | 0 | 0 | — |
case-18 | fail→pass | 28,623 | 4,359 | -85% | 1 | 1 | 0% | 5,601 | 2,199 | -61% | 0 | 0 | — |
case-19 | fail→pass | 11,924 | 6,014 | -50% | 1 | 1 | 0% | 2,302 | 2,575 | +12% | 0 | 0 | — |
case-20 | fail→pass | 21,343 | 1,764 | -92% | 1 | 1 | 0% | 4,000 | 1,698 | -58% | 0 | 0 | — |
case-22 | pass→pass | 6,019 | 6,597 | +10% | 1 | 1 | 0% | 1,214 | 2,607 | +115% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +23 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.