Spaces:
Runtime error
Runtime error
| ##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() | |
| } | |