Backup #2080

ID2080
Dateipfad/var/www/dev.campus.systemische-tools.de/src/UseCases/Chat/ChatPromptLoader.php
Version1
Typ modified
Größe5.3 KB
Hash1be11fe36d92c6dca4102f1dd92ea61f2ab091c2aeb83e2781d4a1c1436f34f7
Datum2025-12-29 00:08:12
Geändert vonclaude-code-hook
GrundClaude Code Pre-Hook Backup vor Edit-Operation
Datei existiert Ja

Dateiinhalt

<?php

declare(strict_types=1);

namespace UseCases\Chat;

// @responsibility: Lädt Chat-Prompts aus ContentConfig-Repository

use Domain\Repository\ContentConfigRepositoryInterface;

final class ChatPromptLoader
{
    public function __construct(
        private ContentConfigRepositoryInterface $configRepo
    ) {
    }

    /**
     * Load style prompt from author profile.
     *
     * @throws \RuntimeException When profile cannot be parsed
     */
    public function getStylePrompt(int $profileId): ?string
    {
        if ($profileId === 0) {
            return null;
        }

        $profile = $this->configRepo->getAuthorProfile($profileId);
        if ($profile === null) {
            return null;
        }

        $config = json_decode($profile['content'] ?? '{}', true);
        if ($config === null) {
            return null;
        }

        $parts = [];

        if (isset($config['stimme']['ton'])) {
            $parts[] = 'Ton: ' . $config['stimme']['ton'];
        }
        if (isset($config['stimme']['perspektive'])) {
            $parts[] = 'Perspektive: ' . $config['stimme']['perspektive'];
        }
        if (isset($config['stil']['fachsprache']) && $config['stil']['fachsprache']) {
            $parts[] = 'Verwende Fachsprache';
        }
        if (isset($config['stil']['beispiele']) && $config['stil']['beispiele'] === 'häufig') {
            $parts[] = 'Nutze häufig Beispiele';
        }
        if (isset($config['stil']['listen']) && $config['stil']['listen'] === 'bevorzugt') {
            $parts[] = 'Bevorzuge Listen und Bullet-Points';
        }
        if (isset($config['tabus']) && is_array($config['tabus'])) {
            $parts[] = 'Vermeide: ' . implode(', ', $config['tabus']);
        }

        if ($parts === []) {
            return null;
        }

        return 'Schreibstil (' . ($profile['name'] ?? 'Profil') . '): ' . implode('. ', $parts) . '.';
    }

    /**
     * Load system prompt by ID.
     *
     * @throws \RuntimeException When prompt cannot be parsed
     */
    public function getSystemPrompt(int $promptId): ?string
    {
        if ($promptId === 0) {
            return null;
        }

        $prompt = $this->configRepo->getSystemPrompt($promptId);
        if ($prompt === null) {
            return null;
        }

        $content = json_decode($prompt['content'] ?? '{}', true);

        return $content['prompt'] ?? null;
    }

    /**
     * Load structure prompt.
     *
     * @throws \RuntimeException When structure cannot be parsed
     */
    public function getStructurePrompt(int $structureId): ?string
    {
        if ($structureId === 0) {
            return null;
        }

        $structure = $this->configRepo->getStructure($structureId);
        if ($structure === null) {
            return null;
        }

        $name = $structure['name'] ?? 'Struktur';
        $config = json_decode($structure['content'] ?? '{}', true);
        if ($config === null) {
            return null;
        }

        $parts = ["Formatiere deine Antwort als: {$name}"];

        if (isset($config['sections']) && is_array($config['sections'])) {
            $parts[] = 'Struktur: ' . implode(' → ', $config['sections']);
        }
        if (isset($config['max_chars'])) {
            $parts[] = 'Maximale Länge: ' . $config['max_chars'] . ' Zeichen';
        }
        if (isset($config['min_words'])) {
            $parts[] = 'Mindestens ' . $config['min_words'] . ' Wörter';
        }
        if (isset($config['max_words'])) {
            $parts[] = 'Maximal ' . $config['max_words'] . ' Wörter';
        }
        if (isset($config['format']) && $config['format'] === 'qa') {
            $parts[] = 'FAQ mit ' . ($config['min_questions'] ?? 3) . ' Paaren';
        }
        if (isset($config['hashtags']) && $config['hashtags']) {
            $parts[] = 'Füge passende Hashtags hinzu';
        }
        if (isset($config['cta']) && $config['cta']) {
            $parts[] = 'Schließe mit einem Call-to-Action ab';
        }

        return implode('. ', $parts) . '.';
    }

    /**
     * Get structure name by ID.
     */
    public function getStructureName(int $structureId): ?string
    {
        if ($structureId === 0) {
            return null;
        }

        $structure = $this->configRepo->getStructure($structureId);

        return $structure['name'] ?? null;
    }

    /**
     * Compose effective system prompt from components.
     */
    public function composeSystemPrompt(
        int $systemPromptId,
        int $structureId,
        int $authorProfileId,
        bool $hasContext,
        string $defaultRagPrompt,
        string $defaultNoContextPrompt
    ): string {
        $systemPrompt = $this->getSystemPrompt($systemPromptId);
        $structurePrompt = $this->getStructurePrompt($structureId);
        $stylePrompt = $this->getStylePrompt($authorProfileId);

        // Add structure to system prompt
        if ($structurePrompt !== null) {
            $systemPrompt = ($systemPrompt ?? '') . "\n\n" . $structurePrompt;
        }

        // Use default if no system prompt
        $effectivePrompt = $systemPrompt ?? ($hasContext ? $defaultRagPrompt : $defaultNoContextPrompt);

        // Add style prompt
        if ($stylePrompt !== null && $stylePrompt !== '') {
            $effectivePrompt .= "\n\n" . $stylePrompt;
        }

        return $effectivePrompt;
    }
}

Vollständig herunterladen

Aktionen

Herunterladen

← Zurück zur Übersicht