Developer
This chapter is for developers who work on the extension itself or extend it. How a job flows through the pipeline is described in Architecture, and the reasons behind the main design choices in Architecture Decision Records.
Local environment
The repository ships a DDEV setup with the system binaries and a worker container (see Local development with DDEV). Use it to run the backend module and the worker. The tests do not run inside DDEV; they have their own runner.
Running the tests
Every test and quality tool runs through Build/,
which starts the TYPO3 core-testing Docker images. The script in the
repository is a small bootstrap: on a fresh clone it runs
composer install and then hands over to the shared runner that
netresearch/ installs as .Build/.
./Build/Scripts/runTests.sh -s unit # unit tests
./Build/Scripts/runTests.sh -s functional # functional tests (SQLite)
./Build/Scripts/runTests.sh -s functional -d mariadb # functional tests against MariaDB
./Build/Scripts/runTests.sh -s lint # PHP lint
./Build/Scripts/runTests.sh -p 8.3 -s cgl -n # code style check
./Build/Scripts/runTests.sh -s phpstan # static analysis
./Build/Scripts/runTests.sh -s rector -n # Rector dry run
-n makes cgl and rector report only; without it they rewrite the
files. The default PHP version is 8.5; -p selects another one. Run the
code-style check on PHP 8.3, because the CI code-style job uses the first PHP
version of its matrix. PHPStan runs at level 8 over Classes/, as
configured in phpstan..
Adding a generator
A generator produces the artifacts of one type. The orchestrator runs exactly
the services tagged nr_; a class that is not
tagged is never run, even when it implements the interface.
-
Implement
Netresearchwith its two methods:Nr Repurpose Generator Artifact Generator Interface supports— whether the job asked for this artifact, usually by reading the job's(Generation Context $ctx): bool want_*flag from$ctx->job;Row generate— inserts the generator's own artifact rows, fills them, and returns whether it succeeded.(Generation Context $ctx): bool
Extend
Abstractrather than starting from scratch. It provides the Fluid theme rendering, per-run temporary directories,Generator failandArtifact () specialized, the budget and availability check for text-to-speech and image calls.Allowed () Abstractis the base for a structured text format, andText Generator Abstractfor a document printed to PDF.Document Generator Podcastis the reference for a generator that combines an LLM call with specialized calls and local rendering.Generator -
Register the class in
Configuration/with the tag, the same way as the existing generators:Services. yaml Configuration/Services.yamlNetresearch\NrRepurpose\Generator\MyGenerator: public: true tags: ['nr_repurpose.artifact_generator']Copied! - Check the capability grants before a speech or image call
(
$ctx->grants->audio,$ctx->grants->vision, see ADR-008: Capability Permissions Checked Before Spend), and callspecializedbefore spending on them.Allowed () - Name the pipeline step on every nr-llm call with a constant from
Netresearch, so nr-llm's analytics attribute its cost (see Cost attribution).Nr Repurpose Service Caller Source
One failing generator does not stop the others: record the failure on the
artifact with fail and return false.
Another image or speech backend
The generators never call nr-llm's image or speech services directly. They use
Image and Speech, which
Configuration/ aliases to Dall and
Open. A different backend is a new adapter behind the
interface and a changed alias; the adapter still reaches the provider through
nr-llm, which holds the keys (see ADR-003: Provider Credentials Delegated to nr-llm).