.. SPDX-License-Identifier: CC-BY-4.0 .. SPDX-FileCopyrightText: Netresearch DTT GmbH .. include:: /Includes.rst.txt .. _installation: ============ Installation ============ .. _installation-requirements: Requirements ============ .. list-table:: :header-rows: 1 :widths: 30 70 * - Requirement - Notes * - PHP - ``^8.3`` * - TYPO3 - ``^14.3`` (v14.3 LTS only) * - :composer:`netresearch/nr-llm` - ``^0.35 || ^0.36 || ^0.37 || ^0.38 || ^0.39`` — AI access (completion, TTS, image), budget enforcement and one-click configuration presets. * - :composer:`netresearch/nr-vault` - ``^1.1`` — holds the provider keys nr-llm reads; its technical-actor API lets the worker read them (see :ref:`configuration-extension-settings`). * - PHP extension ``curl`` - Fetching ``url`` and ``pdf_url`` sources and sending the social webhook. The worker connects to the addresses the host was checked with, and the time limit covers the whole transfer including the response headers. Without it these requests are refused. * - ``poppler-utils`` - ``pdftoppm`` / ``pdftotext`` for PDF ingestion (Vision OCR and layout tiers). * - ``ffmpeg`` / ``ffprobe`` - Concatenate the podcast MP3 segments and measure segment durations for the WebVTT cue timing. * - ``chromium`` - Headless browser the Node renderer drives to turn HTML into PNGs. * - Node.js - ``>=22.18.0 <25.0.0`` to run the bundled ``render.cjs`` (uses ``playwright-core``). The version ranges are the ones :path:`composer.json` requires; that file is authoritative. .. note:: The system binaries (``poppler-utils``, ``ffmpeg``, ``chromium``) are not PHP dependencies — they must be present on the host (and on the worker host). In the bundled DDEV environment they are baked into the web image. .. _installation-composer: Composer installation ===================== .. code-block:: bash :caption: Install via Composer composer require netresearch/nr-repurpose This pulls in nr-llm and its own dependencies. After installation, set up the extension's database tables and activate it: .. code-block:: bash :caption: Set up the extension vendor/bin/typo3 extension:setup nr_repurpose vendor/bin/typo3 cache:flush The extension creates two tables: .. list-table:: :header-rows: 1 :widths: 45 55 * - Table - Purpose * - :sql:`tx_nrrepurpose_domain_model_job` - One row per generation run (source, selected artifacts, theme, status, progress). * - :sql:`tx_nrrepurpose_domain_model_artifact` - One row per produced artifact (type, variant, FAL file references, transcript, metadata, status). .. _installation-classic: Classic mode (TER) is not supported =================================== .. warning:: nr_repurpose requires a Composer-based TYPO3 installation. Installing it through the Extension Manager (classic mode) is not supported. The extension needs code that only a Composer installation provides: - **A PHP library.** PDF ingestion uses :composer:`smalot/pdfparser`, which :path:`composer.json` requires. The TER package contains no :path:`vendor/` directory, so the library is missing in classic mode. - **The Node renderer's dependencies.** The TER package ships only :path:`Resources/Private/NodeRenderer/render.cjs`, without the :path:`package.json` and :path:`package-lock.json` that :ref:`installation-node-renderer` installs ``playwright-core`` from. Without them the Schaubild, story, slide deck and handout cannot be rendered. The extension is listed in the TYPO3 Extension Repository as `nr_repurpose `__ so it can be found there. Install it with Composer as described in :ref:`installation-composer`. .. _installation-node-renderer: Install the Node renderer ======================== The image renderer is a small Node script under :path:`Resources/Private/NodeRenderer/`. Install its single dependency (``playwright-core``) and rely on the system ``chromium`` instead of letting Playwright download its own browser: .. code-block:: bash :caption: Install the renderer (skip the Playwright browser download) cd Resources/Private/NodeRenderer PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm ci The renderer starts the Chromium binary at ``/usr/bin/chromium``. For another path, see :ref:`configuration-rendering`. .. _installation-openai-key: Hand the provider key to nr-llm =============================== nr_repurpose never reads an API key — it owns no provider credentials at all. Give the key (the examples use OpenAI, the tested default) to nr-llm, which stores it and hands back the identifier its records reference. The normal route is nr-llm's setup wizard in the TYPO3 backend: enter the key, and nr-llm stores it securely and generates the key identifier for you. How it keeps the secret is nr-llm's business and documented there. Two places then refer to that identifier, both of them nr-llm's: the **Provider** record carries it for the chat and vision completions, and nr-llm's extension configuration carries it as ``providers.openai.apiKeyIdentifier`` for the specialized text-to-speech and image services. The Configuration records nr_repurpose ships as presets bake in no provider, model or key at all. See :ref:`configuration-nr-llm`. .. note:: For scripted installs where no one can operate the wizard, nr-llm's storage backend can also be filled from the command line — that is what the bundled DDEV setup does, seeding the identifier ``nr_repurpose_openai``. See :ref:`installation-ddev`. .. _installation-worker: Run the generation worker ======================== Generation runs asynchronously: job submission only dispatches a message, and a Symfony Messenger worker does the actual work. Run a long-lived consumer on a host that has the system binaries and the Node renderer installed: .. code-block:: bash :caption: Consume the generation transport php -d memory_limit=1G vendor/bin/typo3 messenger:consume doctrine --time-limit=3600 --memory-limit=512M Restart the consumer in a loop (systemd, a container restart policy, or a supervisor) so it survives the deliberate time/memory limits that recycle the process. The transport routing is configured in :ref:`configuration-messenger`. .. important:: The PHP ``memory_limit`` must exceed Messenger's ``--memory-limit`` soft restart threshold, with headroom for GD image compositing — otherwise PHP fatals before Messenger can recycle the process, and the unacknowledged message is redelivered into the same crash (re-running paid AI calls). The compositor pre-flights its memory need and fails the single artifact gracefully, but only within the limit PHP actually has. .. note:: The worker host runs ``chromium`` and ``ffmpeg`` and reaches the configured AI providers — bound the outbound HTTP timeout (see :ref:`configuration-http`) so a stalled provider response cannot hang the worker indefinitely. .. _installation-ddev: Local development with DDEV ========================== The repository ships a DDEV setup whose web image already contains ``poppler-utils``, ``ffmpeg`` and ``chromium``, and a sidecar worker container: .. code-block:: bash :caption: Bring up the DDEV environment cp .ddev/.env.dist .ddev/.env # then set OPENAI_API_KEY=sk-… ddev start # builds the web image ddev setup # composer install + TYPO3 setup into .Build/Web ``ddev setup`` installs TYPO3 v14.3 into :path:`.Build/Web`, seeds the OpenAI key into nr-vault under ``nr_repurpose_openai``, wires the nr-llm provider and the messenger routing in :path:`config/system/additional.php`, and installs the Node renderer. The backend is then at ``https://nr-repurpose.ddev.site/typo3/``.