| """
|
| CAMADA L6 — Resposta Final em Texto Fluido
|
| ==========================================
|
| Transforma o output estruturado das camadas L1–L5 em um texto contínuo,
|
| claro e preciso, com tom profissional e acessível.
|
|
|
| Fluxo de processamento:
|
| Motor de Raciocínio → Output Estruturado → Síntese → Resposta Final
|
| """
|
|
|
| from __future__ import annotations
|
| from dataclasses import dataclass, field
|
| from typing import Any, Dict, List, Optional
|
| from l4_synthesis import SynthesisResult
|
| from layer_titles import LAYER_TITLES
|
|
|
| try:
|
| from l5_generation import generate_with_groq, generate_with_custom_lm
|
| except Exception:
|
| generate_with_groq = None
|
| generate_with_custom_lm = None
|
|
|
|
|
| @dataclass
|
| class EpistemicContext:
|
| """Contexto epistemológico agregado para L6."""
|
| proposition_states: List[Dict[str, Any]] = field(default_factory=list)
|
| many_valued_routes: List[Dict[str, Any]] = field(default_factory=list)
|
| bert_classifications: List[Dict[str, Any]] = field(default_factory=list)
|
| application_context: str = ""
|
|
|
|
|
| class FinalResponseEngine:
|
| """Gera a resposta final em texto fluido a partir da síntese das camadas anteriores."""
|
|
|
| def finalize_response(
|
| self,
|
| prompt: str,
|
| synthesis_result: SynthesisResult,
|
| epistemic_context: Optional[EpistemicContext] = None,
|
| generated_text: str = "",
|
| concepts_summary: str = "",
|
| top_judgments: str = "",
|
| agent_context: str = "",
|
| ) -> str:
|
| """Produz a resposta final única e contínua seguindo regras de redação clara."""
|
| main_text = self._normalize_text(generated_text or synthesis_result.response or "")
|
| if not main_text:
|
| return "Não há informação suficiente para formular uma resposta final."
|
|
|
| intro = self._build_intro(synthesis_result)
|
| conclusion = self._build_conclusion(synthesis_result)
|
| context_note = self._build_context_note(concepts_summary, top_judgments, agent_context, epistemic_context)
|
|
|
| if intro:
|
| if main_text.lower().startswith(intro.lower()):
|
| final = main_text
|
| else:
|
| final = f"{intro} {main_text}"
|
| else:
|
| final = main_text
|
|
|
| if conclusion:
|
| final = f"{final} {conclusion}"
|
|
|
| if context_note:
|
| final = f"{final} {context_note}"
|
|
|
| return self._ensure_single_paragraph(final)
|
|
|
| def _build_context_note(
|
| self,
|
| concepts_summary: str,
|
| top_judgments: str,
|
| agent_context: str,
|
| epistemic_context: Optional[EpistemicContext] = None,
|
| ) -> str:
|
| note_parts = []
|
| if concepts_summary:
|
| note_parts.append("o raciocínio integrou conceitos extraídos e evidências relevantes")
|
| if top_judgments:
|
| note_parts.append("os juízos kantianos foram usados para priorizar hipóteses")
|
| if agent_context:
|
| note_parts.append("informações de busca externas também foram consideradas")
|
| if epistemic_context is not None:
|
| if epistemic_context.application_context:
|
| note_parts.append("o contexto aplicacional do LogicLMSolver também foi considerado")
|
| if epistemic_context.many_valued_routes:
|
| note_parts.append("as rotas paraconsistentes do ManyValuedRouter foram analisadas")
|
| if epistemic_context.bert_classifications:
|
| note_parts.append("classificações BERT (T/I/F) das principais hipóteses influenciaram a formulação")
|
| if not note_parts:
|
| return ""
|
| return "Essa resposta reflete o processamento integrado das camadas anteriores, com atenção a evidências e juízos relevantes."
|
|
|
|
|
|
|
|
|
|
|
| def _build_intro(self, synthesis_result: SynthesisResult) -> str:
|
| if synthesis_result.truth_value >= 0.85:
|
| return "Com base no motor de raciocínio L1–L5, a melhor conclusão indica"
|
| if synthesis_result.truth_value >= 0.65:
|
| return "A partir da síntese das camadas L1–L5, o cenário mais sólido sugere"
|
| if synthesis_result.truth_value >= 0.45:
|
| return "Com certa cautela, a análise das camadas L1–L5 aponta"
|
| return "A análise das camadas L1–L5 indica"
|
|
|
| def _build_conclusion(self, synthesis_result: SynthesisResult) -> str:
|
| if synthesis_result.state in {"Indeterminado", "N"}:
|
| return (
|
| "Esta questão tem uma dimensão genuinamente indeterminada — não por falta de rigor, "
|
| "mas porque a evidência empírica ainda não existe. Isso é diferente de 'não sabemos' "
|
| "— é 'não há dados para saber'."
|
| )
|
| if synthesis_result.state == "Inconsistente_local" or synthesis_result.contradiction > 0.25:
|
| return "Essa conclusão é apresentada como a melhor interpretação disponível, embora exista uma contradição local que recomenda prudência."
|
| if synthesis_result.truth_value < 0.65:
|
| return "Dado o grau de incerteza, vale considerar essa resposta como provisória até que evidências adicionais sejam avaliadas."
|
| return ""
|
|
|
| def _normalize_text(self, text: str) -> str:
|
| return " ".join(text.split()).strip()
|
|
|
| def _ensure_single_paragraph(self, text: str) -> str:
|
| normalized = text.replace("\n", " ").replace(" ", " ")
|
| normalized = " ".join(normalized.split())
|
| return normalized.strip()
|
|
|
| def rewrite_response(
|
| self,
|
| prompt: str,
|
| synthesis_result: SynthesisResult,
|
| epistemic_context: Optional[EpistemicContext] = None,
|
| generated_text: str = "",
|
| concepts_summary: str = "",
|
| top_judgments: str = "",
|
| agent_context: str = "",
|
| provider: str = "template",
|
| groq_model: str = "mixtral-8x7b-32768",
|
| custom_lm_path: str = "",
|
| ) -> str:
|
| """Refina a resposta final com um segundo prompt no estilo de um agente escritor."""
|
| draft = self.finalize_response(
|
| prompt=prompt,
|
| synthesis_result=synthesis_result,
|
| epistemic_context=epistemic_context,
|
| generated_text=generated_text,
|
| concepts_summary=concepts_summary,
|
| top_judgments=top_judgments,
|
| agent_context=agent_context,
|
| )
|
| writer_prompt = self._build_writer_prompt(
|
| prompt,
|
| draft,
|
| synthesis_result,
|
| epistemic_context,
|
| concepts_summary,
|
| top_judgments,
|
| agent_context,
|
| )
|
|
|
| if provider == "groq" and generate_with_groq:
|
| text = generate_with_groq(writer_prompt, model=groq_model)
|
| if text:
|
| return self._ensure_single_paragraph(text)
|
|
|
| if provider == "custom_lm" and generate_with_custom_lm and custom_lm_path:
|
| text = generate_with_custom_lm(writer_prompt, custom_lm_path)
|
| if text:
|
| return self._ensure_single_paragraph(text)
|
|
|
| return self._polish_writer_text(draft)
|
|
|
| def _build_writer_prompt(
|
| self,
|
| prompt: str,
|
| draft: str,
|
| synthesis_result: SynthesisResult,
|
| epistemic_context: Optional[EpistemicContext],
|
| concepts_summary: str,
|
| top_judgments: str,
|
| agent_context: str,
|
| ) -> str:
|
| lines = [
|
| "Você é um agente escritor técnico e comunicador.",
|
| "Transforme o raciocínio completo gerado pelas camadas L1 a L6 em um único texto fluido, natural, coeso e fácil de ler.",
|
| "Respeite as proposições e conclusões encontradas entre L1 e L6 e mantenha o rigor lógico e técnico.",
|
| "Comece direto pela resposta principal, depois explique o caminho se necessário.",
|
| "Use linguagem clara, conversacional e precisa e mencione incertezas ou trade-offs de forma elegante quando existirem.",
|
| "Não separe o texto em passos numerados ou listas.",
|
| "Ao se referir às etapas, use os títulos de seção designados abaixo:",
|
| f"L1: {LAYER_TITLES['l1']}",
|
| f"L2: {LAYER_TITLES['l2']}",
|
| f"L3: {LAYER_TITLES['l3']}",
|
| f"L4: {LAYER_TITLES['l4']}",
|
| f"L5: {LAYER_TITLES['l5']}",
|
| f"L6: {LAYER_TITLES['l6']}",
|
| "",
|
| f"Pergunta do usuário: {prompt}",
|
| "",
|
| "Texto preliminar:",
|
| draft,
|
| "",
|
| "Contexto de síntese:",
|
| f"Resposta de síntese L4: {synthesis_result.response}",
|
| f"Valor de verdade: {synthesis_result.truth_value:.2f}",
|
| f"Estado: {synthesis_result.state}",
|
| f"Certeza: {synthesis_result.certainty:+.2f}",
|
| f"Contradição: {synthesis_result.contradiction:+.2f}",
|
| ]
|
| if concepts_summary:
|
| lines.extend(["", f"Conceitos L1: {concepts_summary}"])
|
| if top_judgments:
|
| lines.extend(["", f"Juízos L2: {top_judgments}"])
|
| if agent_context:
|
| lines.extend(["", "Contexto de busca externo:", agent_context])
|
| if epistemic_context is not None:
|
| lines.extend(["", "Detalhes epistemológicos:", self._summarize_epistemic_context(epistemic_context)])
|
| lines.extend([
|
| "",
|
| "Raciocínio completo:",
|
| "O texto deve sintetizar a extração de conceitos, os juízos kantianos, a avaliação paraconsistente, a síntese russelliana e a formulação final.",
|
| ])
|
| return "\n".join(lines)
|
|
|
| def _summarize_epistemic_context(self, epistemic_context: EpistemicContext) -> str:
|
| parts: List[str] = []
|
| if epistemic_context.application_context:
|
| parts.append(f"Contexto de aplicação: {epistemic_context.application_context}")
|
| if epistemic_context.proposition_states:
|
| top_props = epistemic_context.proposition_states[:3]
|
| summary = ", ".join(
|
| f"{item.get('state', 'Desconhecido')} ({item.get('truth_value', 'n/a')})" for item in top_props
|
| )
|
| parts.append(f"Proposições avaliadas: {summary}")
|
| if epistemic_context.many_valued_routes:
|
| parts.append("Rotas paraconsistentes avaliadas.")
|
| if epistemic_context.bert_classifications:
|
| parts.append("Classificações BERT (T/I/F) foram usadas para ajustar prioridades epistemológicas.")
|
| return " ".join(parts)
|
|
|
| def _polish_writer_text(self, draft: str) -> str:
|
| return self._ensure_single_paragraph(draft)
|
|
|