File size: 3,056 Bytes
e6027de
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
##PARA.AI/core/segmenter.py
"""
Segmenter V13.6 - Fase 2.2 (Regex, sem LLM)
Segmenta inteiro_teor em 3 blocos: RELATORIO, FUNDAMENTACAO, DECISAO
"""
import re
from typing import Dict, Optional, Tuple

class Segmenter:
    """Segmenta texto em blocos lógicos usando regex"""

    # Gatilhos para RELATÓRIO (início)
    TRIGGERS_RELATORIO = [
        r"RELATÓRIO",
        r"Trata-se de",
        r"Cuida a espécie"
    ]

    # Gatilhos para FUNDAMENTAÇÃO (meio)
    TRIGGERS_FUNDAMENTACAO = [
        r"É o (relatório|síntese|resumo|histórico)",
        r"_nPresentes",
        r"_nDecido",
        r"_nVOTO",
        r"_nFUNDAMENTAÇÃO"
    ]

    # Gatilhos para DECISÃO (fim)
    TRIGGERS_DECISAO = [
        r"Diante do exposto",
        r"DECISÃO",
        r"DISPOSITIVO",
        r"Por todo o exposto"
    ]

    def segment(self, inteiro_teor: str) -> Dict[str, Optional[str]]:
        """
        Segmenta inteiro_teor em blocos
        RETORNA: {"bloco_1": str, "bloco_2": str, "bloco_3": str}
        """
        if not inteiro_teor:
            return {"bloco_1": None, "bloco_2": None, "bloco_3": None}

        # Normalizar quebras de linha
        text = inteiro_teor.replace("\r\n", "\n").replace("\r", "\n")

        # Tentar encontrar limites
        pos_inicio_fund = self._find_fundamentacao_start(text)
        pos_inicio_decisao = self._find_decisao_start(text)

        # Se não encontrou, usar divisão proporcional
        if pos_inicio_fund is None and pos_inicio_decisao is None:
            return self._split_proportional(text)

        # Dividir pelos limites encontrados
        bloco_1 = text[:pos_inicio_fund] if pos_inicio_fund else text[:int(len(text)*0.3)]
        bloco_2 = text[pos_inicio_fund:pos_inicio_decisao] if pos_inicio_decisao else text[pos_inicio_fund:]
        bloco_3 = text[pos_inicio_decisao:] if pos_inicio_decisao else text[int(len(text)*0.7):]

        return {
            "bloco_1": bloco_1.strip(),
            "bloco_2": bloco_2.strip(),
            "bloco_3": bloco_3.strip()
        }

    def _find_fundamentacao_start(self, text: str) -> Optional[int]:
        """Encontra início da fundamentação"""
        for trigger in self.TRIGGERS_FUNDAMENTACAO:
            match = re.search(trigger, text, re.IGNORECASE)
            if match:
                return match.start()
        return None

    def _find_decisao_start(self, text: str) -> Optional[int]:
        """Encontra início da decisão"""
        for trigger in self.TRIGGERS_DECISAO:
            match = re.search(trigger, text, re.IGNORECASE)
            if match:
                return match.start()
        return None

    def _split_proportional(self, text: str) -> Dict[str, str]:
        """Divisão proporcional quando não encontra gatilhos"""
        length = len(text)
        pos_1 = int(length * 0.3)
        pos_2 = int(length * 0.7)

        return {
            "bloco_1": text[:pos_1].strip(),
            "bloco_2": text[pos_1:pos_2].strip(),
            "bloco_3": text[pos_2:].strip()
        }