TYPO3 Extension · nr-llm

One LLM setup. Every extension. Full admin control.

nr-llm is shared AI infrastructure for TYPO3 — like the caching framework, but for language models. Administrators configure providers once in the backend; every AI-powered extension on the site uses them automatically. Supports OpenAI, Anthropic Claude, Google Gemini, Ollama, and more.

Supported providers
OpenAI Anthropic Claude Google Gemini Mistral AI Ollama + Groq, OpenRouter, Azure OpenAI

The problem

Every TYPO3 extension that wants AI capabilities today has to solve the same infrastructure problems on its own. When a site runs three AI extensions, that means three separate API key configurations, three places to check when something breaks, and no way to switch providers globally.

  • Build its own provider integration — HTTP calls, authentication, error handling, streaming
  • Store API keys in its own way, often as plaintext in extension settings
  • Create its own backend configuration UI
  • Leave administrators with no central overview of AI usage or costs

The solution

nr-llm provides the missing shared layer between your extensions and the LLM providers. Extension developers add AI in a few lines of dependency injection; administrators manage every connection, key, and budget from one backend module.

Extensions inject a single service interface and call methods for chat, completion, translation, vision, embeddings, streaming, and tool calling. Provider selection, API keys, caching, and error handling are all managed by nr-llm.

Underneath, a provider abstraction layer maps a common interface onto OpenAI, Anthropic, Gemini, Ollama, OpenRouter, Mistral, Groq, Azure OpenAI, and any OpenAI-compatible endpoint. Switching providers is an admin setting, not a code change.

The Admin Tools > LLM backend module holds encrypted keys, usage and cost tracking, per-user budgets, and a setup wizard — restricted to administrators.

Your extensions Cowriter · SEO Assistant · …
nr-llm service layer Chat · Translation · Vision · Embeddings · Streaming · Tools · Caching
Provider abstraction OpenAI · Anthropic · Gemini · Ollama · Mistral · Groq · …
Admin Tools > LLM Encrypted keys · Usage & cost · Setup wizard
Extensions call the nr-llm service layer (chat, translation, vision, embeddings, streaming, tool calling, caching), which sits on a provider abstraction layer (OpenAI, Anthropic, Gemini, Ollama, and more), backed by the Admin Tools > LLM backend module for encrypted keys, usage tracking, and the setup wizard.

Core concepts

nr-llm is organized around a small set of building blocks. Each one solves a problem you would otherwise re-implement in every AI extension.

Provider abstraction

All providers implement one common interface. OpenAI, Anthropic Claude, Google Gemini, Ollama, OpenRouter, Mistral, Groq, Azure OpenAI, and any OpenAI-compatible endpoint (vLLM, LocalAI, LiteLLM) are reachable through the same service calls. Switch provider with a single configuration change — no code edits, no vendor lock-in.

Read the deep dive →

Encrypted API keys via nr-vault

Every API key is stored as a vault identifier (UUID) using nr-vault envelope encryption. nr-llm never stores or logs raw keys in plain text. Error messages are sanitized to strip secret-bearing query parameters before anything is logged.

Read the deep dive →

Three-tier configuration

A Provider holds an endpoint, encrypted key, and adapter type. A Model references a provider and defines its model id, capabilities, and pricing. A Configuration references a model and adds use-case settings — system prompt, temperature, token limits. This lets you keep multiple keys per provider (prod/dev/backup) and reuse model definitions across use cases.

Feature services

High-level services cover common tasks: CompletionService for text generation with format and creativity control, TranslationService with formality and glossary support, VisionService for alt-text and image analysis, and EmbeddingService for text-to-vector conversion with similarity calculations.

Streaming and tool calling

Stream responses chunk by chunk with a single foreach over streamChat() for real-time UIs. Tool/function calling lets the model request functions your code executes, via chatWithTools() — the response reports which tools were called so you can process them.

Read the deep dive →

RAG site-search tools

41 built-in read-only function-calling tools in 8 toggleable groups give the model grounded access to the TYPO3 instance — content search, TCA/FlexForm schema, TypoScript, source and exception reads, FAL files, diagnostics, and backend accounts. The rag group returns cited site-content evidence from the installed search index (EXT:solr, ke_search, indexed_search, or a database fallback).

Read the deep dive →

Per-user budgets and usage tracking

Cap per-backend-user spending across every preset by requests, tokens, or estimated cost, on a daily or monthly basis. The Analytics view shows cost and usage trends with breakdowns per provider, model, and service, plus per-user consumption against monthly budgets.

TYPO3 caching-framework integration

Responses are cached automatically through TYPO3's caching framework — using whatever backend the instance configures (Redis, Valkey, Memcached, or the default). Embedding results cache deterministically with a 24-hour default lifetime, and cache lifetimes are configurable per operation type.

Who it is for

nr-llm serves three audiences with the same shared foundation.

Extension developers

Add AI capabilities without building provider integrations, handling API keys, or implementing caching and streaming. Inject one service interface and call it. Register custom providers when you need them.

TYPO3 administrators

Manage every AI connection, encrypted key, and provider configuration from a single backend module. Switch from OpenAI to Anthropic without touching extension code. Set per-user budgets and watch cost and usage in one dashboard.

