diff --git a/backend/src/main/kotlin/com/condado/newsletter/service/PromptBuilderService.kt b/backend/src/main/kotlin/com/condado/newsletter/service/PromptBuilderService.kt new file mode 100644 index 0000000..ffec939 --- /dev/null +++ b/backend/src/main/kotlin/com/condado/newsletter/service/PromptBuilderService.kt @@ -0,0 +1,61 @@ +package com.condado.newsletter.service + +import com.condado.newsletter.model.EmailContext +import com.condado.newsletter.model.VirtualEntity +import org.springframework.stereotype.Service + +/** + * The single authoritative place in the codebase where AI prompts are constructed. + * No other class may build or modify prompt strings. + */ +@Service +class PromptBuilderService { + + /** + * Builds the full prompt to be sent to the AI, based on the entity's profile + * and the list of recent emails from the company inbox. + * + * @param entity The virtual employee whose turn it is to send an email. + * @param emailContext Recent emails from the IMAP inbox (oldest-first). + * @return The complete prompt string ready to send to the OpenAI API. + */ + fun buildPrompt(entity: VirtualEntity, emailContext: List): String { + val emailSection = if (emailContext.isEmpty()) { + "(No recent emails in the inbox.)" + } else { + emailContext.joinToString("\n\n") { email -> + """ + |From: ${email.from} + |Subject: ${email.subject} + |Received: ${email.receivedAt} + | + |${email.body} + """.trimMargin() + } + } + + return """ + |You are ${entity.name}, ${entity.jobTitle} at "Condado Abaixo da Média SA". + | + |Your personality: ${entity.personality ?: "Professional and formal."} + | + |IMPORTANT TONE RULE: You must write in an extremely formal, bureaucratic, corporate tone — + |as if writing an official memo. However, the actual content of the email must be completely + |casual, trivial, or nonsensical — as if talking to close friends about mundane things. + |The contrast between the formal tone and the casual content is intentional and essential. + | + |Here are the most recent emails from the company inbox (last ${entity.contextWindowDays} days) + |for context: + | + |$emailSection + | + |Write a new email to be sent to the company group, continuing the conversation naturally. + |Reply or react to the recent emails if relevant. Sign off as ${entity.name}, ${entity.jobTitle}. + | + |Format your response exactly as: + |SUBJECT: + |BODY: + | + """.trimMargin() + } +}