You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Data Designer is built around a simple idea: describe the dataset you want, and let the framework handle execution. A config points to seed data, defines generated columns, picks models, and shapes the final records — no orchestration code required. [Data Designer plugins](../../plugins/overview.md) keep that promise when a project needs something custom.
15
15
16
16
<!-- more -->
17
17
18
-
Suppose a robotics team has [Isaac Sim](https://developer.nvidia.com/isaac/sim)-generated warehouse runs and wants to turn robot poses, camera views, and event metadata into instruction data. With an internal simulation-log plugin, the user-facing part can still be this small:
18
+
What does "something custom" actually look like? Picture a robotics team sitting on a pile of [Isaac Sim](https://developer.nvidia.com/isaac/sim)-generated warehouse runs, trying to turn robot poses, camera views, and event metadata into instruction data. With an internal simulation-log plugin, the user-facing part can still be this small:
19
19
20
20
```bash
21
21
uv pip install data-designer-isaac-logs
@@ -26,40 +26,25 @@ from data_designer_isaac_logs.config import IsaacRunSeedSource
26
26
from data_designer_isaac_logs.config import WarehouseEventLabelColumnConfig
27
27
from data_designer_isaac_logs.config import RobotSFTProcessor
That is the point of plugins: install a package, import its config classes, and keep the workflow declarative. The Isaac run reader, event labeler, and trainer-format processor own the custom parsing, labeling, validation, and export shape, while Data Designer still handles discovery, dependency ordering, model calls, previews, and output.
47
47
48
-
49
-
<divclass="devnote-clear"></div>
50
-
51
-
!!! tip "TL;DR - What plugins give you"
52
-
53
-
1. Plugins expose custom behavior through the same Data Designer config and runtime paths as built-in components.
54
-
55
-
2. A plugin is a Python package discovered through the `data_designer.plugins` entry point group. Once installed, there is no manual registration step in user code.
56
-
57
-
3. Plugin configs use the same typed config model and serialization behavior as core config types. The engine receives an implementation through the plugin registry.
58
-
59
-
4. Plugins can start as a local editable install, move to an internal package index, and later be published publicly.
60
-
61
-
5. NVIDIA-maintained plugins now live in [NVIDIA-NeMo/DataDesignerPlugins](https://github.com/NVIDIA-NeMo/DataDesignerPlugins), separate from the core repo and installed as packages.
62
-
63
48
---
64
49
65
50
## **Customization Is the Normal Case**
@@ -68,7 +53,7 @@ That is the point of plugins: install a package, import its config classes, and
68
53
69
54
The mess usually starts innocently. A team defines a Data Designer config, then discovers that its seed data lives in an internal layout, its generated column needs a domain simulator, and its trainer expects a slightly different record shape. Someone writes a small reader beside the notebook. Someone patches a generator into a project folder. Someone adds a cleanup script after preview because the final export has one more organization-specific rule. Each choice is reasonable because every project has its own corpus, policy, ontology, simulator, and training stack.
70
55
71
-
The problem is that the custom behavior now lives around Data Designer instead of inside the Data Designer workflow. It is harder to validate, harder to share, harder to version, and easier to lose. Plugins give that bespoke work a clean package boundary: a name, typed config, runtime implementation, entry point, and tests that travel together. Users still declare the dataset they want, but the local reader, domain generator, or trainer-format processor becomes a normal Data Designer component instead of another layer of glue.
56
+
The problem is that the custom behavior now lives around Data Designer instead of inside the Data Designer workflow. It is harder to validate, harder to share, harder to version, and easier to lose. Plugins give that bespoke work a clean package boundary – a name, typed config, runtime implementation, entry point, and tests that travel together. Users still declare the dataset they want, but the local reader, domain generator, or trainer-format processor becomes a normal Data Designer component instead of another layer of glue.
72
57
73
58
<divclass="devnote-clear"></div>
74
59
@@ -96,12 +81,29 @@ These boundaries are intentionally narrow. A plugin should own the behavior that
96
81
97
82
Consider a markdown seed reader. The one-off version might be a helper function that walks a directory, splits files into sections, returns a DataFrame, and then gets copied into the next project that needs it. That can work for one project. It becomes a problem when the reader needs options, tests, documentation, versioning, or reuse across teams. At that point, the helper has become a capability whether or not it is packaged like one.
98
83
99
-
A plugin packages the same idea as a small Python project:
84
+
A plugin packages that same helper as a small Python project:
100
85
101
86
- A user-facing config class describes the options.
102
87
- An implementation class does the work.
103
88
- A `Plugin` object connects the config to the implementation.
104
-
- A Python entry point exposes the plugin to Data Designer.
89
+
- An entry point registers the plugin with Data Designer.
90
+
91
+
The config class declares the user-facing options. For a directory-backed reader, Data Designer's `FileSystemSeedSource` already has fields for `path`, `file_pattern`, and `recursive`, we just need to define the seed type discriminator:
92
+
93
+
```python
94
+
# config.py
95
+
from__future__import annotations
96
+
97
+
from typing import Literal
98
+
99
+
from data_designer.config.seed_source import FileSystemSeedSource
The implementation class is where the old helper code should move. For a filesystem seed reader, Data Designer gives you a small interface instead of a blank page: implement `build_manifest(...)` to build a cheap index of candidate inputs, and implement `hydrate_row(...)` to turn each selected manifest row into one or more dataset rows. That split matters because Data Designer can sample, shuffle, partition, and batch against the lightweight manifest before paying the cost of reading files, parsing sections, or calling project-specific libraries. The parser can still be a normal helper function; the reader class is the framework boundary.
107
109
@@ -173,17 +175,9 @@ class MarkdownSectionSeedReader(FileSystemSeedReader[MarkdownSectionSeedSource])
173
175
]
174
176
```
175
177
176
-
The class should own only the domain-specific behavior: how to find candidate files, how to parse them, and what rows it emits. Let Data Designer keep owning attachment, sampling, shuffling, batching, DuckDB registration, dependency resolution, and execution. The same rule applies to column generators and processors: choose the closest base class, keep options on the config object, implement the narrow runtime method, and leave orchestration out of the plugin.
178
+
The same rule applies to column generators and processors: choose the closest base class, keep options on the config object, implement the narrow runtime method, and leave orchestration out of the plugin.
177
179
178
-
The entry point exposes the plugin package to Data Designer:
The plugin object tells Data Designer what kind of extension this is and where to find the config and implementation:
180
+
Two small files connect the plugin to Data Designer — a `Plugin` descriptor that names the config and implementation, and a Python entry point that exposes them at install time:
No custom orchestration. No separate DataFrame preparation step. The reader is part of the Data Designer workflow. For the same package shape applied to other extension points, see the [Build Your Own plugin guide](../../plugins/build_your_own.md#implementation-patterns), [Column Generators](../../code_reference/engine/column_generators.md), and [Engine Processors](../../code_reference/engine/processors.md) documentation.
224
+
No custom orchestration. No separate DataFrame preparation step. The reader is part of the Data Designer workflow.
225
225
226
226
---
227
227
@@ -243,34 +243,22 @@ It is useful for the broader community too. If you build a plugin that should be
243
243
244
244
## **A Repository for First-Party Plugins**
245
245
246
-
We also created [NVIDIA-NeMo/DataDesignerPlugins](https://github.com/NVIDIA-NeMo/DataDesignerPlugins), a dedicated repository for NVIDIA-maintained plugins. It is where we will publish first-party plugin packages, recommended packaging examples, and plugin-specific docs as the catalog grows.
246
+
We recently created [NVIDIA-NeMo/DataDesignerPlugins](https://github.com/NVIDIA-NeMo/DataDesignerPlugins), a dedicated repository for NVIDIA-maintained plugins. It is where we will publish first-party plugin packages, recommended packaging examples, and plugin-specific docs as the catalog grows.
247
247
248
248
The split keeps the core Data Designer repo focused on the framework: the config API, engine execution, model integration, validation behavior, and stable plugin interface. Plugin packages can depend on optional libraries, target narrower use cases, and move at a different release pace, while still installing separately and using the same plugin interface once installed.
249
249
250
250
---
251
251
252
-
## **Start with One Capability**
253
-
254
-
If you have custom Data Designer code that keeps getting copied between projects, it is a strong candidate for a plugin.
255
-
256
-
Pick one capability. Give it a typed config. Write the implementation behind the matching plugin boundary. Add an `assert_valid_plugin(...)` test so structural problems fail early:
257
-
258
-
```python
259
-
from data_designer.engine.testing import assert_valid_plugin
260
-
from data_designer_markdown_sections.plugin import plugin
261
-
262
-
assert_valid_plugin(plugin)
263
-
```
264
-
265
-
Then run a tiny `preview` before you trust it in a larger generation job.
252
+
## **Where to Go Next**
266
253
267
-
For implementation details, see:
254
+
Interested in building your own plugin? Here are some resources to get you started:
268
255
269
-
-[Plugins overview](../../plugins/overview.md)
270
-
-[Build Your Own](../../plugins/build_your_own.md)
271
-
-[Using Models in Plugins](../../plugins/models.md)
1.[Plugins overview](../../plugins/overview.md) — learn how plugins fit into Data Designer
257
+
2.[Build Your Own](../../plugins/build_your_own.md) — follow the authoring guide for seed readers, column generators, and processors
258
+
3.[Using Models in Plugins](../../plugins/models.md) — call configured models from plugin code
259
+
4.[Markdown Section Seed Reader recipe](../../recipes/plugin_development/markdown_seed_reader.md) — study the complete version of the example from this post
260
+
5.[Available Plugins](../../plugins/available.md) — browse the catalog and learn how to submit your own plugin
261
+
6.[DataDesignerPlugins on GitHub](https://github.com/NVIDIA-NeMo/DataDesignerPlugins) — explore first-party plugin packages
274
262
275
263
Moving plugins out of experimental mode means Data Designer no longer has to predict every customization users will need. The framework provides the pipeline. Plugins supply the custom pieces.
0 commit comments