Add an AI-Q Data Source
Use this skill when a developer wants to add a retrieval or search source to
AI-Q and expose it as a toggleable source in the UI. A data source is a NeMo
Agent Toolkit (NAT) function package under sources/, registered in the
data_source_registry.
Start Here
- Confirm this is a new retrieval/search source (not a UI, auth, or prompt
change). For a general utility function, use
aiq-add-tool instead.
- Read the authoritative files below before editing.
- Copy the closest existing source package rather than inventing a new shape.
- Never print or commit API keys; resolve secrets at runtime via
SecretStr.
Authoritative References
docs/source/extending/adding-a-data-source.md: canonical package and
registration walkthrough (the steps below mirror it).
sources/google_scholar_paper_search/: complete example package with a
client, a config + registration, a graceful missing-secret stub, and tests.
sources/tavily_web_search/: minimal source package for comparison.
src/aiq_agent/common/data_source_registry.py: the data_source_registry
config (name="data_source_registry") that drives GET /v1/data_sources.
docs/source/customization/tools-and-sources.md: how the registry maps to UI
toggles and per-request filtering.
frontends/ui/src/features/layout/data-sources.ts: the UI DataSource type;
sources are fetched dynamically, so usually no UI code change is needed.
Longer procedures live in this bundle:
- references/package-layout.md: package files,
pyproject.toml, config class, @register_function, and the missing-secret stub.
- references/registry-and-ui.md: registering in
YAML and how the registry surfaces toggles and filtering.
- references/validation.md: install, test, and lint
commands with expected results.
Workflow
- Pick the closest existing package under
sources/ and inspect its layout.
- Create
sources/<my_data_source>/ with src/register.py, the client
module, pyproject.toml, and tests/ (see package-layout reference).
- Define a
FunctionBaseConfig subclass with a stable name= and resolve any
API key via SecretStr; register it with @register_function.
- Yield a graceful stub when the required secret is missing.
- Install the package editable and add it to the
data_source_registry in the
relevant config under configs/.
- Add focused tests; run the validation commands below.
- Summarize changed files and paste the test/lint evidence.
Validation
Run the narrowest commands first; broaden only if the change touches shared code.
uv pip install -e ./sources/my_data_source
uv run pytest sources/my_data_source/tests
uv run ruff check sources/my_data_source
uv run ruff format --check sources/my_data_source
Expected: the package installs, its tests pass, and Ruff reports no lint or
format failures for the new source package.
Common Mistakes
- Forgetting to add the source to the
data_source_registry, so the UI cannot
toggle it and agents do not inherit the tool.
- Omitting the
[project.entry-points."nat.plugins"] entry in pyproject.toml,
so NAT never discovers the registration.
- Crashing on a missing API key instead of yielding a stub that returns a clear
error message.
- Returning unstructured or citation-poor output, which weakens report grounding.
- Printing API keys or embedding secrets in YAML instead of using environment
variables or
SecretStr.
Related Skills
aiq-configure-workflow
aiq-add-tool
aiq-release-qa
aiq-prepare-pr
1---2name: aiq-add-data-source3description: Use when adding or changing an AI-Q data source under sources/, registering it as a NeMo Agent Toolkit function, wiring it into the data_source_registry for UI toggles, or validating retrieval behavior with tests.4license: Apache-2.05---67# Add an AI-Q Data Source89Use this skill when a developer wants to add a retrieval or search source to10AI-Q and expose it as a toggleable source in the UI. A data source is a NeMo11Agent Toolkit (NAT) function package under `sources/`, registered in the12`data_source_registry`.1314## Start Here1516- Confirm this is a new retrieval/search source (not a UI, auth, or prompt17 change). For a general utility function, use `aiq-add-tool` instead.18- Read the authoritative files below before editing.19- Copy the closest existing source package rather than inventing a new shape.20- Never print or commit API keys; resolve secrets at runtime via `SecretStr`.2122## Authoritative References2324- `docs/source/extending/adding-a-data-source.md`: canonical package and25 registration walkthrough (the steps below mirror it).26- `sources/google_scholar_paper_search/`: complete example package with a27 client, a config + registration, a graceful missing-secret stub, and tests.28- `sources/tavily_web_search/`: minimal source package for comparison.29- `src/aiq_agent/common/data_source_registry.py`: the `data_source_registry`30 config (`name="data_source_registry"`) that drives `GET /v1/data_sources`.31- `docs/source/customization/tools-and-sources.md`: how the registry maps to UI32 toggles and per-request filtering.33- `frontends/ui/src/features/layout/data-sources.ts`: the UI `DataSource` type;34 sources are fetched dynamically, so usually no UI code change is needed.3536Longer procedures live in this bundle:3738- [references/package-layout.md](references/package-layout.md): package files,39 `pyproject.toml`, config class, `@register_function`, and the missing-secret stub.40- [references/registry-and-ui.md](references/registry-and-ui.md): registering in41 YAML and how the registry surfaces toggles and filtering.42- [references/validation.md](references/validation.md): install, test, and lint43 commands with expected results.4445## Workflow46471. Pick the closest existing package under `sources/` and inspect its layout.482. Create `sources/<my_data_source>/` with `src/register.py`, the client49 module, `pyproject.toml`, and `tests/` (see package-layout reference).503. Define a `FunctionBaseConfig` subclass with a stable `name=` and resolve any51 API key via `SecretStr`; register it with `@register_function`.524. Yield a graceful stub when the required secret is missing.535. Install the package editable and add it to the `data_source_registry` in the54 relevant config under `configs/`.556. Add focused tests; run the validation commands below.567. Summarize changed files and paste the test/lint evidence.5758## Validation5960Run the narrowest commands first; broaden only if the change touches shared code.6162```bash63uv pip install -e ./sources/my_data_source64uv run pytest sources/my_data_source/tests65uv run ruff check sources/my_data_source66uv run ruff format --check sources/my_data_source67```6869Expected: the package installs, its tests pass, and Ruff reports no lint or70format failures for the new source package.7172## Common Mistakes7374- Forgetting to add the source to the `data_source_registry`, so the UI cannot75 toggle it and agents do not inherit the tool.76- Omitting the `[project.entry-points."nat.plugins"]` entry in `pyproject.toml`,77 so NAT never discovers the registration.78- Crashing on a missing API key instead of yielding a stub that returns a clear79 error message.80- Returning unstructured or citation-poor output, which weakens report grounding.81- Printing API keys or embedding secrets in YAML instead of using environment82 variables or `SecretStr`.8384## Related Skills8586- `aiq-configure-workflow`87- `aiq-add-tool`88- `aiq-release-qa`89- `aiq-prepare-pr`