Skip to content

AI-Provider ​

Einrichtung und Editor-Funktionen beschreibt KI-Unterstützung.

Provider-Schicht ​

Treiber implementieren Renick\Content\Classes\Ai\AiProvider:

php
interface AiProvider
{
    public function chat(array $messages, ?array $schema = null, array $options = []): AiResponse;
    public function listModels(): array;
    public function testConnection(): ConnectionResult;
}

OpenAiDriver (https://api.openai.com/v1) und OpenRouterDriver (https://openrouter.ai/api/v1) teilen sich OpenAiCompatibleDriver, gebaut auf Laravels Http-Client, sodass Tests Http::fake() nutzen können. MockDriver antwortet offline.

  • ProviderManager::make($feature) liefert den Treiber mit dem Modell für translate oder draft. Eine leere Modell-Einstellung fällt auf AiSetting::DEFAULT_MODELS des aktiven Providers zurück (gpt-5.6-terra, bei OpenRouter openai/gpt-5.6-terra). Ist das monatliche Token-Budget erreicht, wirft es eine Exception.
  • ProviderManager::recordUsage() protokolliert die Token-Zahlen in renick_content_ai_usage.
  • Erhält chat() ein JSON-Schema, fordert der Treiber Structured Output per OpenAI-json_schema an.
  • Reasoning-Modelle (GPT-5-Familie, o-Serie) erhalten keine temperature, und OpenAI-Anfragen senden max_completion_tokens. Lehnt ein anderes Modell die Temperatur ab, wird die Anfrage einmal ohne sie wiederholt.
  • Reasoning-Modelle erhalten zusätzlich reasoning_effort aus renick.content::limits.ai_reasoning_effort (RENICK_CONTENT_AI_REASONING_EFFORT, Standard low; leer behält den Standard des Modells). Eine Chat-Anfrage hat insgesamt ai_timeout Sekunden (RENICK_CONTENT_AI_TIMEOUT, Standard 300), verteilt auf zwei Versuche, danach erscheint eine lesbare Timeout-Meldung. Bei OpenRouter werden OpenAI-Modelle an OpenAIs Standard-Endpunkt geleitet (provider.order, Flex-Tarif ausgenommen).
  • Netzwerkfehler, Timeouts sowie HTTP-5xx- und 429-Antworten werden zu übersetzten Meldungen (TransportError); das rohe cURL- oder Antwortdetail wird als Warnung geloggt. Andere 4xx-Antworten behalten die Begründung des Providers, etwa ein unbekanntes Modell.
  • Über REST haben POST /translate und POST /draft ein eigenes Limit von 10 Requests pro Minute pro Token, siehe REST-API.

Das beforeRequest-Event ​

Direkt vor dem HTTP-Aufruf durchlaufen Chat-Payloads ein haltendes Event, Bild- und Firecrawl-Requests nicht. Gib ein Array zurück, um den Payload zu ersetzen:

php
Event::listen('renick.content.ai.beforeRequest', function (&$payload) {
    Log::info('AI request', ['model' => $payload['model']]);
    // optionally: return $modifiedPayload;
});

Mock-Treiber ​

Der Provider mock braucht keinen Schlüssel. Übersetzte Werte kommen mit dem Präfix "[LANG] " zurück, Entwürfe liefern einen Heading-Block Draft: <brief>, alles andere wird als MOCK: … zurückgegeben.

Translator und Drafter ​

Translator::translateDocument() übersetzt die Textfelder aus der Definition jedes Blocks: nicht leere Strings von text, textarea, richeditor, richtext- und markdown-Feldern, auch in Repeater-Einträgen und Kindblöcken, außer ein Feld ist translatable: false oder sein Name kennzeichnet einen technischen Wert (siehe Blöcke erstellen). Blöcke ohne Definition greifen auf text, html, caption, alt, title, author und label zurück. Es sendet Chunks von 40 Werten, behält bei fehlender Übersetzung das Original und wirft eine Exception, wenn das Ergebnis ungültig ist. Die Anrede wird einmal pro Dokument bestimmt (Translator::register()) und im Prompt jedes Pakets wiederholt, sodass Deutsch durchgehend bei Sie oder du bleibt.

Drafter::draft($brief, $templateJson, $researchContext, $length, $allowExternalImages, $fileContext, $locale, $context) übergibt im Prompt einen Katalog aller registrierten Blöcke. Die Antwort erhält neue IDs und wird gegen Schema und Blockregeln validiert, mit höchstens 2 Reparaturversuchen. Danach setzt der Drafter Standard-Blockeinstellungen und entfernt externe Bild-URLs, sofern sie nicht erlaubt sind. Mit $context = 'article' verbietet der Prompt Heros und Sektionen auf oberster Ebene, und DraftArticlePolicy macht aus jedem Hero eine Überschrift plus Richtext und entpackt Sektionen der obersten Ebene.

Bilder und Recherche ​

ImageGenerator ruft die Bild-APIs direkt auf: OpenAI images/generations (Standard gpt-image-2, dazu die Einstellung Bildqualität, sofern sie nicht auto ist, Hochskalieren über images/edits) oder OpenRouter images (Standard google/gemini-3.1-flash-image, kein Hochskalieren). FirecrawlClient kapselt https://api.firecrawl.dev/v1 für Recherchieren & entwerfen.

Hartes Privacy-Gate

Solange nicht Ausgehende Recherche-Anfragen erlauben aktiv und ein Firecrawl-API-Schlüssel gesetzt ist, wirft jeder Firecrawl-Aufruf eine Exception. Kein inhaltsbezogener Request verlässt die Installation.