Agencies and solution architects

Reduce integration effort across client projects with a consistent AI architecture and no vendor lock-in. Encrypted keys, admin-only access, and SBOM plus SLSA provenance on every release support compliance. Ollama gives a local-first option for data-sensitive environments.

Developers

Developer kickstart

Add AI to your TYPO3 extension in a few minutes — no API key handling, no HTTP client code, no provider-specific logic.

Require the package

Install via Composer. Then activate in Admin Tools > Extensions and run Admin Tools > LLM > Setup Wizard.

bash
composer require netresearch/nr-llm

Inject the service you need

Inject LlmServiceManagerInterface via constructor promotion and call it. Provider selection, API keys, caching, and error handling are all managed by nr-llm.

php
use Netresearch\NrLlm\Service\LlmServiceManagerInterface;

class MyController
{
    public function __construct(
        private readonly LlmServiceManagerInterface $llm,
    ) {}

    public function summarizeAction(string $text): string
    {
        return $this->llm->complete("Summarize: {$text}")->content;
    }
}

Use the services you need

Chat, completion, streaming, embeddings and tool calling are methods on the injected LlmServiceManagerInterface. Translation and vision alt-text are dedicated feature services — inject them the same way. Tool calling is a request/execute/reply loop; the Streaming & Tool Calling deep dive has the complete example.

php
use Netresearch\NrLlm\Domain\ValueObject\ChatMessage;

$messages = [
    ChatMessage::system('You are a helpful TYPO3 assistant.'),
    ChatMessage::user('Explain TYPO3 content elements in one paragraph.'),
];

// Chat & completion (LlmServiceManagerInterface)
$answer = $this->llm->chat($messages)->content;
$answer = $this->llm->complete('Summarize the TYPO3 release cycle.')->content;

// Streaming — yields string chunks
foreach ($this->llm->streamChat($messages) as $chunk) {
    echo $chunk;
}

// Embeddings — EmbeddingResponse carries the vector
$embedding = $this->llm->embed('semantic search query');

// Translation — dedicated service, returns a TranslationResult
$german = $this->translationService->translate('Hello world', 'de')->getText();

// Vision alt-text — dedicated service
$altText = $this->visionService->generateAltText($imageUrl);

Handle failures with typed exceptions

Every provider error is a typed exception. Catch the ones you care about and show a friendly message; the fallback chain and retries have already run before these surface.

php
use Netresearch\NrLlm\Exception\BudgetExceededException;
use Netresearch\NrLlm\Provider\Exception\ProviderRateLimitException;
use Netresearch\NrLlm\Provider\Exception\ProviderConnectionException;
use Netresearch\NrLlm\Provider\Exception\FallbackChainExhaustedException;
use Netresearch\NrLlm\Provider\Exception\ProviderResponseException;

try {
    return $this->llm->complete("Summarize: {$text}")->content;
} catch (BudgetExceededException) {
    return 'The AI budget for this account is exhausted.';
} catch (ProviderRateLimitException) {
    return 'The AI provider is rate-limiting requests. Please retry shortly.';
} catch (FallbackChainExhaustedException | ProviderConnectionException) {
    return 'Could not reach any AI provider right now.';
} catch (ProviderResponseException $e) {
    $this->logger->warning('LLM provider error', ['status' => $e->httpStatus]);
    return 'The AI service returned an error.';
}

Tune output and get structured JSON back

ChatOptions ships tuned presets — factual, creative, balanced, json, code — plus fluent overrides. CompletionService::completeJson() returns a decoded array, so you extract fields directly.

php
use Netresearch\NrLlm\Service\Option\ChatOptions;

// Deterministic output, capped length
$options = ChatOptions::factual()->withMaxTokens(200);
$summary = $this->llm->complete('Summarize the changelog.', $options)->content;

// Decoded JSON straight from the model
$data = $this->completionService->completeJson(
    'Return {"title": ..., "tags": [...]} for this article: ' . $article,
);
$title = $data['title'];

For admins

For administrators

The Admin Tools > LLM backend module gives administrators full control over AI on the site — providers, models, configurations, budgets, and analytics in one place.

Providers, Models, Configurations

Register API connections (OpenAI, Anthropic, Gemini, Ollama, and more), define which models are available and their capabilities, and create use-case presets with temperature, system prompts, and token limits.

Setup wizard

The Setup Wizard auto-detects your provider type from the endpoint URL, discovers available models, and generates a ready-to-use configuration in five guided steps. Paste your API key and go.

AI-powered wizards

The Task Wizard and Configuration Wizard generate complete tasks and configurations — system prompt, parameters, and model recommendation — from a plain-language description. A Fetch Models button auto-fills capabilities and pricing from the provider API.

User budgets and analytics

Cap per-backend-user spending by requests, tokens, or cost on a daily or monthly basis across every preset. The Analytics view shows estimated cost and usage trends with breakdowns per provider, model, and service, plus per-user consumption against budgets.

Tools and RAG

41 read-only function-calling tools in 8 toggleable groups let models inspect content, schema, configuration, code, files, system diagnostics, and accounts — with the rag group returning cited evidence from the installed search index.

