Search by

netresearch / t3-cowriter

netresearch

AI Cowriter - AI assistant in CKEditor that helps editors write page content.

Package info

github.com/netresearch/t3x-cowriter

Documentation

Type:typo3-cms-extension

pkg:composer/netresearch/t3-cowriter

Statistics

Installs: 15 796

Dependents: 1

Suggesters: 0

Stars: 10

Open Issues: 6

v3.27.0 2026-11-08 00:42 UTC

README

AI Cowriter for TYPO3

CI codecov

OpenSSF Scorecard OpenSSF Best Practices SLSA 3

PHPStan PHP 8.2+ TYPO3 v13 TYPO3 v14 License: GPL v3 Latest Release Contributor Covenant

Composer Downloads Extension Stability TYPO3 Version

AI-powered content assistant for TYPO3 CKEditor - write better content with help from AI.

Cowriter dialog in TYPO3 v14 backend

Features

  • Task-based dialog: Select from predefined tasks (Improve, Summarize, Extend, Fix Grammar, Translate) with result preview before inserting
  • Vision / Alt Text: Analyze images and generate descriptive alt text via the CKEditor toolbar
  • Translation: Translate selected text into 10+ languages directly from the toolbar dropdown
  • Image generation (off by default): Describe an image, an OpenAI image model generates it via nr-llm, and it is stored in the editor's upload folder and inserted. Switch it on with the extension setting image.enable; image.model chooses the model. Requires the image plugin of netresearch/rte-ckeditor-image in the editor configuration. File fields such as the images of a content element get a "Generate image" button too, which adds the stored file to the field as a new file reference
  • Present as tabs or accordion (off by default): A button next to the rich text of a text element cuts the saved text into sections, at its headings or, without headings, as the language model proposes, and after a preview creates a new Tabs or Accordion element of bootstrap_package directly after the original, with one item per section, hidden; one more click shows it and hides the original (not offered for an original with translations or a connected translation). The original element is not changed until then. Switch it on with the extension setting presentation.enable
  • Audience variant (off by default): A button next to the rich text of a text element lets the editor choose an audience (and a tone of voice) from the operator's nr-llm prompt snippets; the language model rewrites the saved header and text for it, and after the editor reviewed the proposal a copy with that text is created directly after the original, hidden. With contexts installed (optional) the editor gives the copy a context, so it is shown only while that context is active, and one more click shows it and hides the original in that context; without it the copy stays hidden and the editor is told. Switch it on with the extension setting variant.enable
  • Inline suggestions (off by default): While an editor types at the end of a paragraph, the language model proposes how the sentence goes on; the proposal appears as grey text after the cursor, Tab inserts it, any other key discards it. Switch it on with the extension setting inlineSuggestions.enable; each editor can switch it off with a toolbar button. Every suggestion counts against the editor's nr-llm budget
  • Field suggestions: A light bulb button next to plain text fields asks the language model for alternative values, written for the field's purpose and kept within its length limit: page title, navigation title, subtitle, abstract, SEO title, description, keywords, Open Graph and X (Twitter) title and description, URL segment, and the header and subheader of content elements. The extension setting fieldSuggestions.fields changes the list. Suggest values for all fields with AI in the document header reviews all those fields of a record in one request and shows a table of suggestions, each with its reason; the editor checks the values to apply, can edit them, and saves the record himself
  • Prompt Templates: Load reusable prompt presets from the backend for consistent content generation
  • Tool Calling: Structured function calling that lets the LLM query TYPO3 content during conversations
  • CKEditor Integration: Six toolbar components — main dialog, vision, translation, templates, image generation, and the inline suggestions toggle
  • Visual Editor: The toolbar components also appear when content is edited in the frontend preview with friendsoftypo3/visual-editor, with the same preset and the record's site configuration
  • Multi-Provider Support: Works with all LLM providers supported by nr-llm (OpenAI, Claude, Gemini, etc.)
  • Secure Backend Proxy: API keys never exposed to frontend — all requests proxied through TYPO3 backend
  • Context control: Choose between selected text or full content element as context
  • Ad-hoc instructions: Add custom instructions per request (e.g., "Write in formal tone")
  • Rate limiting: 20 requests/minute per backend user; inline suggestions have their own limit of 12 requests/minute
  • Streaming: Server-Sent Events for real-time completions
  • Content sanitization: Frontend DOMParser-based sanitization with CKEditor's HTML processing pipeline

Requirements

  • PHP 8.2+
  • TYPO3 v13.4 LTS or v14.3 LTS
  • netresearch/nr-llm 0.43.9 or later, up to 0.43 (LLM provider abstraction)

