Spaces:
Build error
Build error
| # aduc_framework/engineers/prompt_engine.py | |
| # | |
| # Copyright (C) August 4, 2025 Carlos Rodrigues dos Santos | |
| # | |
| # Versão 2.0.0 (Context-Aware Prompt Translator) | |
| # | |
| # O PromptEngine atua como o tradutor entre a lógica de tarefa agnóstica | |
| # do Composer e o formato de prompt específico exigido por um LLM. | |
| # Esta versão é consciente do contexto, sabendo diferenciar entre | |
| # prompts que requerem contexto visual (imagens) e os que são apenas texto. | |
| import logging | |
| from pathlib import Path | |
| from typing import Dict | |
| logger = logging.getLogger(__name__) | |
| class PromptEngine: | |
| """ | |
| O PromptEngine traduz prompts genéricos para o formato específico do | |
| modelo de linguagem alvo. Ele seleciona o template correto com base | |
| na presença de imagens na requisição. | |
| """ | |
| def __init__(self, model_map_name: str): | |
| """ | |
| Inicializa o PromptEngine carregando os templates específicos do modelo. | |
| Args: | |
| model_map_name (str): O nome do diretório do mapa do modelo em | |
| 'aduc_framework/prompts/model_maps/'. | |
| """ | |
| self.model_map_name = model_map_name | |
| # Carrega os dois templates essenciais: um para prompts com imagens | |
| # e outro para prompts que contêm apenas texto. | |
| self.template_with_image = self._load_model_template(model_map_name, "image_template.txt") | |
| self.template_text_only = self._load_model_template(model_map_name, "text_template.txt") | |
| logger.info(f"PromptEngine inicializado com o mapa de modelo '{model_map_name}'.") | |
| def _load_model_template(self, map_name: str, template_file: str) -> str: | |
| """ | |
| Carrega um arquivo de template de um mapa de modelo específico. | |
| """ | |
| map_path = Path(__file__).resolve().parent.parent / "prompts" / "model_maps" / map_name / template_file | |
| if not map_path.is_file(): | |
| # Este é um erro crítico de configuração, então levantamos uma exceção clara. | |
| raise FileNotFoundError(f"Template de modelo '{template_file}' não encontrado no mapa '{map_name}' em: {map_path}") | |
| with open(map_path, 'r', encoding='utf-8') as f: | |
| return f.read() | |
| def translate(self, generic_prompt_content: str, has_image: bool) -> str: | |
| """ | |
| Envolve o conteúdo do prompt genérico com o template específico do modelo, | |
| escolhendo o template correto com base na presença de uma imagem. | |
| Args: | |
| generic_prompt_content (str): O conteúdo do prompt agnóstico gerado pelo Composer. | |
| has_image (bool): Sinaliza se a tarefa atual inclui um contexto visual. | |
| Returns: | |
| str: O prompt final, formatado e pronto para ser enviado ao LLM. | |
| """ | |
| logger.debug(f"--- PROMPT ENGINE: INICIANDO TRADUÇÃO (Imagem: {has_image}) ---") | |
| logger.debug(f"PROMPT GENÉRICO RECEBIDO:\n---\n{generic_prompt_content[:500]}...\n---") | |
| # Seleciona o "mapa" correto com base no contexto | |
| if has_image: | |
| template = self.template_with_image | |
| logger.debug("Usando o template de modelo com imagem.") | |
| else: | |
| template = self.template_text_only | |
| logger.debug("Usando o template de modelo apenas de texto.") | |
| try: | |
| # Insere o conteúdo genérico dentro do template específico do modelo | |
| final_prompt = template.format(generic_prompt_content=generic_prompt_content) | |
| logger.debug(f"PROMPT FINAL (TRADUZIDO) GERADO:\n---\n{final_prompt}\n---") | |
| logger.debug("--- PROMPT ENGINE: TRADUÇÃO CONCLUÍDA ---") | |
| return final_prompt | |
| except KeyError as e: | |
| logger.error(f"PROMPT ENGINE: Erro de chave durante a tradução! Chave não encontrada: {e}", exc_info=True) | |
| logger.error("Verifique se o template do modelo contém apenas o placeholder '{generic_prompt_content}'.") | |
| raise e | |
| # --- Instância Singleton --- | |
| # A seleção do mapa de modelo é feita aqui. No futuro, isso poderia ser | |
| # lido do arquivo de configuração `config.yaml` para maior flexibilidade. | |
| prompt_engine_singleton = PromptEngine(model_map_name="llama_3_2_vision") |