Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions .github/ISSUE_TEMPLATE/extension-hook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: 🔌 Extension hook
description: Ask for a hook your probe, scorer or other extension needs and User Sim does not offer
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: >-
Use this form when an extension needs something no hook, class
attribute or entry point offers. A maintainer reviews the request,
agrees the hook's shape with you and adds the `triaged` label when a
pull request is wanted.
[Adding a hook](https://github.com/NVIDIA-NeMo/UserSim/blob/main/CONTRIBUTING.md#adding-a-hook)
lists what a new hook must do.

- type: textarea
id: need
attributes:
label: What does your extension need to do?
description: >-
The need in general terms: what the extension has to read or change,
and at which stage of a run (setup, the conversation, the stored
columns, scoring or the report). The general shape is enough to design
a hook, so leave out anything confidential about your project.
validations:
required: true

- type: textarea
id: gap
attributes:
label: Why don't the existing hooks cover it?
description: >-
The hooks, class attributes and entry points you looked at, in
[architecture/probes.md](https://github.com/NVIDIA-NeMo/UserSim/blob/main/architecture/probes.md)
and [docs/extension_api.md](https://github.com/NVIDIA-NeMo/UserSim/blob/main/docs/extension_api.md),
and where each falls short.
validations:
required: true

- type: textarea
id: shape
attributes:
label: What shape do you propose?
description: >-
A method, class attribute or entry point, its signature, and what
happens for a probe that does not define it. That default should keep
today's behaviour.
validations:
required: true

- type: textarea
id: hosted
attributes:
label: Does it work when a host drives the probe?
description: >-
A host can run a probe from its own loop through `ProbeEpisodeRuntime`,
as
[EXTERNAL_PROBE_RUNTIME.md](https://github.com/NVIDIA-NeMo/UserSim/blob/main/docs/engine/EXTERNAL_PROBE_RUNTIME.md)
describes. Say whether the hook runs there too, and whether it calls a
model.
validations:
required: true

- type: textarea
id: investigation
attributes:
label: Prior investigation
description: >-
What you or your coding agent found in the code, documentation and
existing issues, such as a hook that covers part of this or an open
request for the same thing. If an agent investigated, paste its
findings.
placeholder: Paste the agent's findings, or describe what you checked.

- type: checkboxes
id: checklist
attributes:
label: Checklist
options:
- label: I searched existing issues and the documentation, or had my agent do so
required: true
- label: The request describes the need in general terms and holds nothing confidential
required: true
- label: If an agent helped, its findings are under Prior investigation
required: false
3 changes: 2 additions & 1 deletion .github/ISSUE_TEMPLATE/feature-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ body:
change is wanted. If you plan to build this yourself, open the pull
request once the issue has that label; see
[Issues before pull requests](https://github.com/NVIDIA-NeMo/UserSim/blob/main/CONTRIBUTING.md#issues-before-pull-requests).
To propose a probe you plan to build, use the New probe form instead.
To propose a probe you plan to build, use the New probe form instead,
and to ask for a hook your extension needs, the Extension hook form.

- type: textarea
id: problem
Expand Down
29 changes: 28 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,9 @@ your package adds with its own prefix, such as `my_bookings`; unprefixed
names belong to the built-ins, and
[`architecture/plugins.md`](architecture/plugins.md) lists the names this
covers. [`docs/extensions.md`](docs/extensions.md) builds a whole extension
package, a probe with its bank, a scorer and their tests, step by step. Import
package, a probe with its bank, a scorer and their tests, step by step, and
[`templates/extension_package/`](templates/extension_package/) is one to copy
and fill in. Import
from `usersim.extension` and `usersim.testing`;
[`docs/extension_api.md`](docs/extension_api.md) lists every name they export.

Expand Down Expand Up @@ -445,6 +447,31 @@ To propose a probe, open the
Triage settles where it lives: in this repository, as an extension, or as an
extension first.

### Adding a hook

When a probe, scorer or other extension needs something no hook, class
attribute or entry point offers, open the
[Extension hook form](https://github.com/NVIDIA-NeMo/UserSim/issues/new?template=extension-hook.yml).
[`architecture/probes.md`](architecture/probes.md) lists the hooks and
declarations a probe has, and [`docs/extension_api.md`](docs/extension_api.md)
the names an extension imports.

A new hook:

- **is general:** it serves probes beyond the one that asks for it, and its
name and documentation describe that general use.
- **keeps today's behaviour by default:** a probe that does not define it runs,
and stores its rows, as before.
- **is `async def` if it can call a model,** so the loop awaits it.
- **works when a host drives the probe:** `assert_hosted_parity` passes for a
probe that uses it.
- **comes with its uses:** the extension fixture in
`tests/fixtures/extension_package/` uses it, so `make check-extensions`
proves it works from an installed package. The pull request that adds it
also updates the conformance checks, `templates/probe/`,
[`architecture/probes.md`](architecture/probes.md) and
[`docs/engine/AUTHORING_A_PROBE.md`](docs/engine/AUTHORING_A_PROBE.md).

## Code style

`ruff` owns formatting and linting; there is no separate style config to
Expand Down
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ health-check: ## Live one-row simulate + eval + report against a provider
|| { echo "report produced no index.html"; exit 1; }; \
echo "✓ simulate, eval and report all completed"

check-extensions: ## Install an out-of-tree package and prove all six seams work
check-extensions: ## Install an out-of-tree package, prove all six seams work, and test the package template
@set -eu; \
WORK=$$(mktemp -d); \
EMPTY=$$(mktemp -d); \
Expand All @@ -280,10 +280,15 @@ check-extensions: ## Install an out-of-tree package and prove all six seams wor
test -x "$$WORK/venv/bin/python" || { echo "venv was not created"; exit 1; }; \
$(UV) pip install --quiet --python "$$WORK/venv/bin/python" "$$WORK"/*.whl; \
cp -R tests/fixtures/extension_package "$$WORK/ext"; \
cp -R templates/extension_package "$$WORK/template"; \
$(UV) pip install --quiet --python "$$WORK/venv/bin/python" "$$WORK/ext"; \
echo "→ asking the installed CLI what it can see, from $$EMPTY"; \
cp tests/fixtures/extension_package/verify_seams.py "$$EMPTY/"; \
cd "$$EMPTY" && "$$WORK/venv/bin/python" verify_seams.py
cd "$$EMPTY" && "$$WORK/venv/bin/python" verify_seams.py; \
echo "→ installing templates/extension_package and running its tests"; \
$(UV) pip install --quiet --python "$$WORK/venv/bin/python" "$$WORK/template" \
"pytest>=8.0" "pytest-asyncio>=1.0,<2" "pytest-env>=1.1,<2"; \
cd "$$WORK/template" && "$$WORK/venv/bin/python" -m pytest -q -p no:cacheprovider

# --- housekeeping ----------------------------------------------------------

Expand Down
Loading
Loading