Update app.py
Browse files
app.py
CHANGED
|
@@ -15,6 +15,9 @@ import cv2
|
|
| 15 |
import numpy as np
|
| 16 |
from datetime import datetime
|
| 17 |
from ratelimiter import RateLimiter
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
load_dotenv()
|
| 20 |
|
|
@@ -186,6 +189,20 @@ def calcular_pontuacao(enderecamento, fundamentos, pedidos, fechamento):
|
|
| 186 |
tabela_formatada = "\n".join([f"| {linha[0].ljust(60)} | {linha[1].rjust(10)} |" for linha in tabela])
|
| 187 |
return f"{tabela_formatada}\n\n**Nota Final:** {nota_final:.2f} / 10,00"
|
| 188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
def estruturar_prompt_correcao(caso, peticao, modo_treinamento=False):
|
| 190 |
base_prompt = f"""
|
| 191 |
## Correção Rigorosa de Petição Inicial Cível (Critérios Realistas da OAB)
|
|
@@ -262,9 +279,10 @@ def estruturar_prompt_correcao(caso, peticao, modo_treinamento=False):
|
|
| 262 |
base_prompt += f"""
|
| 263 |
**Modo de Treinamento Interativo Ativado:**
|
| 264 |
- Para cada item com pontuação inferior ao máximo, forneça:
|
| 265 |
-
a) Uma explicação detalhada (mínimo 2 frases) descrevendo o erro e
|
| 266 |
-
b) Uma sugestão de redação corrigida baseada
|
| 267 |
-
c)
|
|
|
|
| 268 |
- Não resuma; detalhe cada erro de forma pedagógica e clara.
|
| 269 |
"""
|
| 270 |
return base_prompt
|
|
@@ -341,6 +359,10 @@ def corrigir_peticao(caso, peticao_texto=None, peticao_arquivo=None, modo_treina
|
|
| 341 |
if not peticao_conteudo.strip():
|
| 342 |
return "⚠️ Forneça uma petição."
|
| 343 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 344 |
cache_key = f"{caso[:50]}|{peticao_conteudo[:50]}|{modo_treinamento}"
|
| 345 |
if cache_key in CORRECAO_CACHE:
|
| 346 |
return CORRECAO_CACHE[cache_key]
|
|
@@ -376,7 +398,7 @@ def corrigir_peticao(caso, peticao_texto=None, peticao_arquivo=None, modo_treina
|
|
| 376 |
analise = correção_completa.strip()
|
| 377 |
correção_formatada = formatar_correção(analise)
|
| 378 |
HISTORICO.append({
|
| 379 |
-
"data": datetime.now().strftime("%Y-%
|
| 380 |
"caso": caso,
|
| 381 |
"peticao": peticao_conteudo,
|
| 382 |
"correcao_completa": correção_completa
|
|
@@ -400,11 +422,19 @@ def formatar_correção(texto):
|
|
| 400 |
linhas = texto.split('\n')
|
| 401 |
texto_formatado = ""
|
| 402 |
for linha in linhas:
|
| 403 |
-
if "Análise Geral" in linha
|
| 404 |
-
texto_formatado += f"### {linha.strip()}\n\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 405 |
elif linha.strip().startswith('-') and len(linha) > 2 and any(termo in linha for termo in ["Endereçamento", "Qualificação", "Fatos", "Pedidos", "Valor", "Provas"]):
|
| 406 |
texto_formatado += f"**{linha.strip()}**\n"
|
| 407 |
-
elif "Explicação" in linha or "Sugestão" in linha or "Dica" in linha:
|
| 408 |
texto_formatado += f"*{linha.strip()}*\n"
|
| 409 |
else:
|
| 410 |
texto_formatado += f"{linha}\n"
|
|
@@ -414,7 +444,7 @@ def formatar_correção(texto):
|
|
| 414 |
match = re.search(nota_pattern, texto_formatado, re.DOTALL)
|
| 415 |
if match:
|
| 416 |
nota = match.group(1)
|
| 417 |
-
texto_formatado = texto_formatado.replace(f"### Nota Final\n\n{nota}", f"### Nota Final: {nota}/10\n\n")
|
| 418 |
return texto_formatado
|
| 419 |
|
| 420 |
def extrair_peticao_corrigida(correcao_completa):
|
|
@@ -450,9 +480,6 @@ def calcular_progresso():
|
|
| 450 |
return f"📊 Progresso: Média {media:.1f}/10 | Tentativas: {len(notas)} | Tendência: {tendencia}"
|
| 451 |
|
| 452 |
def comparar_peticao_melhorada(caso, peticao_texto, correcao):
|
| 453 |
-
import difflib
|
| 454 |
-
from html import escape
|
| 455 |
-
|
| 456 |
if not caso:
|
| 457 |
return "⚠️ Forneça um caso antes de comparar.", "", ""
|
| 458 |
peticao = peticao_texto if peticao_texto else (HISTORICO[-1]["peticao"] if HISTORICO else "")
|
|
@@ -497,6 +524,7 @@ def comparar_peticao_melhorada(caso, peticao_texto, correcao):
|
|
| 497 |
|
| 498 |
secao_atual = "OUTROS"
|
| 499 |
resultado_diff = []
|
|
|
|
| 500 |
for linha in diff:
|
| 501 |
if linha.startswith(' '):
|
| 502 |
texto = linha[2:]
|
|
@@ -506,6 +534,8 @@ def comparar_peticao_melhorada(caso, peticao_texto, correcao):
|
|
| 506 |
resultado_diff.append(f"<div class='linha-igual'>{escape(texto)}</div>")
|
| 507 |
elif linha.startswith('- '):
|
| 508 |
texto = linha[2:]
|
|
|
|
|
|
|
| 509 |
resultado_diff.append(f"<div class='linha-removida'><del>{escape(texto)}</del></div>")
|
| 510 |
secoes[secao_atual].append(f"- REMOVIDO: {texto}")
|
| 511 |
elif linha.startswith('+ '):
|
|
@@ -513,6 +543,8 @@ def comparar_peticao_melhorada(caso, peticao_texto, correcao):
|
|
| 513 |
nova_secao = identificar_secao(texto)
|
| 514 |
if nova_secao != "OUTROS":
|
| 515 |
secao_atual = nova_secao
|
|
|
|
|
|
|
| 516 |
resultado_diff.append(f"<div class='linha-adicionada'><ins>{escape(texto)}</ins></div>")
|
| 517 |
secoes[secao_atual].append(f"+ ADICIONADO: {texto}")
|
| 518 |
elif linha.startswith('? '):
|
|
@@ -524,31 +556,56 @@ def comparar_peticao_melhorada(caso, peticao_texto, correcao):
|
|
| 524 |
resumo_alteracoes = []
|
| 525 |
for secao, alteracoes in secoes.items():
|
| 526 |
if alteracoes:
|
| 527 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 528 |
for alt in alteracoes[:5]:
|
| 529 |
-
|
|
|
|
| 530 |
if len(alteracoes) > 5:
|
| 531 |
-
resumo_alteracoes.append(f" - ... e mais {len(alteracoes) - 5} alterações
|
| 532 |
|
| 533 |
resumo_estatistico = f"""
|
| 534 |
-
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
|
| 541 |
-
|
| 542 |
-
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
|
| 546 |
-
|
| 547 |
-
|
| 548 |
-
|
| 549 |
-
|
|
|
|
|
|
|
|
|
|
| 550 |
return peticao, peticao_corrigida, resumo_estatistico
|
| 551 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 552 |
def interface_gradio():
|
| 553 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 554 |
gr.Markdown("# 📝 Corretor Avançado de Petições Iniciais (Critérios OAB)")
|
|
@@ -592,7 +649,7 @@ def interface_gradio():
|
|
| 592 |
with gr.Row():
|
| 593 |
gr.Markdown("### 🧩 Gerar Caso Fictício")
|
| 594 |
caso_btn = gr.Button("🔄 Gerar Novo Caso Fictício", variant="secondary")
|
| 595 |
-
caso_input = gr.Textbox(label="
|
| 596 |
with gr.Tabs():
|
| 597 |
with gr.TabItem("✏️ Inserir Texto"):
|
| 598 |
peticao_texto = gr.Textbox(label="Texto da Petição do Aluno", lines=15, placeholder="Insira a petição completa...")
|
|
@@ -618,6 +675,8 @@ def interface_gradio():
|
|
| 618 |
|
| 619 |
with gr.Row():
|
| 620 |
comparacao_diferencas = gr.HTML(label="Diferenças Destacadas")
|
|
|
|
|
|
|
| 621 |
|
| 622 |
with gr.Accordion("📜 Histórico de Correções", open=False):
|
| 623 |
historico_output = gr.Markdown()
|
|
@@ -639,14 +698,25 @@ def interface_gradio():
|
|
| 639 |
outputs=[resultado_output]
|
| 640 |
)
|
| 641 |
clear_btn.click(
|
| 642 |
-
fn=lambda: [None, None, None, None, "", "", "", ""],
|
| 643 |
inputs=None,
|
| 644 |
-
outputs=[caso_input, peticao_texto, peticao_arquivo, arquivo_preview, resultado_output, dica_contextual, peticao_aluno_output, peticao_corrigida_output]
|
| 645 |
)
|
| 646 |
comparar_btn.click(
|
| 647 |
fn=comparar_peticao_melhorada,
|
| 648 |
inputs=[caso_input, peticao_texto, resultado_output],
|
| 649 |
outputs=[peticao_aluno_output, peticao_corrigida_output, comparacao_diferencas]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 650 |
)
|
| 651 |
|
| 652 |
with gr.Accordion("📘 Critérios Detalhados", open=False):
|
|
|
|
| 15 |
import numpy as np
|
| 16 |
from datetime import datetime
|
| 17 |
from ratelimiter import RateLimiter
|
| 18 |
+
import difflib
|
| 19 |
+
from html import escape
|
| 20 |
+
import pdfkit # Requer wkhtmltopdf instalado
|
| 21 |
|
| 22 |
load_dotenv()
|
| 23 |
|
|
|
|
| 189 |
tabela_formatada = "\n".join([f"| {linha[0].ljust(60)} | {linha[1].rjust(10)} |" for linha in tabela])
|
| 190 |
return f"{tabela_formatada}\n\n**Nota Final:** {nota_final:.2f} / 10,00"
|
| 191 |
|
| 192 |
+
def validar_peticao_basica(peticao):
|
| 193 |
+
problemas = []
|
| 194 |
+
if "EXCELENTÍSSIMO" not in peticao.upper():
|
| 195 |
+
problemas.append("⚠️ Endereçamento ausente ou incompleto.")
|
| 196 |
+
if "Art. 319" not in peticao and "CPC" not in peticao:
|
| 197 |
+
problemas.append("⚠️ Fundamentação jurídica não menciona o CPC.")
|
| 198 |
+
if "Dá-se à causa o valor" not in peticao:
|
| 199 |
+
problemas.append("⚠️ Valor da causa não especificado (Art. 319, V, CPC).")
|
| 200 |
+
if "juntada da guia de custas" not in peticao.lower():
|
| 201 |
+
problemas.append("⚠️ Pedido de juntada da guia de custas ausente.")
|
| 202 |
+
if "Nestes termos" not in peticao:
|
| 203 |
+
problemas.append("⚠️ Fechamento formal ausente.")
|
| 204 |
+
return problemas
|
| 205 |
+
|
| 206 |
def estruturar_prompt_correcao(caso, peticao, modo_treinamento=False):
|
| 207 |
base_prompt = f"""
|
| 208 |
## Correção Rigorosa de Petição Inicial Cível (Critérios Realistas da OAB)
|
|
|
|
| 279 |
base_prompt += f"""
|
| 280 |
**Modo de Treinamento Interativo Ativado:**
|
| 281 |
- Para cada item com pontuação inferior ao máximo, forneça:
|
| 282 |
+
a) Uma explicação detalhada (mínimo 2 frases) descrevendo o erro e sua base legal (ex.: Art. 319, CPC).
|
| 283 |
+
b) Uma sugestão de redação corrigida baseada no caso.
|
| 284 |
+
c) Um exemplo prático de redação correta em outro contexto (ex.: "Em uma ação de dano moral, poderia ser: 'Requer a condenação ao pagamento de R$ 10.000,00 por danos morais, conforme Súmula 387 do STJ.'").
|
| 285 |
+
d) Uma dica prática do banco ({json.dumps(DICAS_OAB)}) ou personalizada.
|
| 286 |
- Não resuma; detalhe cada erro de forma pedagógica e clara.
|
| 287 |
"""
|
| 288 |
return base_prompt
|
|
|
|
| 359 |
if not peticao_conteudo.strip():
|
| 360 |
return "⚠️ Forneça uma petição."
|
| 361 |
|
| 362 |
+
problemas = validar_peticao_basica(peticao_conteudo)
|
| 363 |
+
if problemas:
|
| 364 |
+
return f"### Validação Inicial\n\n" + "\n".join(problemas) + "\n\nCorrija os itens acima antes de prosseguir."
|
| 365 |
+
|
| 366 |
cache_key = f"{caso[:50]}|{peticao_conteudo[:50]}|{modo_treinamento}"
|
| 367 |
if cache_key in CORRECAO_CACHE:
|
| 368 |
return CORRECAO_CACHE[cache_key]
|
|
|
|
| 398 |
analise = correção_completa.strip()
|
| 399 |
correção_formatada = formatar_correção(analise)
|
| 400 |
HISTORICO.append({
|
| 401 |
+
"data": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
| 402 |
"caso": caso,
|
| 403 |
"peticao": peticao_conteudo,
|
| 404 |
"correcao_completa": correção_completa
|
|
|
|
| 422 |
linhas = texto.split('\n')
|
| 423 |
texto_formatado = ""
|
| 424 |
for linha in linhas:
|
| 425 |
+
if "Análise Geral" in linha:
|
| 426 |
+
texto_formatado += f"### ℹ️ {linha.strip()}\n\n"
|
| 427 |
+
elif "Nota Final" in linha:
|
| 428 |
+
texto_formatado += f"### ⭐ {linha.strip()}\n\n"
|
| 429 |
+
elif "Pontos Positivos" in linha:
|
| 430 |
+
texto_formatado += f"### ✅ {linha.strip()}\n\n"
|
| 431 |
+
elif "Pontos a Melhorar" in linha:
|
| 432 |
+
texto_formatado += f"### ⚠️ {linha.strip()}\n\n"
|
| 433 |
+
elif "- Invenção de fatos" in linha:
|
| 434 |
+
texto_formatado += f"**🔴 {linha.strip()}**\n"
|
| 435 |
elif linha.strip().startswith('-') and len(linha) > 2 and any(termo in linha for termo in ["Endereçamento", "Qualificação", "Fatos", "Pedidos", "Valor", "Provas"]):
|
| 436 |
texto_formatado += f"**{linha.strip()}**\n"
|
| 437 |
+
elif "Explicação" in linha or "Sugestão" in linha or "Dica" in linha or "Exemplo" in linha:
|
| 438 |
texto_formatado += f"*{linha.strip()}*\n"
|
| 439 |
else:
|
| 440 |
texto_formatado += f"{linha}\n"
|
|
|
|
| 444 |
match = re.search(nota_pattern, texto_formatado, re.DOTALL)
|
| 445 |
if match:
|
| 446 |
nota = match.group(1)
|
| 447 |
+
texto_formatado = texto_formatado.replace(f"### ⭐ Nota Final\n\n{nota}", f"### ⭐ Nota Final: {nota}/10\n\n")
|
| 448 |
return texto_formatado
|
| 449 |
|
| 450 |
def extrair_peticao_corrigida(correcao_completa):
|
|
|
|
| 480 |
return f"📊 Progresso: Média {media:.1f}/10 | Tentativas: {len(notas)} | Tendência: {tendencia}"
|
| 481 |
|
| 482 |
def comparar_peticao_melhorada(caso, peticao_texto, correcao):
|
|
|
|
|
|
|
|
|
|
| 483 |
if not caso:
|
| 484 |
return "⚠️ Forneça um caso antes de comparar.", "", ""
|
| 485 |
peticao = peticao_texto if peticao_texto else (HISTORICO[-1]["peticao"] if HISTORICO else "")
|
|
|
|
| 524 |
|
| 525 |
secao_atual = "OUTROS"
|
| 526 |
resultado_diff = []
|
| 527 |
+
criticas = []
|
| 528 |
for linha in diff:
|
| 529 |
if linha.startswith(' '):
|
| 530 |
texto = linha[2:]
|
|
|
|
| 534 |
resultado_diff.append(f"<div class='linha-igual'>{escape(texto)}</div>")
|
| 535 |
elif linha.startswith('- '):
|
| 536 |
texto = linha[2:]
|
| 537 |
+
if any(kw in texto.lower() for kw in ["invenção", "custas", "art. 319"]):
|
| 538 |
+
criticas.append(f"🔴 REMOVIDO: {texto}")
|
| 539 |
resultado_diff.append(f"<div class='linha-removida'><del>{escape(texto)}</del></div>")
|
| 540 |
secoes[secao_atual].append(f"- REMOVIDO: {texto}")
|
| 541 |
elif linha.startswith('+ '):
|
|
|
|
| 543 |
nova_secao = identificar_secao(texto)
|
| 544 |
if nova_secao != "OUTROS":
|
| 545 |
secao_atual = nova_secao
|
| 546 |
+
if any(kw in texto.lower() for kw in ["custas", "art. 319"]):
|
| 547 |
+
criticas.append(f"🟢 ADICIONADO: {texto}")
|
| 548 |
resultado_diff.append(f"<div class='linha-adicionada'><ins>{escape(texto)}</ins></div>")
|
| 549 |
secoes[secao_atual].append(f"+ ADICIONADO: {texto}")
|
| 550 |
elif linha.startswith('? '):
|
|
|
|
| 556 |
resumo_alteracoes = []
|
| 557 |
for secao, alteracoes in secoes.items():
|
| 558 |
if alteracoes:
|
| 559 |
+
adicionadas = sum(1 for alt in alteracoes if alt.startswith("+"))
|
| 560 |
+
removidas = sum(1 for alt in alteracoes if alt.startswith("-"))
|
| 561 |
+
resumo_alteracoes.append(f"""
|
| 562 |
+
### {secao}
|
| 563 |
+
| Tipo | Quantidade |
|
| 564 |
+
|--------------|------------|
|
| 565 |
+
| Adicionadas | {adicionadas} |
|
| 566 |
+
| Removidas | {removidas} |
|
| 567 |
+
""")
|
| 568 |
for alt in alteracoes[:5]:
|
| 569 |
+
texto = alt[:60] + "..." if len(alt) > 60 else alt
|
| 570 |
+
resumo_alteracoes.append(f" {texto}")
|
| 571 |
if len(alteracoes) > 5:
|
| 572 |
+
resumo_alteracoes.append(f" - ... e mais {len(alteracoes) - 5} alterações")
|
| 573 |
|
| 574 |
resumo_estatistico = f"""
|
| 575 |
+
## 📊 Resumo das Alterações
|
| 576 |
+
- **Linhas Removidas:** {total_removidas}
|
| 577 |
+
- **Linhas Adicionadas:** {total_adicionadas}
|
| 578 |
+
- **Diferença Líquida:** {total_adicionadas - total_removidas} linhas
|
| 579 |
+
|
| 580 |
+
## 🚨 Mudanças Críticas
|
| 581 |
+
{''.join(criticas) if criticas else 'Nenhuma mudança crítica detectada.'}
|
| 582 |
+
|
| 583 |
+
## 🔍 Alterações por Seção
|
| 584 |
+
{''.join(resumo_alteracoes)}
|
| 585 |
+
|
| 586 |
+
## 📝 Visualização Detalhada
|
| 587 |
+
<style>
|
| 588 |
+
.linha-igual {{ color: #000000; margin: 2px 0; }}
|
| 589 |
+
.linha-removida {{ color: #ffffff; background-color: #b30000; margin: 2px 0; padding: 2px; }}
|
| 590 |
+
.linha-adicionada {{ color: #ffffff; background-color: #006600; margin: 2px 0; padding: 2px; }}
|
| 591 |
+
</style>
|
| 592 |
+
{"".join(resultado_diff)}
|
| 593 |
+
"""
|
| 594 |
return peticao, peticao_corrigida, resumo_estatistico
|
| 595 |
|
| 596 |
+
def exportar_diferencas(caso, peticao_texto, correcao):
|
| 597 |
+
_, _, resumo_estatistico = comparar_peticao_melhorada(caso, peticao_texto, correcao)
|
| 598 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".html") as tmp:
|
| 599 |
+
tmp.write(resumo_estatistico.encode('utf-8'))
|
| 600 |
+
pdf_path = tmp.name.replace(".html", ".pdf")
|
| 601 |
+
try:
|
| 602 |
+
pdfkit.from_file(tmp.name, pdf_path)
|
| 603 |
+
return pdf_path
|
| 604 |
+
except Exception as e:
|
| 605 |
+
return f"❌ Erro ao gerar PDF: {str(e)}"
|
| 606 |
+
finally:
|
| 607 |
+
os.unlink(tmp.name)
|
| 608 |
+
|
| 609 |
def interface_gradio():
|
| 610 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 611 |
gr.Markdown("# 📝 Corretor Avançado de Petições Iniciais (Critérios OAB)")
|
|
|
|
| 649 |
with gr.Row():
|
| 650 |
gr.Markdown("### 🧩 Gerar Caso Fictício")
|
| 651 |
caso_btn = gr.Button("🔄 Gerar Novo Caso Fictício", variant="secondary")
|
| 652 |
+
caso_input = gr.Textbox(label="📋 Caso Fornecido pela Banca", lines=8, placeholder="Insira o texto COMPLETO do caso...")
|
| 653 |
with gr.Tabs():
|
| 654 |
with gr.TabItem("✏️ Inserir Texto"):
|
| 655 |
peticao_texto = gr.Textbox(label="Texto da Petição do Aluno", lines=15, placeholder="Insira a petição completa...")
|
|
|
|
| 675 |
|
| 676 |
with gr.Row():
|
| 677 |
comparacao_diferencas = gr.HTML(label="Diferenças Destacadas")
|
| 678 |
+
export_btn = gr.Button("📥 Exportar Diferenças", visible=False)
|
| 679 |
+
export_file = gr.File(label="Baixar Diferenças", visible=False)
|
| 680 |
|
| 681 |
with gr.Accordion("📜 Histórico de Correções", open=False):
|
| 682 |
historico_output = gr.Markdown()
|
|
|
|
| 698 |
outputs=[resultado_output]
|
| 699 |
)
|
| 700 |
clear_btn.click(
|
| 701 |
+
fn=lambda: [None, None, None, None, "", "", "", "", gr.update(visible=False), gr.update(visible=False)],
|
| 702 |
inputs=None,
|
| 703 |
+
outputs=[caso_input, peticao_texto, peticao_arquivo, arquivo_preview, resultado_output, dica_contextual, peticao_aluno_output, peticao_corrigida_output, export_btn, export_file]
|
| 704 |
)
|
| 705 |
comparar_btn.click(
|
| 706 |
fn=comparar_peticao_melhorada,
|
| 707 |
inputs=[caso_input, peticao_texto, resultado_output],
|
| 708 |
outputs=[peticao_aluno_output, peticao_corrigida_output, comparacao_diferencas]
|
| 709 |
+
).then(
|
| 710 |
+
fn=lambda: [gr.update(visible=True), gr.update(visible=False)],
|
| 711 |
+
outputs=[export_btn, export_file]
|
| 712 |
+
)
|
| 713 |
+
export_btn.click(
|
| 714 |
+
fn=exportar_diferencas,
|
| 715 |
+
inputs=[caso_input, peticao_texto, resultado_output],
|
| 716 |
+
outputs=export_file
|
| 717 |
+
).then(
|
| 718 |
+
fn=lambda x: [gr.update(visible=True, value=x), gr.update(visible=True)],
|
| 719 |
+
outputs=[export_file, export_btn]
|
| 720 |
)
|
| 721 |
|
| 722 |
with gr.Accordion("📘 Critérios Detalhados", open=False):
|