Installation

Install via Composer:

composer require netresearch/t3-cowriter

Configuration

1. Configure nr-llm Extension

First, set up at least one LLM provider in the nr-llm extension:

  1. Navigate to AI → Setup
  2. Add a provider (e.g., OpenAI with your API key)
  3. Create a model configuration
  4. Create an LLM configuration and set it as default

2. Add CKEditor Preset

Option A: Use the included preset

Add the cowriter preset to your Page TSconfig:

RTE.default.preset = cowriter

Option B: Extend your existing preset

Add to your RTE configuration YAML:

editor:
  config:
    importModules:
      - { module: '@netresearch/t3_cowriter/cowriter', exports: ['Cowriter'] }
    toolbar:
      items:
        - cowriter
        - cowriterVision
        - cowriterTranslate
        - cowriterTemplates
        - cowriterImage
        - cowriterInlineSuggestions

Usage

  1. Open a content element with a rich text field in the TYPO3 backend
  2. Optionally select text in CKEditor (or leave empty to use full content)
  3. Click the Cowriter button in the toolbar
  4. A dialog opens where you can:
    • Select a task (Improve Text, Summarize, Extend, Fix Grammar, Translate to EN/DE)
    • Choose context scope — selected text or whole content element
    • Add instructions — optional ad-hoc rules like "Write in formal tone"
  5. Click Execute — the task is sent to the LLM
  6. Review the result in the preview area
  7. Click Insert to replace content, or Retry to re-execute

Available tasks

Tasks are managed in the nr-llm extension (tx_nrllm_task table) with category = 'content'. Default tasks:

Task Description
Improve Text Enhance readability and quality
Summarize Create a concise summary
Extend / Elaborate Add depth and detail
Fix Grammar & Spelling Correct grammar and spelling
Translate to English Translate to English
Translate to German Translate to German

Architecture

CKEditor Toolbar
  ├─ cowriter         → [CowriterDialog] → AIService.js → AjaxController
  ├─ cowriterVision   → AIService.js     ──────────────→ VisionController
  ├─ cowriterTranslate→ AIService.js     ──────────────→ TranslationController
  ├─ cowriterTemplates→ AIService.js     ──────────────→ TemplateController
  ├─ cowriterImage    → [ImageDialog]    → AIService.js → ImageGenerationController → DallEImageService (nr-llm), FAL
  ├─ (typing pause)   → [InlineSuggestions] → AIService.js → InlineSuggestionController → CompletionService (nr-llm)
  └─ (tool calling)   → AIService.js     ──────────────→ ToolController
                                                              ↓
                                                   [LlmServiceManagerInterface]
                                                              ↓
                                                        [nr-llm Provider]
                                                              ↓
                                                        [External LLM API]

All LLM requests are proxied through the TYPO3 backend. API keys are stored encrypted and never exposed to the browser.

Development

Prerequisites

  • DDEV for local development
  • PHP 8.2+ with required extensions

Setup

ddev start
ddev composer install
ddev install-v14

Testing

# Run all quality checks (lint, phpstan, rector, code style)
make ci

# Run all tests (unit, functional, integration, e2e)
make test

# Individual test suites
make test-unit           # Unit tests
make test-functional     # Functional tests
make test-integration    # Integration tests
make test-e2e            # End-to-end tests

# Code quality
make lint               # PHP-CS-Fixer
make phpstan            # PHPStan level 10

Test Coverage

Target: >80% code coverage

make test-coverage
open var/coverage/unit/index.html

Security

  • API keys stored in nr-llm with sodium encryption
  • All backend AJAX endpoints require TYPO3 authentication
  • Frontend DOMParser-based content sanitization via CKEditor's HTML processing pipeline
  • TYPO3 backend route authentication with nonce-based URL tokens
  • Content Security Policy (CSP) compatible

What users can expect from the extension in terms of security — what editor content leaves the system and to whom, how AI output enters the editor, the threat model, trust boundaries and the controls that implement them — is in docs/SECURITY-ASSURANCE.md.

Migration to v3.x

Version 3.0 requires TYPO3 v13.4+ and PHP 8.2+. It removes the frontend-only architecture and uses the nr-llm extension for provider-agnostic LLM access. API keys are no longer stored in extension settings.

See CHANGELOG.md for migration details.

License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

Contributing

See CONTRIBUTING.md for contribution guidelines.

Contact

Netresearch DTT GmbH - Your TYPO3 and eCommerce experts.

Twitter | LinkedIn | GitHub