Update app.py
Browse files
app.py
CHANGED
|
@@ -37,17 +37,15 @@ CONFIG = {
|
|
| 37 |
"max_retry_attempts": 3,
|
| 38 |
"retry_delay": 5,
|
| 39 |
"timeout": 180,
|
| 40 |
-
"temperatura": 0.3,
|
| 41 |
"max_tokens": 8192
|
| 42 |
}
|
| 43 |
|
| 44 |
-
# Lower temperature for more deterministic OAB-based generation/correction
|
| 45 |
CONFIG_OAB = {
|
| 46 |
"temperatura": 0.2,
|
| 47 |
"max_tokens": 8192
|
| 48 |
}
|
| 49 |
|
| 50 |
-
|
| 51 |
rate_limiter = RateLimiter(max_calls=30, period=60)
|
| 52 |
|
| 53 |
TIPOS_DE_PETICAO = [
|
|
@@ -89,7 +87,6 @@ DICAS_OAB_MELHORADO = {
|
|
| 89 |
HISTORICO = []
|
| 90 |
CORRECAO_CACHE = {}
|
| 91 |
|
| 92 |
-
# --- Funções de Extração de Texto ---
|
| 93 |
def preprocess_image_for_ocr(img):
|
| 94 |
try:
|
| 95 |
gray = img.convert('L')
|
|
@@ -111,7 +108,7 @@ def extract_text_from_pdf(file_path_or_obj):
|
|
| 111 |
page_text = page.extract_text()
|
| 112 |
if page_text:
|
| 113 |
page_full_text += page_text + "\n"
|
| 114 |
-
text += page_text + "\n"
|
| 115 |
else:
|
| 116 |
logger.warning(f"Página {i+1} sem texto extraível, tentando OCR.")
|
| 117 |
try:
|
|
@@ -120,7 +117,7 @@ def extract_text_from_pdf(file_path_or_obj):
|
|
| 120 |
page_ocr_text = pytesseract.image_to_string(preprocessed_img, lang='por')
|
| 121 |
if page_ocr_text.strip():
|
| 122 |
page_full_text += page_ocr_text + "\n"
|
| 123 |
-
ocr_text += page_ocr_text + "\n"
|
| 124 |
else:
|
| 125 |
logger.warning(f"OCR falhou na página {i+1}.")
|
| 126 |
page_full_text += f"[OCR falhou na página {i+1}]\n"
|
|
@@ -162,7 +159,6 @@ def extract_text_from_pdf(file_path_or_obj):
|
|
| 162 |
logger.error(f"Erro no fallback com PyPDF2: {str(fallback_e)}")
|
| 163 |
return f"❌ Erro crítico ao processar o PDF: {str(e)}"
|
| 164 |
|
| 165 |
-
|
| 166 |
def extract_text_from_docx(file_path_or_obj):
|
| 167 |
try:
|
| 168 |
doc = docx.Document(file_path_or_obj)
|
|
@@ -235,8 +231,6 @@ def process_file(file_obj):
|
|
| 235 |
logger.error(f"Erro geral ao processar o arquivo '{getattr(file_obj, 'name', 'N/A')}': {str(e)}", exc_info=True)
|
| 236 |
return f"❌ Erro inesperado ao processar o arquivo: {str(e)}"
|
| 237 |
|
| 238 |
-
|
| 239 |
-
# --- Funções da API Gemini ---
|
| 240 |
def chamar_api(prompt, use_oab_config=False):
|
| 241 |
config_to_use = CONFIG_OAB if use_oab_config else CONFIG
|
| 242 |
payload = {
|
|
@@ -311,12 +305,6 @@ def chamar_api(prompt, use_oab_config=False):
|
|
| 311 |
|
| 312 |
return "❌ Falha API após todas tentativas."
|
| 313 |
|
| 314 |
-
|
| 315 |
-
# --- Funções de Correção Geral (IA) ---
|
| 316 |
-
# (Inclui as funções restauradas: get_instrucoes_gerais_avaliacao, estruturar_prompt_analise,
|
| 317 |
-
# estruturar_prompt_peticao_corrigida, pos_corrigir_peticao, corrigir_peticao_geral_ia,
|
| 318 |
-
# formatar_correcao, avaliar_criterios_peticao (renomeada para avaliacao_criterios_ia), etc.)
|
| 319 |
-
|
| 320 |
def get_instrucoes_gerais_avaliacao(modo_treinamento=False):
|
| 321 |
base = """
|
| 322 |
**Estrutura da Avaliação (Geral - IA):**
|
|
@@ -394,7 +382,7 @@ def estruturar_prompt_analise_geral(caso, peticao, tipo_peticao, modo_treinament
|
|
| 394 |
- **Pedidos:** Acolhimento preliminares; IMPROCEDÊNCIA TOTAL; Condenação custas/honorários.
|
| 395 |
- Indicação de provas. Fechamento formal.
|
| 396 |
"""
|
| 397 |
-
# Add other
|
| 398 |
|
| 399 |
prompt_especifico += "\n\n**Instruções Finais:** Analise a peça do aluno com base no caso e nos critérios gerais e específicos. Use seu conhecimento jurídico para simular um examinador da OAB. Forneça feedback construtivo e detalhado. Gere a resposta **exclusivamente** no formato solicitado (Análise Geral, Nota, Pontos Positivos, etc.)."
|
| 400 |
return prompt_especifico
|
|
@@ -451,32 +439,32 @@ def pos_corrigir_peticao(peticao_corrigida, tipo_peticao):
|
|
| 451 |
if tipo_peticao in ["Petição Inicial", "Ação de Alimentos Gravídicos"]:
|
| 452 |
if "juntada da guia de custas" not in peticao_corrigida.lower() and "gratuidade de justiça" not in peticao_corrigida.lower():
|
| 453 |
partes = peticao_corrigida.split("Nestes termos pede deferimento")
|
| 454 |
-
prefixo = partes[0] if len(partes) > 1 else peticao_corrigida
|
| 455 |
-
sufixo = "
|
| 456 |
-
peticao_corrigida = prefixo
|
| 457 |
|
| 458 |
if "audiência de conciliação" not in peticao_corrigida.lower() and "audiência de mediação" not in peticao_corrigida.lower():
|
| 459 |
partes = peticao_corrigida.split("Nestes termos pede deferimento")
|
| 460 |
-
prefixo = partes[0] if len(partes) > 1 else peticao_corrigida
|
| 461 |
-
sufixo = "
|
| 462 |
-
peticao_corrigida = prefixo
|
| 463 |
|
| 464 |
linhas = [l.strip() for l in peticao_corrigida.strip().split('\n') if l.strip()]
|
| 465 |
fechamento_padrao = ["\nLocal, data.", "ADVOGADO(A)", "OAB/..."]
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
|
|
|
|
|
|
|
| 471 |
break
|
| 472 |
linhas.pop()
|
| 473 |
|
| 474 |
-
|
| 475 |
-
peticao_corrigida = "\n".join(linhas).strip() + "\n" + "\n".join(fechamento_padrao)
|
| 476 |
|
| 477 |
return peticao_corrigida.strip()
|
| 478 |
|
| 479 |
-
|
| 480 |
def formatar_correcao(texto):
|
| 481 |
texto = texto.replace("### Análise Geral", "## 📝 Análise Geral")
|
| 482 |
texto = texto.replace("### Nota Final", "## ⭐ Nota Final")
|
|
@@ -512,15 +500,6 @@ def formatar_correcao(texto):
|
|
| 512 |
texto_final = re.sub(nota_pattern, f"\\1**{nota}/10**", texto_final, count=1, flags=re.IGNORECASE)
|
| 513 |
return texto_final
|
| 514 |
|
| 515 |
-
def avaliar_criterios_ia(caso, peticao_original, tipo_peticao):
|
| 516 |
-
# This function remains from the previous step, evaluating based on IA criteria
|
| 517 |
-
# Ensure it's called by corrigir_peticao_geral_ia if needed
|
| 518 |
-
logger.info(f"Iniciando avaliação por critérios (IA) para: {tipo_peticao}")
|
| 519 |
-
# ... (rest of the function logic as provided in the previous answer) ...
|
| 520 |
-
# It needs: obter_criterios_avaliacao, estruturar_prompt_avaliacao_criterios, chamar_api
|
| 521 |
-
# parse the JSON response and format to Markdown.
|
| 522 |
-
return "Avaliação por Critérios (IA) - Implementação Pendente ou Removida" # Placeholder
|
| 523 |
-
|
| 524 |
def corrigir_peticao_geral_ia(caso, tipo_peticao, peticao_texto=None, peticao_arquivo=None, modo_treinamento=False):
|
| 525 |
logger.info(f"Iniciando correção GERAL (IA) para tipo: {tipo_peticao}")
|
| 526 |
start_time = time.time()
|
|
@@ -537,7 +516,7 @@ def corrigir_peticao_geral_ia(caso, tipo_peticao, peticao_texto=None, peticao_ar
|
|
| 537 |
peticao_conteudo = peticao_texto
|
| 538 |
else: return "⚠️ Forneça a petição.", "", "", "", "", "", ""
|
| 539 |
|
| 540 |
-
troll_triggers = [ "escreva a petição", "faça a petição"]
|
| 541 |
if any(trigger in peticao_conteudo.lower() for trigger in troll_triggers):
|
| 542 |
return random.choice(["Nope! 😉", "Faça você e eu corrijo!"]), "", "", "", "", "", ""
|
| 543 |
|
|
@@ -565,8 +544,7 @@ def corrigir_peticao_geral_ia(caso, tipo_peticao, peticao_texto=None, peticao_ar
|
|
| 565 |
else:
|
| 566 |
peticao_corrigida_final = pos_corrigir_peticao(peticao_corrigida_bruta, tipo_peticao)
|
| 567 |
|
| 568 |
-
|
| 569 |
-
avaliacao_criterios_md = "" # Set to empty for now
|
| 570 |
|
| 571 |
visualizacao_detalhada_html, resumo_diff, criticas_diff = calcular_diff_interno(peticao_conteudo, peticao_corrigida_final)
|
| 572 |
|
|
@@ -583,11 +561,7 @@ def corrigir_peticao_geral_ia(caso, tipo_peticao, peticao_texto=None, peticao_ar
|
|
| 583 |
return ( correcao_completa_formatada, peticao_conteudo, peticao_corrigida_final,
|
| 584 |
resumo_diff, criticas_diff, avaliacao_criterios_md, visualizacao_detalhada_html )
|
| 585 |
|
| 586 |
-
|
| 587 |
-
|
| 588 |
# --- Funções de Correção Padrão OAB ---
|
| 589 |
-
# (Inclui as funções: parse_oab_pdf, estruturar_prompt_geracao_modelo_oab,
|
| 590 |
-
# gerar_peticao_modelo_oab, estruturar_prompt_correcao_pela_oab, corrigir_pela_oab)
|
| 591 |
def parse_oab_pdf(file_obj):
|
| 592 |
if file_obj is None: return None, None, None, "⚠️ Nenhum PDF OAB."
|
| 593 |
try:
|
|
@@ -602,13 +576,11 @@ def parse_oab_pdf(file_obj):
|
|
| 602 |
line_strip = line.strip()
|
| 603 |
line_lower = line_strip.lower()
|
| 604 |
|
| 605 |
-
# Section Start Markers (allow variations)
|
| 606 |
if line_strip.startswith("Enunciado"): current_section = "enunciado"; continue
|
| 607 |
if line_strip.startswith("Gabarito comentado"): current_section = "gabarito"; continue
|
| 608 |
if line_strip.startswith("Distribuição dos Pontos"): current_section = "distribuicao"; continue
|
| 609 |
-
# Break Markers (end of relevant sections)
|
| 610 |
if line_strip.startswith("PADRÃO DE RESPOSTA – QUESTÃO"): current_section = None; break
|
| 611 |
-
if line_strip.startswith("Padrão de Resposta"): continue
|
| 612 |
|
| 613 |
if current_section == "enunciado": enunciado += line + "\n"
|
| 614 |
elif current_section == "gabarito": gabarito += line + "\n"
|
|
@@ -618,10 +590,9 @@ def parse_oab_pdf(file_obj):
|
|
| 618 |
gabarito = gabarito.strip()
|
| 619 |
distribuicao = distribuicao.strip()
|
| 620 |
|
| 621 |
-
# Basic check if sections were captured
|
| 622 |
if not enunciado or not gabarito or not distribuicao:
|
| 623 |
logger.warning(f"Parse OAB PDF falhou. E:{bool(enunciado)}, G:{bool(gabarito)}, D:{bool(distribuicao)}")
|
| 624 |
-
return None, None, None, f"⚠️ Falha separar seções. Verifique o texto completo:\n\n{full_text[:500]}..."
|
| 625 |
|
| 626 |
logger.info("PDF OAB parseado.")
|
| 627 |
return enunciado, gabarito, distribuicao, "✅ PDF OAB carregado e seções extraídas."
|
|
@@ -629,7 +600,6 @@ def parse_oab_pdf(file_obj):
|
|
| 629 |
logger.error(f"Erro parsear PDF OAB: {str(e)}", exc_info=True)
|
| 630 |
return None, None, None, f"❌ Erro processar PDF OAB: {str(e)}"
|
| 631 |
|
| 632 |
-
|
| 633 |
def estruturar_prompt_geracao_modelo_oab(enunciado, gabarito, distribuicao):
|
| 634 |
prompt = f"""
|
| 635 |
**Tarefa:** Elabore a peça processual completa e adequada para o **Enunciado**, seguindo **estritamente** as diretrizes do **Gabarito Comentado** e os critérios da **Distribuição dos Pontos**. Crie uma peça modelo perfeita para este caso OAB.
|
|
@@ -666,7 +636,7 @@ def gerar_peticao_modelo_oab(enunciado, gabarito, distribuicao):
|
|
| 666 |
|
| 667 |
logger.info("Gerando peça modelo OAB...")
|
| 668 |
prompt = estruturar_prompt_geracao_modelo_oab(enunciado, gabarito, distribuicao)
|
| 669 |
-
peticao_modelo = chamar_api(prompt, use_oab_config=True)
|
| 670 |
|
| 671 |
if peticao_modelo.startswith("❌") or peticao_modelo.startswith("⏱️"):
|
| 672 |
logger.error(f"Erro API gerar modelo OAB: {peticao_modelo}")
|
|
@@ -704,7 +674,7 @@ def estruturar_prompt_correcao_pela_oab(peticao_usuario, enunciado, gabarito, di
|
|
| 704 |
1. **Avaliação Pontual:** Para **cada item** na **Distribuição**, verifique se foi abordado pelo Usuário conforme o Gabarito. Atribua a pontuação correspondente.
|
| 705 |
2. **Justificativa:** Justifique brevemente a pontuação de cada item.
|
| 706 |
3. **Feedback:** Aponte erros/omissões do Usuário vs Gabarito/Distribuição.
|
| 707 |
-
4. **Peça Corrigida (Opcional
|
| 708 |
5. **Output Markdown:**
|
| 709 |
|
| 710 |
```markdown
|
|
@@ -738,7 +708,7 @@ def corrigir_pela_oab(peticao_usuario, enunciado, gabarito, distribuicao):
|
|
| 738 |
|
| 739 |
logger.info("Corrigindo pela OAB...")
|
| 740 |
prompt = estruturar_prompt_correcao_pela_oab(peticao_usuario, enunciado, gabarito, distribuicao)
|
| 741 |
-
correcao_oab = chamar_api(prompt, use_oab_config=True)
|
| 742 |
|
| 743 |
if correcao_oab.startswith("❌") or correcao_oab.startswith("⏱️"):
|
| 744 |
logger.error(f"Erro API corrigir OAB: {correcao_oab}")
|
|
@@ -747,9 +717,7 @@ def corrigir_pela_oab(peticao_usuario, enunciado, gabarito, distribuicao):
|
|
| 747 |
logger.info("Correção/Avaliação OAB concluída.")
|
| 748 |
return correcao_oab
|
| 749 |
|
| 750 |
-
|
| 751 |
-
# --- Funções Auxiliares (Diff, Histórico, Salvar/Carregar, Gerar Caso Fictício) ---
|
| 752 |
-
# (Keep these largely as they were in the previous correct version)
|
| 753 |
def calcular_diff_interno(texto_original, texto_corrigido):
|
| 754 |
if not texto_original or not texto_corrigido or texto_corrigido.startswith("⚠️") or texto_corrigido.startswith("❌"): return "","",""
|
| 755 |
orig_lines = texto_original.splitlines(); corr_lines = texto_corrigido.splitlines()
|
|
@@ -774,7 +742,6 @@ def calcular_diff_interno(texto_original, texto_corrigido):
|
|
| 774 |
|
| 775 |
def calcular_progresso():
|
| 776 |
if not HISTORICO: return "📊 Progresso vazio."
|
| 777 |
-
# Simplified progress focusing on General IA for now
|
| 778 |
notas_geral = []
|
| 779 |
tipos_geral = set()
|
| 780 |
count_geral = 0
|
|
@@ -851,15 +818,71 @@ def gerar_caso_ficticio(tipo_peticao="Petição Inicial"):
|
|
| 851 |
logger.info("Caso gerado.")
|
| 852 |
return caso
|
| 853 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 854 |
|
| 855 |
-
# --- Interface Gradio
|
| 856 |
def interface_gradio():
|
| 857 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="orange")) as demo:
|
| 858 |
gr.Markdown("# ⚖️ Corretor Jurídico OAB Master ⚖️")
|
| 859 |
gr.Markdown("Use a **Correção Geral (IA)** para feedback amplo ou a **Correção Baseada no Padrão OAB** para avaliação específica.")
|
| 860 |
|
| 861 |
with gr.Tabs() as main_tabs:
|
| 862 |
-
# --- ABA: Correção Geral (IA) ---
|
| 863 |
with gr.TabItem("🤖 Correção Geral (IA)", id=0):
|
| 864 |
with gr.Row():
|
| 865 |
with gr.Column(scale=1):
|
|
@@ -905,7 +928,6 @@ def interface_gradio():
|
|
| 905 |
processing_message_geral = gr.Markdown("", visible=False)
|
| 906 |
with gr.Tabs():
|
| 907 |
with gr.TabItem("📊 Análise IA"): resultado_analise_output_geral = gr.Markdown()
|
| 908 |
-
# with gr.TabItem("💎 Critérios IA"): avaliacao_criterios_output_geral = gr.Markdown() # Optional tab
|
| 909 |
with gr.TabItem("✨ Correção IA"): resultado_peticao_corrigida_output_geral = gr.Textbox(lines=15, show_copy_button=True)
|
| 910 |
with gr.TabItem("⚖️ Diff"):
|
| 911 |
with gr.Row():
|
|
@@ -913,7 +935,6 @@ def interface_gradio():
|
|
| 913 |
with gr.Column(scale=3): visualizacao_detalhada_output_geral = gr.HTML()
|
| 914 |
criticas_output_geral = gr.Markdown()
|
| 915 |
|
| 916 |
-
# --- ABA: Correção Padrão OAB ---
|
| 917 |
with gr.TabItem("📄 Correção Padrão OAB", id=1):
|
| 918 |
gr.Markdown("Forneça o material oficial (PDF ou texto) e sua peça.")
|
| 919 |
with gr.Row():
|
|
@@ -941,13 +962,11 @@ def interface_gradio():
|
|
| 941 |
|
| 942 |
clear_btn = gr.Button("🗑️ Limpar Tudo")
|
| 943 |
|
| 944 |
-
# --- Lógica Eventos ---
|
| 945 |
caso_btn_geral.click(gerar_caso_ficticio, [tipo_peticao_input_geral], [caso_input_geral])
|
| 946 |
peticao_texto_input_geral.change(fornecer_dica_contextual, [peticao_texto_input_geral, tipo_peticao_input_geral], dica_contextual_output_geral)
|
| 947 |
tipo_peticao_input_geral.change(fornecer_dica_contextual, [peticao_texto_input_geral, tipo_peticao_input_geral], dica_contextual_output_geral)
|
| 948 |
peticao_arquivo_input_geral.change(process_file, [peticao_arquivo_input_geral], arquivo_preview_output_geral)
|
| 949 |
|
| 950 |
-
# Correção Geral IA (Texto)
|
| 951 |
btn_corrigir_geral.click( lambda: gr.update(value="⏳ Processando IA...", visible=True), None, processing_message_geral).then(
|
| 952 |
corrigir_peticao_geral_ia,
|
| 953 |
[caso_input_geral, tipo_peticao_input_geral, peticao_texto_input_geral, gr.State(None), modo_treinamento_geral],
|
|
@@ -955,7 +974,6 @@ def interface_gradio():
|
|
| 955 |
resumo_alteracoes_output_geral, criticas_output_geral, gr.Markdown(visible=False), visualizacao_detalhada_output_geral]
|
| 956 |
).then( lambda: gr.update(visible=False), None, processing_message_geral )
|
| 957 |
|
| 958 |
-
# Correção Geral IA (Arquivo)
|
| 959 |
btn_corrigir_arquivo_geral.click( lambda: gr.update(value="⏳ Processando IA...", visible=True), None, processing_message_geral).then(
|
| 960 |
corrigir_peticao_geral_ia,
|
| 961 |
[caso_input_geral, tipo_peticao_input_geral, gr.State(None), peticao_arquivo_input_geral, modo_treinamento_geral],
|
|
@@ -963,7 +981,6 @@ def interface_gradio():
|
|
| 963 |
resumo_alteracoes_output_geral, criticas_output_geral, gr.Markdown(visible=False), visualizacao_detalhada_output_geral]
|
| 964 |
).then( lambda: gr.update(visible=False), None, processing_message_geral )
|
| 965 |
|
| 966 |
-
# Salvar/Carregar Geral
|
| 967 |
salvar_btn_geral.click( lambda: gr.update(value="⏳ Salvando...", visible=True), None, processing_message_geral).then(
|
| 968 |
salvar_progresso, [caso_input_geral, peticao_texto_input_geral, tipo_peticao_input_geral],
|
| 969 |
[gr.Textbox(visible=False), config_status_geral, progresso_download_file_geral]
|
|
@@ -974,7 +991,6 @@ def interface_gradio():
|
|
| 974 |
[tipo_peticao_input_geral, caso_input_geral, peticao_texto_input_geral, config_status_geral]
|
| 975 |
).then( lambda: gr.update(visible=False), None, processing_message_geral )
|
| 976 |
|
| 977 |
-
# Padrão OAB
|
| 978 |
oab_pdf_input.change(parse_oab_pdf, [oab_pdf_input], [oab_enunciado_input, oab_gabarito_input, oab_distribuicao_input, parse_status_output])
|
| 979 |
btn_gerar_modelo_oab.click( lambda: gr.update(value="⏳ Gerando Modelo...", visible=True), None, processing_message_oab).then(
|
| 980 |
gerar_peticao_modelo_oab, [oab_enunciado_input, oab_gabarito_input, oab_distribuicao_input], [resultado_modelo_oab_output]
|
|
@@ -983,10 +999,9 @@ def interface_gradio():
|
|
| 983 |
corrigir_pela_oab, [peticao_usuario_oab_input, oab_enunciado_input, oab_gabarito_input, oab_distribuicao_input], [resultado_correcao_oab_output]
|
| 984 |
).then( lambda: gr.update(visible=False), None, processing_message_oab )
|
| 985 |
|
| 986 |
-
|
| 987 |
-
|
| 988 |
-
|
| 989 |
-
None, "", None, None, None, "", "", "", "" # OAB Tab
|
| 990 |
], inputs=None, outputs=[
|
| 991 |
tipo_peticao_input_geral, modo_treinamento_geral, caso_input_geral, peticao_texto_input_geral, peticao_arquivo_input_geral,
|
| 992 |
arquivo_preview_output_geral, processing_message_geral, resultado_analise_output_geral,
|
|
@@ -999,7 +1014,6 @@ def interface_gradio():
|
|
| 999 |
|
| 1000 |
return demo
|
| 1001 |
|
| 1002 |
-
# --- Execução ---
|
| 1003 |
if __name__ == "__main__":
|
| 1004 |
app = interface_gradio()
|
| 1005 |
app.launch()
|
|
|
|
| 37 |
"max_retry_attempts": 3,
|
| 38 |
"retry_delay": 5,
|
| 39 |
"timeout": 180,
|
| 40 |
+
"temperatura": 0.3,
|
| 41 |
"max_tokens": 8192
|
| 42 |
}
|
| 43 |
|
|
|
|
| 44 |
CONFIG_OAB = {
|
| 45 |
"temperatura": 0.2,
|
| 46 |
"max_tokens": 8192
|
| 47 |
}
|
| 48 |
|
|
|
|
| 49 |
rate_limiter = RateLimiter(max_calls=30, period=60)
|
| 50 |
|
| 51 |
TIPOS_DE_PETICAO = [
|
|
|
|
| 87 |
HISTORICO = []
|
| 88 |
CORRECAO_CACHE = {}
|
| 89 |
|
|
|
|
| 90 |
def preprocess_image_for_ocr(img):
|
| 91 |
try:
|
| 92 |
gray = img.convert('L')
|
|
|
|
| 108 |
page_text = page.extract_text()
|
| 109 |
if page_text:
|
| 110 |
page_full_text += page_text + "\n"
|
| 111 |
+
text += page_text + "\n"
|
| 112 |
else:
|
| 113 |
logger.warning(f"Página {i+1} sem texto extraível, tentando OCR.")
|
| 114 |
try:
|
|
|
|
| 117 |
page_ocr_text = pytesseract.image_to_string(preprocessed_img, lang='por')
|
| 118 |
if page_ocr_text.strip():
|
| 119 |
page_full_text += page_ocr_text + "\n"
|
| 120 |
+
ocr_text += page_ocr_text + "\n"
|
| 121 |
else:
|
| 122 |
logger.warning(f"OCR falhou na página {i+1}.")
|
| 123 |
page_full_text += f"[OCR falhou na página {i+1}]\n"
|
|
|
|
| 159 |
logger.error(f"Erro no fallback com PyPDF2: {str(fallback_e)}")
|
| 160 |
return f"❌ Erro crítico ao processar o PDF: {str(e)}"
|
| 161 |
|
|
|
|
| 162 |
def extract_text_from_docx(file_path_or_obj):
|
| 163 |
try:
|
| 164 |
doc = docx.Document(file_path_or_obj)
|
|
|
|
| 231 |
logger.error(f"Erro geral ao processar o arquivo '{getattr(file_obj, 'name', 'N/A')}': {str(e)}", exc_info=True)
|
| 232 |
return f"❌ Erro inesperado ao processar o arquivo: {str(e)}"
|
| 233 |
|
|
|
|
|
|
|
| 234 |
def chamar_api(prompt, use_oab_config=False):
|
| 235 |
config_to_use = CONFIG_OAB if use_oab_config else CONFIG
|
| 236 |
payload = {
|
|
|
|
| 305 |
|
| 306 |
return "❌ Falha API após todas tentativas."
|
| 307 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
def get_instrucoes_gerais_avaliacao(modo_treinamento=False):
|
| 309 |
base = """
|
| 310 |
**Estrutura da Avaliação (Geral - IA):**
|
|
|
|
| 382 |
- **Pedidos:** Acolhimento preliminares; IMPROCEDÊNCIA TOTAL; Condenação custas/honorários.
|
| 383 |
- Indicação de provas. Fechamento formal.
|
| 384 |
"""
|
| 385 |
+
# Add other types...
|
| 386 |
|
| 387 |
prompt_especifico += "\n\n**Instruções Finais:** Analise a peça do aluno com base no caso e nos critérios gerais e específicos. Use seu conhecimento jurídico para simular um examinador da OAB. Forneça feedback construtivo e detalhado. Gere a resposta **exclusivamente** no formato solicitado (Análise Geral, Nota, Pontos Positivos, etc.)."
|
| 388 |
return prompt_especifico
|
|
|
|
| 439 |
if tipo_peticao in ["Petição Inicial", "Ação de Alimentos Gravídicos"]:
|
| 440 |
if "juntada da guia de custas" not in peticao_corrigida.lower() and "gratuidade de justiça" not in peticao_corrigida.lower():
|
| 441 |
partes = peticao_corrigida.split("Nestes termos pede deferimento")
|
| 442 |
+
prefixo = partes[0].strip() if len(partes) > 1 else peticao_corrigida.strip()
|
| 443 |
+
sufixo = "\nNestes termos pede deferimento" + partes[1] if len(partes) > 1 else ""
|
| 444 |
+
peticao_corrigida = prefixo + "\nRequer, ainda, a juntada da guia de custas devidamente recolhida." + sufixo
|
| 445 |
|
| 446 |
if "audiência de conciliação" not in peticao_corrigida.lower() and "audiência de mediação" not in peticao_corrigida.lower():
|
| 447 |
partes = peticao_corrigida.split("Nestes termos pede deferimento")
|
| 448 |
+
prefixo = partes[0].strip() if len(partes) > 1 else peticao_corrigida.strip()
|
| 449 |
+
sufixo = "\nNestes termos pede deferimento" + partes[1] if len(partes) > 1 else ""
|
| 450 |
+
peticao_corrigida = prefixo + "\nOpta o Autor pela realização da audiência de conciliação ou mediação (Art. 319, VII, CPC)." + sufixo
|
| 451 |
|
| 452 |
linhas = [l.strip() for l in peticao_corrigida.strip().split('\n') if l.strip()]
|
| 453 |
fechamento_padrao = ["\nLocal, data.", "ADVOGADO(A)", "OAB/..."]
|
| 454 |
+
|
| 455 |
+
# Remove potential multiple closing lines before adding the standard one
|
| 456 |
+
while linhas and any(term.lower() in linhas[-1].lower() for term in ["advogado", "oab", "local", "data", "pede deferimento", "termos em que"]):
|
| 457 |
+
# More robust check to avoid removing essential content like the final request
|
| 458 |
+
last_line_lower = linhas[-1].lower()
|
| 459 |
+
is_closing_line = any(std_close.strip().lower() in last_line_lower for std_close in fechamento_padrao) or "pede deferimento" in last_line_lower or "termos em que" in last_line_lower
|
| 460 |
+
if not is_closing_line and len(linhas[-1]) > 30: # Heuristic: unlikely to be just closing
|
| 461 |
break
|
| 462 |
linhas.pop()
|
| 463 |
|
| 464 |
+
peticao_corrigida = "\n".join(linhas).strip() + "".join(fechamento_padrao) # Join directly
|
|
|
|
| 465 |
|
| 466 |
return peticao_corrigida.strip()
|
| 467 |
|
|
|
|
| 468 |
def formatar_correcao(texto):
|
| 469 |
texto = texto.replace("### Análise Geral", "## 📝 Análise Geral")
|
| 470 |
texto = texto.replace("### Nota Final", "## ⭐ Nota Final")
|
|
|
|
| 500 |
texto_final = re.sub(nota_pattern, f"\\1**{nota}/10**", texto_final, count=1, flags=re.IGNORECASE)
|
| 501 |
return texto_final
|
| 502 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 503 |
def corrigir_peticao_geral_ia(caso, tipo_peticao, peticao_texto=None, peticao_arquivo=None, modo_treinamento=False):
|
| 504 |
logger.info(f"Iniciando correção GERAL (IA) para tipo: {tipo_peticao}")
|
| 505 |
start_time = time.time()
|
|
|
|
| 516 |
peticao_conteudo = peticao_texto
|
| 517 |
else: return "⚠️ Forneça a petição.", "", "", "", "", "", ""
|
| 518 |
|
| 519 |
+
troll_triggers = [ "escreva a petição", "faça a petição"]
|
| 520 |
if any(trigger in peticao_conteudo.lower() for trigger in troll_triggers):
|
| 521 |
return random.choice(["Nope! 😉", "Faça você e eu corrijo!"]), "", "", "", "", "", ""
|
| 522 |
|
|
|
|
| 544 |
else:
|
| 545 |
peticao_corrigida_final = pos_corrigir_peticao(peticao_corrigida_bruta, tipo_peticao)
|
| 546 |
|
| 547 |
+
avaliacao_criterios_md = ""
|
|
|
|
| 548 |
|
| 549 |
visualizacao_detalhada_html, resumo_diff, criticas_diff = calcular_diff_interno(peticao_conteudo, peticao_corrigida_final)
|
| 550 |
|
|
|
|
| 561 |
return ( correcao_completa_formatada, peticao_conteudo, peticao_corrigida_final,
|
| 562 |
resumo_diff, criticas_diff, avaliacao_criterios_md, visualizacao_detalhada_html )
|
| 563 |
|
|
|
|
|
|
|
| 564 |
# --- Funções de Correção Padrão OAB ---
|
|
|
|
|
|
|
| 565 |
def parse_oab_pdf(file_obj):
|
| 566 |
if file_obj is None: return None, None, None, "⚠️ Nenhum PDF OAB."
|
| 567 |
try:
|
|
|
|
| 576 |
line_strip = line.strip()
|
| 577 |
line_lower = line_strip.lower()
|
| 578 |
|
|
|
|
| 579 |
if line_strip.startswith("Enunciado"): current_section = "enunciado"; continue
|
| 580 |
if line_strip.startswith("Gabarito comentado"): current_section = "gabarito"; continue
|
| 581 |
if line_strip.startswith("Distribuição dos Pontos"): current_section = "distribuicao"; continue
|
|
|
|
| 582 |
if line_strip.startswith("PADRÃO DE RESPOSTA – QUESTÃO"): current_section = None; break
|
| 583 |
+
if line_strip.startswith("Padrão de Resposta"): continue
|
| 584 |
|
| 585 |
if current_section == "enunciado": enunciado += line + "\n"
|
| 586 |
elif current_section == "gabarito": gabarito += line + "\n"
|
|
|
|
| 590 |
gabarito = gabarito.strip()
|
| 591 |
distribuicao = distribuicao.strip()
|
| 592 |
|
|
|
|
| 593 |
if not enunciado or not gabarito or not distribuicao:
|
| 594 |
logger.warning(f"Parse OAB PDF falhou. E:{bool(enunciado)}, G:{bool(gabarito)}, D:{bool(distribuicao)}")
|
| 595 |
+
return None, None, None, f"⚠️ Falha separar seções. Verifique o texto completo:\n\n{full_text[:500]}..."
|
| 596 |
|
| 597 |
logger.info("PDF OAB parseado.")
|
| 598 |
return enunciado, gabarito, distribuicao, "✅ PDF OAB carregado e seções extraídas."
|
|
|
|
| 600 |
logger.error(f"Erro parsear PDF OAB: {str(e)}", exc_info=True)
|
| 601 |
return None, None, None, f"❌ Erro processar PDF OAB: {str(e)}"
|
| 602 |
|
|
|
|
| 603 |
def estruturar_prompt_geracao_modelo_oab(enunciado, gabarito, distribuicao):
|
| 604 |
prompt = f"""
|
| 605 |
**Tarefa:** Elabore a peça processual completa e adequada para o **Enunciado**, seguindo **estritamente** as diretrizes do **Gabarito Comentado** e os critérios da **Distribuição dos Pontos**. Crie uma peça modelo perfeita para este caso OAB.
|
|
|
|
| 636 |
|
| 637 |
logger.info("Gerando peça modelo OAB...")
|
| 638 |
prompt = estruturar_prompt_geracao_modelo_oab(enunciado, gabarito, distribuicao)
|
| 639 |
+
peticao_modelo = chamar_api(prompt, use_oab_config=True)
|
| 640 |
|
| 641 |
if peticao_modelo.startswith("❌") or peticao_modelo.startswith("⏱️"):
|
| 642 |
logger.error(f"Erro API gerar modelo OAB: {peticao_modelo}")
|
|
|
|
| 674 |
1. **Avaliação Pontual:** Para **cada item** na **Distribuição**, verifique se foi abordado pelo Usuário conforme o Gabarito. Atribua a pontuação correspondente.
|
| 675 |
2. **Justificativa:** Justifique brevemente a pontuação de cada item.
|
| 676 |
3. **Feedback:** Aponte erros/omissões do Usuário vs Gabarito/Distribuição.
|
| 677 |
+
4. **Peça Corrigida (Opcional):** Se possível, sugira trechos corrigidos para alinhar ao padrão.
|
| 678 |
5. **Output Markdown:**
|
| 679 |
|
| 680 |
```markdown
|
|
|
|
| 708 |
|
| 709 |
logger.info("Corrigindo pela OAB...")
|
| 710 |
prompt = estruturar_prompt_correcao_pela_oab(peticao_usuario, enunciado, gabarito, distribuicao)
|
| 711 |
+
correcao_oab = chamar_api(prompt, use_oab_config=True)
|
| 712 |
|
| 713 |
if correcao_oab.startswith("❌") or correcao_oab.startswith("⏱️"):
|
| 714 |
logger.error(f"Erro API corrigir OAB: {correcao_oab}")
|
|
|
|
| 717 |
logger.info("Correção/Avaliação OAB concluída.")
|
| 718 |
return correcao_oab
|
| 719 |
|
| 720 |
+
# --- Funções Auxiliares (Diff, Histórico, Salvar/Carregar, Gerar Caso Fictício, Dicas) ---
|
|
|
|
|
|
|
| 721 |
def calcular_diff_interno(texto_original, texto_corrigido):
|
| 722 |
if not texto_original or not texto_corrigido or texto_corrigido.startswith("⚠️") or texto_corrigido.startswith("❌"): return "","",""
|
| 723 |
orig_lines = texto_original.splitlines(); corr_lines = texto_corrigido.splitlines()
|
|
|
|
| 742 |
|
| 743 |
def calcular_progresso():
|
| 744 |
if not HISTORICO: return "📊 Progresso vazio."
|
|
|
|
| 745 |
notas_geral = []
|
| 746 |
tipos_geral = set()
|
| 747 |
count_geral = 0
|
|
|
|
| 818 |
logger.info("Caso gerado.")
|
| 819 |
return caso
|
| 820 |
|
| 821 |
+
def fornecer_dica_contextual(texto_peticao, tipo_peticao):
|
| 822 |
+
if not texto_peticao or not texto_peticao.strip():
|
| 823 |
+
return "Digite algo na petição para receber dicas..."
|
| 824 |
+
dicas_relevantes = []
|
| 825 |
+
texto_lower = texto_peticao.lower()
|
| 826 |
+
for chave, dica in DICAS_OAB_MELHORADO.items():
|
| 827 |
+
if chave in ["Clareza e Concisão", "Fundamentação Legal", "Coerência Argumentativa", "Revisão Ortográfica e Gramatical", "Formatação"]:
|
| 828 |
+
dicas_relevantes.append(f"💡 **{chave}:** {dica}")
|
| 829 |
+
keywords_por_tipo = {
|
| 830 |
+
"Petição Inicial": ["endereçamento", "qualificação", "fatos", "fundamentos", "pedidos", "valor da causa", "provas", "audiência", "citação", "custas"],
|
| 831 |
+
"Contestação": ["preliminar", "mérito", "impugnação", "fatos", "improcedência", "provas", "honorários"],
|
| 832 |
+
"Reconvenção": ["reconvinte", "reconvindo", "conexão", "pedidos reconvencionais"],
|
| 833 |
+
"Impugnação à Contestação": ["réplica", "preliminar", "fatos novos", "documentos", "ratifica"],
|
| 834 |
+
"Embargos de Declaração": ["omissão", "contradição", "obscuridade", "erro material", "decisão embargada"],
|
| 835 |
+
"Recurso de Apelação": ["sentença", "reforma", "anulação", "dialeticidade", "preparo", "tribunal", "razões"],
|
| 836 |
+
"Agravo de Instrumento": ["decisão interlocutória", "tribunal", "cabimento", "urgência", "efeito suspensivo", "peças obrigatórias"],
|
| 837 |
+
"Petição de Tutela Provisória": ["urgência", "evidência", "liminar", "periculum", "fumus boni", "probabilidade", "risco"],
|
| 838 |
+
"Ação de Alimentos Gravídicos": ["gravídicos", "nascituro", "indícios de paternidade", "binômio", "conversão", "lei 11.804"],
|
| 839 |
+
}
|
| 840 |
+
if tipo_peticao in keywords_por_tipo:
|
| 841 |
+
for keyword in keywords_por_tipo[tipo_peticao]:
|
| 842 |
+
if keyword in texto_lower:
|
| 843 |
+
for chave, dica in DICAS_OAB_MELHORADO.items():
|
| 844 |
+
chave_lower = chave.lower()
|
| 845 |
+
tipo_simples = tipo_peticao.split()[0].lower() if tipo_peticao else ""
|
| 846 |
+
if f"({tipo_simples})" in chave_lower or keyword in chave_lower:
|
| 847 |
+
dica_formatada = f"💡 **{chave}:** {dica}"
|
| 848 |
+
if dica_formatada not in dicas_relevantes:
|
| 849 |
+
dicas_relevantes.append(dica_formatada)
|
| 850 |
+
if not dicas_relevantes:
|
| 851 |
+
return "💡 Continue escrevendo ou selecione o tipo de peça para dicas mais específicas."
|
| 852 |
+
return "\n\n".join(dicas_relevantes[:5])
|
| 853 |
+
|
| 854 |
+
def estruturar_prompt_geracao_caso(tipo_peticao="Petição Inicial"):
|
| 855 |
+
prompt = f"""
|
| 856 |
+
Crie um caso fictício **detalhado e realista** para um exercício prático de elaboração de uma peça do tipo **"{tipo_peticao}"**, simulando um cenário de Exame de Ordem (OAB).
|
| 857 |
+
**Instruções Gerais para o Caso:**
|
| 858 |
+
1. **Complexidade Adequada:** (Ideal: 15-25 linhas).
|
| 859 |
+
2. **Dados Essenciais:** Nomes, locais, datas, valores, relação jurídica, conflito.
|
| 860 |
+
3. **Coerência:** Fatos lógicos para a peça indicada.
|
| 861 |
+
4. **Foco no Tipo de Peça:** Cenário exige **{tipo_peticao}**.
|
| 862 |
+
**Instruções Específicas para Gerar Caso para "{tipo_peticao}":**
|
| 863 |
+
"""
|
| 864 |
+
if tipo_peticao == "Petição Inicial" or tipo_peticao == "Ação de Alimentos Gravídicos":
|
| 865 |
+
prompt += "* Descreva violação de direitos, busca inicial da tutela. Elementos para danos. Dados para qualificação. Temas: consumo, contrato, cobrança, despejo, família (alimentos gravídicos - incluir indícios paternidade, necessidade mãe/nascituro)."
|
| 866 |
+
elif tipo_peticao == "Contestação":
|
| 867 |
+
prompt += "* Resumo da Inicial recebida. Versão dos fatos do RÉU. Elementos para Preliminares (Art. 337), Impugnação Específica, Defesa de Mérito (direta/indireta). Dados qualificação réu."
|
| 868 |
+
# ... (Add other types as before) ...
|
| 869 |
+
else: prompt += "* Crie um cenário jurídico cível com conflito claro."
|
| 870 |
+
|
| 871 |
+
prompt += """
|
| 872 |
+
**Finalize o caso com:**
|
| 873 |
+
"**Situação-Problema:** Na qualidade de advogado(a) de [Nome do Cliente], elabore a peça processual cabível ({tipo_peticao})."
|
| 874 |
+
**Importante:** Evite temas excessivamente específicos. Foco em Civil/Processo Civil comum.
|
| 875 |
+
"""
|
| 876 |
+
return prompt
|
| 877 |
+
|
| 878 |
|
| 879 |
+
# --- Interface Gradio ---
|
| 880 |
def interface_gradio():
|
| 881 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="orange")) as demo:
|
| 882 |
gr.Markdown("# ⚖️ Corretor Jurídico OAB Master ⚖️")
|
| 883 |
gr.Markdown("Use a **Correção Geral (IA)** para feedback amplo ou a **Correção Baseada no Padrão OAB** para avaliação específica.")
|
| 884 |
|
| 885 |
with gr.Tabs() as main_tabs:
|
|
|
|
| 886 |
with gr.TabItem("🤖 Correção Geral (IA)", id=0):
|
| 887 |
with gr.Row():
|
| 888 |
with gr.Column(scale=1):
|
|
|
|
| 928 |
processing_message_geral = gr.Markdown("", visible=False)
|
| 929 |
with gr.Tabs():
|
| 930 |
with gr.TabItem("📊 Análise IA"): resultado_analise_output_geral = gr.Markdown()
|
|
|
|
| 931 |
with gr.TabItem("✨ Correção IA"): resultado_peticao_corrigida_output_geral = gr.Textbox(lines=15, show_copy_button=True)
|
| 932 |
with gr.TabItem("⚖️ Diff"):
|
| 933 |
with gr.Row():
|
|
|
|
| 935 |
with gr.Column(scale=3): visualizacao_detalhada_output_geral = gr.HTML()
|
| 936 |
criticas_output_geral = gr.Markdown()
|
| 937 |
|
|
|
|
| 938 |
with gr.TabItem("📄 Correção Padrão OAB", id=1):
|
| 939 |
gr.Markdown("Forneça o material oficial (PDF ou texto) e sua peça.")
|
| 940 |
with gr.Row():
|
|
|
|
| 962 |
|
| 963 |
clear_btn = gr.Button("🗑️ Limpar Tudo")
|
| 964 |
|
|
|
|
| 965 |
caso_btn_geral.click(gerar_caso_ficticio, [tipo_peticao_input_geral], [caso_input_geral])
|
| 966 |
peticao_texto_input_geral.change(fornecer_dica_contextual, [peticao_texto_input_geral, tipo_peticao_input_geral], dica_contextual_output_geral)
|
| 967 |
tipo_peticao_input_geral.change(fornecer_dica_contextual, [peticao_texto_input_geral, tipo_peticao_input_geral], dica_contextual_output_geral)
|
| 968 |
peticao_arquivo_input_geral.change(process_file, [peticao_arquivo_input_geral], arquivo_preview_output_geral)
|
| 969 |
|
|
|
|
| 970 |
btn_corrigir_geral.click( lambda: gr.update(value="⏳ Processando IA...", visible=True), None, processing_message_geral).then(
|
| 971 |
corrigir_peticao_geral_ia,
|
| 972 |
[caso_input_geral, tipo_peticao_input_geral, peticao_texto_input_geral, gr.State(None), modo_treinamento_geral],
|
|
|
|
| 974 |
resumo_alteracoes_output_geral, criticas_output_geral, gr.Markdown(visible=False), visualizacao_detalhada_output_geral]
|
| 975 |
).then( lambda: gr.update(visible=False), None, processing_message_geral )
|
| 976 |
|
|
|
|
| 977 |
btn_corrigir_arquivo_geral.click( lambda: gr.update(value="⏳ Processando IA...", visible=True), None, processing_message_geral).then(
|
| 978 |
corrigir_peticao_geral_ia,
|
| 979 |
[caso_input_geral, tipo_peticao_input_geral, gr.State(None), peticao_arquivo_input_geral, modo_treinamento_geral],
|
|
|
|
| 981 |
resumo_alteracoes_output_geral, criticas_output_geral, gr.Markdown(visible=False), visualizacao_detalhada_output_geral]
|
| 982 |
).then( lambda: gr.update(visible=False), None, processing_message_geral )
|
| 983 |
|
|
|
|
| 984 |
salvar_btn_geral.click( lambda: gr.update(value="⏳ Salvando...", visible=True), None, processing_message_geral).then(
|
| 985 |
salvar_progresso, [caso_input_geral, peticao_texto_input_geral, tipo_peticao_input_geral],
|
| 986 |
[gr.Textbox(visible=False), config_status_geral, progresso_download_file_geral]
|
|
|
|
| 991 |
[tipo_peticao_input_geral, caso_input_geral, peticao_texto_input_geral, config_status_geral]
|
| 992 |
).then( lambda: gr.update(visible=False), None, processing_message_geral )
|
| 993 |
|
|
|
|
| 994 |
oab_pdf_input.change(parse_oab_pdf, [oab_pdf_input], [oab_enunciado_input, oab_gabarito_input, oab_distribuicao_input, parse_status_output])
|
| 995 |
btn_gerar_modelo_oab.click( lambda: gr.update(value="⏳ Gerando Modelo...", visible=True), None, processing_message_oab).then(
|
| 996 |
gerar_peticao_modelo_oab, [oab_enunciado_input, oab_gabarito_input, oab_distribuicao_input], [resultado_modelo_oab_output]
|
|
|
|
| 999 |
corrigir_pela_oab, [peticao_usuario_oab_input, oab_enunciado_input, oab_gabarito_input, oab_distribuicao_input], [resultado_correcao_oab_output]
|
| 1000 |
).then( lambda: gr.update(visible=False), None, processing_message_oab )
|
| 1001 |
|
| 1002 |
+
clear_btn.click( fn=lambda: [
|
| 1003 |
+
"Petição Inicial", False, None, None, None, None, "", "", "", "", "", "", "", None, None,
|
| 1004 |
+
None, "", None, None, None, "", "", "", ""
|
|
|
|
| 1005 |
], inputs=None, outputs=[
|
| 1006 |
tipo_peticao_input_geral, modo_treinamento_geral, caso_input_geral, peticao_texto_input_geral, peticao_arquivo_input_geral,
|
| 1007 |
arquivo_preview_output_geral, processing_message_geral, resultado_analise_output_geral,
|
|
|
|
| 1014 |
|
| 1015 |
return demo
|
| 1016 |
|
|
|
|
| 1017 |
if __name__ == "__main__":
|
| 1018 |
app = interface_gradio()
|
| 1019 |
app.launch()
|