*/ private const array DEFAULTS = [ 'specs_research' => <<<'PROMPT' List all known technical specifications for the {{articleType}}: "{{subject}}". Include: processor, RAM, storage variants, display size and resolution, GPU, battery capacity, ports, connectivity, weight, dimensions, OS, and any other relevant specs. If you know this device, be specific and complete. If it is unknown, say so explicitly. PROMPT, 'ebay_title' => <<<'PROMPT' Create a concise eBay listing title (max 80 characters) for this {{typeName}}. Device: {{deviceLabel}} Use the most important specifications. Include condition if not "new". Condition: {{condition}} {{specsSection}} Return ONLY the title text, no quotes, no explanation. PROMPT, 'ebay_description' => <<<'PROMPT' Create a professional eBay listing description in German for this {{typeName}}. Device: {{deviceLabel}} Include all available specifications in a clear, structured format. Mention the condition: {{condition}}. {{conditionNotes}} {{specsSection}} Use HTML formatting (ul, li, strong tags). Max 2000 characters. PROMPT, 'vision_analyze' => <<<'PROMPT' Look at this nameplate/label photo of IT hardware. Extract the manufacturer (brand), model number/designation, and serial number visible on the label. Do not guess or add information not on the label. Respond in exactly this format (use empty string if not visible): MANUFACTURER: MODEL: SERIAL: PROMPT, 'json_coding' => <<<'PROMPT' Convert the following hardware specifications to a JSON object. The JSON must use these exact keys (UUIDs) and follow the indicated value formats: {{schema}} {{missingHint}} Specifications text: {{specsText}} Return ONLY valid JSON. No explanation. No markdown. No extra text. JSON: PROMPT, ]; public function __construct( private readonly PromptTemplateRepositoryInterface $repository, ) { } /** * Renders a prompt template by key, substituting {{variable}} placeholders. * * @param array $variables */ public function render(string $key, array $variables = []): string { $template = $this->repository->findByKey($key); $body = $template?->getBody() ?? self::DEFAULTS[$key] ?? throw new \InvalidArgumentException("Unknown prompt template key: {$key}"); $search = array_map(static fn (string $k) => '{{'.$k.'}}', array_keys($variables)); return str_replace($search, array_values($variables), $body); } /** * Returns all known prompt keys with their available variables. * * @return array> */ public static function knownKeys(): array { return [ 'specs_research' => ['articleType', 'subject'], 'ebay_title' => ['typeName', 'deviceLabel', 'condition', 'specsSection'], 'ebay_description' => ['typeName', 'deviceLabel', 'condition', 'conditionNotes', 'specsSection'], 'vision_analyze' => [], 'json_coding' => ['schema', 'missingHint', 'specsText'], ]; } /** @return string */ public static function defaultFor(string $key): string { return self::DEFAULTS[$key] ?? ''; } }