Tool Playground

The admin-only Playground runs the bounded agent loop against any configuration and streams the whole dialog live — every request, response, and tool execution — plus a dry-run mode that shows the exact prompt without calling the model.

Resilience and security

Configurations can list fallback configurations to retry against on connection errors, HTTP 5xx, or rate limits. Per-capability permissions map to native TYPO3 backend-group options. Keys are stored encrypted via nr-vault and the module is restricted to administrators.

On-device AI

Ask nr-llm

Ask a question about nr-llm and get an answer generated entirely in your browser by Chrome's built-in AI (Gemini Nano). Answers are grounded in this site's content.

Architecture

Architecture

nr-llm uses a three-tier configuration hierarchy that separates concerns cleanly. A Configuration (use-case settings such as system prompt, temperature, and max tokens) references a Model (model id, capabilities, pricing), which references a Provider (endpoint, encrypted API key, adapter type). This lets you keep multiple API keys per provider type, point at custom endpoints such as Azure OpenAI or a local Ollama or vLLM instance, and reuse model definitions across configurations. Requests flow through a middleware pipeline that enforces fallback chains and records usage after each successful call. The extension targets PHP 8.2+ and TYPO3 v13.4 LTS or v14.3 LTS, with a PSR-18 HTTP client.

Read the architecture decisions (89)

Frequently asked questions

Which TYPO3 and PHP versions are supported?

TYPO3 v13.4 LTS or v14.3 LTS, and PHP 8.2 or higher. A PSR-18 compatible HTTP client (such as guzzlehttp/guzzle) is also required. The extension is currently in beta (version 0.22.0).

Which AI providers can I use?

OpenAI, Anthropic Claude, Google Gemini, Ollama, OpenRouter, Mistral, Groq, Azure OpenAI, and any OpenAI-compatible endpoint (vLLM, LocalAI, LiteLLM). Capabilities vary by provider — for example OpenAI, Gemini, and OpenRouter support chat, embeddings, vision, streaming, and tools, while Groq focuses on fast chat and streaming.

Where are API keys stored?

Keys are stored as vault identifiers (UUIDs) via nr-vault envelope encryption. nr-llm never stores or logs raw keys in plain text, and the backend module is restricted to administrators. nr-vault is a required dependency.

Is it free and open source?

Yes. nr-llm is licensed under GPL-2.0-or-later and developed by Netresearch DTT GmbH. The source is on GitHub and the package is on Packagist.

Does it work offline with Ollama?

Yes. Ollama runs models locally and needs no API key, so AI features can work without sending data to external APIs — a local-first option for data-sensitive environments. Ollama supports chat, embeddings, and streaming.

How do I add AI to my own extension?

Require netresearch/nr-llm via Composer, inject LlmServiceManagerInterface (or a specific feature service), and call its methods for chat, completion, translation, vision, embeddings, streaming, or tool calling. You can also register custom providers. See the Developer and Integration guides.

How do I control cost?

Set per-backend-user budgets that cap spending by requests, tokens, or estimated cost on a daily or monthly basis across every preset. Response caching through the TYPO3 caching framework reduces repeat calls, and the Analytics view tracks estimated cost and usage per provider, model, service, and user.

What about data privacy?

You choose the provider, including a local Ollama instance that keeps data on your own infrastructure. Keys are encrypted at rest, access is admin-only, and error messages are sanitized to strip secrets. Treat LLM responses as untrusted content and sanitize user input before sending it, as with any AI integration.

Can I switch providers without changing code?

Yes. All providers implement a common interface, so switching from OpenAI to Anthropic or a local model is a configuration change in the backend, not a code edit. Configurations can also list fallback configurations to retry against on connection errors, HTTP 5xx, or rate limits.

Why use nr-llm instead of calling a provider SDK directly?

Building your own means re-implementing key encryption, provider switching, caching, streaming, tool calling, cost tracking, budgets, guardrails, and error handling in every extension — and hard-coding one vendor. nr-llm centralizes all of that once, so administrators manage providers and keys in one backend module and any extension on the site reuses them with no vendor lock-in.

Is nr-llm GDPR-friendly, and can I keep data in the EU?

You choose the provider per configuration. Running Ollama or another OpenAI-compatible endpoint locally keeps all prompt data on your own infrastructure with no external API calls; for hosted providers you can select EU-region endpoints such as Azure OpenAI. API keys are encrypted at rest via nr-vault, access is admin-only, and error messages are sanitized to strip secrets.

How is nr-llm different from other TYPO3 AI extensions?

nr-llm is not an end-user AI feature — it is shared infrastructure, like the TYPO3 caching framework, that other extensions build on. It provides one provider abstraction across seven-plus providers, encrypted key storage, and typed services, rather than a single bundled use case.

What governance and security controls does nr-llm provide?

Encrypted API keys via nr-vault, an admin-only backend module with per-capability backend-group permissions, a guardrail pipeline that redacts secrets across input, output, and streaming, optional human-in-the-loop approval, and per-user budgets with usage analytics. All 41 built-in tools are read-only. The Governance & Security page covers each control in detail.