Files changed (1) hide show
  1. app.py +657 -133
app.py CHANGED
@@ -4,16 +4,17 @@ import json
4
  import os
5
  import copy
6
 
 
7
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
8
  if not GEMINI_API_KEY:
9
  print("ALERTA: GEMINI_API_KEY não encontrada como Secret no Hugging Face Space. O app não funcionará.")
10
  # Para teste local, descomente e cole sua chave, mas NÃO FAÇA COMMIT DISSO COM A CHAVE.
11
  # GEMINI_API_KEY = "SUA_CHAVE_AQUI_PARA_TESTE_LOCAL_APENAS"
12
 
13
-
14
- MODEL_NAME = "gemini-1.5-flash-latest"
15
  API_URL_BASE = f"https://generativelanguage.googleapis.com/v1beta/models/{MODEL_NAME}:generateContent"
16
 
 
17
  FASE_INICIAL_CONFIG = "CONFIGURACAO"
18
  FASE_ABERTURA_CONCILIACAO = "ABERTURA_E_CONCILIACAO"
19
  FASE_TESTEMUNHAS_AUTOR_INICIO = "TESTEMUNHAS_AUTOR_INICIO"
@@ -27,6 +28,71 @@ FASE_ALEGACOES_FINAIS_REU = "ALEGACOES_FINAIS_REU"
27
  FASE_ANALISE_FINAL_PROFESSOR = "ANALISE_FINAL_PROFESSOR"
28
  FASE_CONCLUIDA = "AIJ_CONCLUIDA"
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  def estado_inicial_simulacao():
31
  return {
32
  "fase_aij": FASE_INICIAL_CONFIG, "caso_fatos": "", "provas_reu_texto": "",
@@ -35,7 +101,7 @@ def estado_inicial_simulacao():
35
  "testemunha_reu_atual_idx": -1, "testemunha_em_depoimento": None,
36
  "transcricao_chat": [], "transcricao_logica": [],
37
  "feedback_para_usuario": "Aguardando início da simulação.",
38
- "instrucao_para_usuario": "Configure os detalhes do caso na aba 'Configuração'."
39
  }
40
 
41
  def chamar_gemini_api(prompt_text, temperature=0.7, max_output_tokens=800):
@@ -55,7 +121,7 @@ def chamar_gemini_api(prompt_text, temperature=0.7, max_output_tokens=800):
55
  ]
56
  }
57
  try:
58
- response = requests.post(api_url_com_chave, headers=headers, data=json.dumps(data), timeout=120)
59
  response.raise_for_status()
60
  response_json = response.json()
61
  if response_json.get("candidates") and response_json["candidates"][0].get("content"):
@@ -63,6 +129,8 @@ def chamar_gemini_api(prompt_text, temperature=0.7, max_output_tokens=800):
63
  elif response_json.get("promptFeedback") and response_json["promptFeedback"].get("blockReason"):
64
  return f"ERRO_API: Conteúdo bloqueado. Razão: {response_json['promptFeedback']['blockReason']}"
65
  return "ERRO_API: Resposta inesperada da API."
 
 
66
  except requests.exceptions.RequestException as e:
67
  error_msg = f"ERRO_CONEXAO: {e}"
68
  if e.response is not None:
@@ -80,7 +148,9 @@ def formatar_historico_para_prompt(transcricao_logica, max_turns=15):
80
  historico_formatado += f"- {ator}: {fala}\n"
81
  return historico_formatado
82
 
 
83
  def gerar_caso_ficticio_com_ia():
 
84
  prompt_geracao_caso = """
85
  **Instrução de Persona:** Você é um roteirista jurídico criativo e experiente, especializado em criar casos simulados realistas para treinamento de advogados.
86
  **Tarefa:** Crie um caso fictício detalhado para uma simulação de Audiência de Instrução e Julgamento (AIJ) sobre o tema "Direito ao Esquecimento vs. Liberdade de Imprensa".
@@ -102,12 +172,13 @@ def gerar_caso_ficticio_com_ia():
102
  `## Testemunhas Hipotéticas da Parte RÉ`
103
  O conteúdo de cada seção deve vir após o marcador. Para Argumentos/Provas e Testemunhas, liste cada item em uma nova linha.
104
  """
105
- texto_caso_completo = chamar_gemini_api(prompt_geracao_caso, temperature=0.75, max_output_tokens=2000)
106
  if "ERRO_" in texto_caso_completo:
107
  return {"fatos": f"Falha ao gerar caso com IA: {texto_caso_completo}", "provas_autor": "", "provas_reu": "", "testemunhas_autor": "", "testemunhas_reu": ""}
108
  return parse_caso_gerado(texto_caso_completo)
109
 
110
  def parse_caso_gerado(texto_completo_caso):
 
111
  dados_caso = {"fatos": "Falha parsing: Fatos", "provas_autor": "Falha parsing: Provas Autor", "provas_reu": "Falha parsing: Provas Réu", "testemunhas_autor": "Falha parsing: Testemunhas Autor", "testemunhas_reu": "Falha parsing: Testemunhas Réu"}
112
  secoes = {"fatos": "## Resumo Detalhado dos Fatos", "provas_autor": "## Argumentos e \"Provas\" Hipotéticas da Parte AUTORA", "provas_reu": "## Argumentos e \"Provas\" Hipotéticas da Parte RÉ (Jornal)", "testemunhas_autor": "## Testemunhas Hipotéticas da Parte AUTORA", "testemunhas_reu": "## Testemunhas Hipotéticas da Parte RÉ"}
113
  fatos_prefix = ""
@@ -135,9 +206,16 @@ def parse_caso_gerado(texto_completo_caso):
135
  dados_caso[chave_atual] = fatos_prefix + conteudo_secao if chave_atual == "fatos" and fatos_prefix else conteudo_secao
136
  current_pos = fim_conteudo
137
  for key_testemunha in ["testemunhas_autor", "testemunhas_reu"]:
138
- if "Falha no parsing" not in dados_caso[key_testemunha]:
139
  linhas = dados_caso[key_testemunha].split('\n')
140
- linhas_formatadas = [f"{p[0].strip()}: {p[1].strip()}" if len(p := linha.split(':', 1)) == 2 else linha.strip() for linha in linhas if linha.strip()]
 
 
 
 
 
 
 
141
  dados_caso[key_testemunha] = "\n".join(linhas_formatadas)
142
  return dados_caso
143
 
@@ -146,7 +224,19 @@ def acao_gerar_caso_ficticio_ui():
146
  dados_gerados = gerar_caso_ficticio_com_ia()
147
  return [dados_gerados["fatos"], dados_gerados["provas_reu"], dados_gerados["provas_autor"], dados_gerados["testemunhas_reu"], dados_gerados["testemunhas_autor"], "Caso fictício gerado. Revise e salve."]
148
 
 
 
 
 
 
 
 
 
 
 
 
149
  def gerar_resposta_juiz_ia(estado_simulacao, acao_especifica=""):
 
150
  fase = estado_simulacao["fase_aij"]
151
  historico = formatar_historico_para_prompt(estado_simulacao["transcricao_logica"])
152
  prompt = f"**Persona:** Juiz(a) experiente em AIJ (Direito Esquecimento vs Liberdade Imprensa).\n**Fatos:** {estado_simulacao['caso_fatos'] or 'Não detalhado.'}\n{historico}**Fase Atual:** {fase}\n"
@@ -158,9 +248,10 @@ def gerar_resposta_juiz_ia(estado_simulacao, acao_especifica=""):
158
  elif fase == FASE_ANALISE_FINAL_PROFESSOR: prompt += "**Tarefa:** Declare audiência encerrada para julgamento (simulado)."
159
  else: prompt += f"**Tarefa:** Conduza a audiência. Ação específica: {acao_especifica or 'Nenhuma'}. Mantenha ordem e fluxo."
160
  prompt += "\n**Sua Fala (Juiz):**"
161
- return chamar_gemini_api(prompt, temperature=0.6, max_output_tokens=250)
162
 
163
  def gerar_resposta_advogado_autor_ia(estado_simulacao, fala_adv_reu=""):
 
164
  fase = estado_simulacao["fase_aij"]
165
  historico = formatar_historico_para_prompt(estado_simulacao["transcricao_logica"])
166
  prompt = f"**Persona:** Advogado(a) do AUTOR em AIJ (Direito Esquecimento vs Liberdade Imprensa). Cliente busca esquecimento/reparação.\n**Réu:** Jornal.\n**Fatos:** {estado_simulacao['caso_fatos'] or 'Não detalhado.'}\n**Provas/Argumentos Autor:** {estado_simulacao['provas_autor_supostas_texto'] or 'Passagem tempo, desinteresse público, dano vida privada.'}\n{historico}**Fase Atual:** {fase}\n"
@@ -181,21 +272,91 @@ def gerar_resposta_advogado_autor_ia(estado_simulacao, fala_adv_reu=""):
181
  elif fase == FASE_ALEGACOES_FINAIS_AUTOR: prompt += "**Tarefa:** Juiz concedeu palavra para alegações finais. Apresente resumo persuasivo e reitere pedidos."
182
  else: prompt += f"**Contexto:** Adv. Réu (Usuário) disse: \"{fala_adv_reu}\"\n**Tarefa:** Responda estrategicamente."
183
  prompt += "\n**Sua Resposta (Advogado Autor):**"
184
- return chamar_gemini_api(prompt, temperature=0.75, max_output_tokens=400)
185
 
186
  def gerar_resposta_testemunha_autor_ia(estado_simulacao, pergunta_feita):
 
187
  testemunha_obj = estado_simulacao.get("testemunha_em_depoimento")
188
  if not testemunha_obj or testemunha_obj["parte"] != "AUTOR": return "Testemunha do Autor (IA): (Erro interno - Nenhuma testemunha do autor em depoimento)"
189
  historico = formatar_historico_para_prompt(estado_simulacao["transcricao_logica"])
190
  prompt = f"**Persona:** Testemunha {testemunha_obj['nome']} (AUTOR).\n**Caso:** Direito Esquecimento vs Liberdade Imprensa.\n**Fatos:** {estado_simulacao['caso_fatos'] or 'Não detalhado.'}\n**Seus Pontos Chave:** {testemunha_obj['pontos_chave'] or 'Conhecimento geral sobre autor e impactos.'}\n{historico}**Pergunta Feita:** \"{pergunta_feita}\"\n**Tarefa:** Responda claro, conciso, baseado nos seus pontos. Se Adv. Réu, seja cauteloso(a).\n**Sua Resposta (Testemunha {testemunha_obj['nome']}):**"
191
- return chamar_gemini_api(prompt, temperature=0.6, max_output_tokens=200)
192
 
193
  def analisar_atuacao_defesa_ia(estado_simulacao, ultima_fala_reu=""):
 
194
  historico_completo_dialogo = formatar_historico_para_prompt(estado_simulacao["transcricao_logica"], max_turns=len(estado_simulacao["transcricao_logica"]))
195
  prompt_analise = f"**Persona:** Professor(a) de Prática Jurídica experiente.\n**Tarefa:** Feedback construtivo para aluno (Adv. RÉU - Jornal) em AIJ (Direito Esquecimento vs Liberdade Imprensa).\n**Fatos:** {estado_simulacao['caso_fatos'] or 'Não detalhado.'}\n**Provas/Argumentos Réu:** {estado_simulacao['provas_reu_texto'] or 'Não detalhado.'}\n**Transcrição AIJ:** {historico_completo_dialogo}\n**Última Intervenção Réu:** \"{ultima_fala_reu}\"\n**Feedback Detalhado (Pontos Fortes, Melhorias, Sugestões, Fundamentação, Estratégia):**"
196
- return chamar_gemini_api(prompt_analise, temperature=0.65, max_output_tokens=1000)
197
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  def adicionar_fala_transcricao(estado_simulacao, ator, fala):
 
199
  estado_simulacao["transcricao_logica"].append((ator, fala))
200
  if ator == "Advogado do Réu (Você)": estado_simulacao["transcricao_chat"].append((fala, None))
201
  else:
@@ -205,6 +366,7 @@ def adicionar_fala_transcricao(estado_simulacao, ator, fala):
205
  return estado_simulacao
206
 
207
  def mostrar_botoes_corretos(fase_atual):
 
208
  vis = {
209
  "btn_responder_conciliacao": fase_atual == FASE_ABERTURA_CONCILIACAO,
210
  "btn_chamar_testemunha_reu": fase_atual == FASE_TESTEMUNHAS_REU_INICIO,
@@ -217,83 +379,147 @@ def mostrar_botoes_corretos(fase_atual):
217
  }
218
  return [gr.update(visible=vis[k]) for k in sorted(vis.keys())]
219
 
220
-
221
  def configurar_e_iniciar_simulacao(estado_s, fatos, p_reu, p_autor, t_reu_str, t_autor_str):
 
222
  novo_estado = estado_inicial_simulacao()
 
 
 
 
223
  novo_estado["caso_fatos"], novo_estado["provas_reu_texto"], novo_estado["provas_autor_supostas_texto"] = fatos, p_reu, p_autor
224
  def parse_testemunhas(t_str):
225
- return [{"nome": p[0].strip(), "pontos_chave": p[1].strip() if len(p) == 2 else "Não especificado."} for linha in t_str.strip().split('\n') if linha.strip() and (p := linha.split(':', 1))]
226
- novo_estado["testemunhas_reu_defs"], novo_estado["testemunhas_autor_supostas_defs"] = parse_testemunhas(t_reu_str), parse_testemunhas(t_autor_str)
 
 
 
 
 
 
 
 
 
 
 
 
227
  novo_estado["fase_aij"] = FASE_ABERTURA_CONCILIACAO
228
  novo_estado = adicionar_fala_transcricao(novo_estado, "Sistema", "Configuração salva. Iniciando simulação...")
 
229
  fala_juiz = gerar_resposta_juiz_ia(novo_estado)
230
  novo_estado = adicionar_fala_transcricao(novo_estado, "Juiz (IA)", fala_juiz)
231
  fala_adv_autor = gerar_resposta_advogado_autor_ia(novo_estado)
232
  novo_estado = adicionar_fala_transcricao(novo_estado, "Advogado do Autor (IA)", fala_adv_autor)
233
  novo_estado["instrucao_para_usuario"] = "Responda à proposta de conciliação do Autor ou declare sua posição."
234
  novo_estado["feedback_para_usuario"] = analisar_atuacao_defesa_ia(novo_estado)
235
- nomes_testemunhas_reu = [t["nome"] for t in novo_estado["testemunhas_reu_defs"]]
236
  botoes_vis = mostrar_botoes_corretos(novo_estado["fase_aij"])
237
- return [novo_estado, novo_estado["transcricao_chat"], novo_estado["feedback_para_usuario"], novo_estado["instrucao_para_usuario"], gr.Dropdown(choices=nomes_testemunhas_reu, value=None)] + botoes_vis
 
238
 
239
  def lidar_com_fala_usuario(estado_s, fala_usuario_txt):
 
240
  if not fala_usuario_txt and estado_s["fase_aij"] not in [FASE_TESTEMUNHAS_REU_INICIO]:
241
  estado_s["instrucao_para_usuario"] = "Por favor, digite sua fala ou selecione uma ação."
242
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"], gr.Textbox(value="")] + mostrar_botoes_corretos(estado_s["fase_aij"])
243
 
244
  estado_s = copy.deepcopy(estado_s)
245
  ator_usuario = "Advogado do Réu (Você)"
246
- if estado_s["fase_aij"] == FASE_TESTEMUNHAS_REU_PERGUNTAS_REU: ator_usuario = f"Advogado do Réu (Você) perguntando a {estado_s['testemunha_em_depoimento']['nome']}"
247
- elif estado_s["fase_aij"] == FASE_TESTEMUNHAS_REU_INQUIRICAO_AUTOR: ator_usuario = f"Testemunha {estado_s['testemunha_em_depoimento']['nome']} (Réu) respondendo"
248
- if fala_usuario_txt: estado_s = adicionar_fala_transcricao(estado_s, ator_usuario, fala_usuario_txt)
 
 
 
 
 
249
 
 
250
  if estado_s["fase_aij"] == FASE_ABERTURA_CONCILIACAO:
251
  fala_adv_autor = gerar_resposta_advogado_autor_ia(estado_s, fala_adv_reu=fala_usuario_txt)
252
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor)
253
  fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica="Partes se manifestaram sobre conciliação. Decida o prosseguimento.")
254
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
255
- if any(k in fala_juiz.lower() for k in ["testemunha", "instrução", "prossegu"]):
256
- if estado_s["testemunhas_autor_supostas_defs"]: estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_AUTOR_INICIO, "Aguarde Juiz/Adv.Autor chamarem testemunha."
257
- elif estado_s["testemunhas_reu_defs"]: estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_REU_INICIO, "Selecione sua testemunha."
258
- else: estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_AUTOR, "Aguarde Juiz iniciar Alegações Finais."
259
- else: estado_s["instrucao_para_usuario"] = "Responda ao Juiz ou Adv. Autor sobre conciliação."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  elif estado_s["fase_aij"] == FASE_TESTEMUNHAS_AUTOR_CONTRADITA_REU:
261
  fala_test_autor = gerar_resposta_testemunha_autor_ia(estado_s, pergunta_feita=fala_usuario_txt)
262
  estado_s = adicionar_fala_transcricao(estado_s, f"Testemunha {estado_s['testemunha_em_depoimento']['nome']} (Autor - IA)", fala_test_autor)
263
- estado_s["instrucao_para_usuario"] = f"Faça outra pergunta à testemunha {estado_s['testemunha_em_depoimento']['nome']} (Autor) ou aguarde Juiz."
264
- elif estado_s["fase_aij"] == FASE_TESTEMUNHAS_REU_PERGUNTAS_REU:
 
 
 
 
 
 
265
  estado_s["fase_aij"] = FASE_TESTEMUNHAS_REU_INQUIRICAO_AUTOR
266
- fala_adv_autor_ia = gerar_resposta_advogado_autor_ia(estado_s)
267
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor_ia)
268
- estado_s["instrucao_para_usuario"] = f"Responda (como {estado_s['testemunha_em_depoimento']['nome']}) à pergunta do Adv. Autor."
269
- elif estado_s["fase_aij"] == FASE_TESTEMUNHAS_REU_INQUIRICAO_AUTOR:
270
- fala_adv_autor_ia = gerar_resposta_advogado_autor_ia(estado_s, fala_adv_reu=fala_usuario_txt)
 
 
271
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor_ia)
272
- if "pergunta" in fala_adv_autor_ia.lower() or "?" in fala_adv_autor_ia: estado_s["instrucao_para_usuario"] = f"Responda (como {estado_s['testemunha_em_depoimento']['nome']}) à nova pergunta."
273
- else: estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_REU_PERGUNTAS_REU, f"Faça mais perguntas à {estado_s['testemunha_em_depoimento']['nome']} ou clique 'Juiz Avançar'."
 
 
 
 
 
 
274
  elif estado_s["fase_aij"] == FASE_ALEGACOES_FINAIS_REU:
275
- # estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Réu (Você)", fala_usuario_txt) # Já adicionado no início da função
276
  estado_s["fase_aij"] = FASE_ANALISE_FINAL_PROFESSOR
277
  fala_juiz = gerar_resposta_juiz_ia(estado_s)
278
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
279
- estado_s["instrucao_para_usuario"] = "Audiência encerrada. Veja feedback final."
280
-
 
281
  estado_s["feedback_para_usuario"] = analisar_atuacao_defesa_ia(estado_s, ultima_fala_reu=fala_usuario_txt if ator_usuario == "Advogado do Réu (Você)" else "")
 
282
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"], gr.Textbox(value="")] + mostrar_botoes_corretos(estado_s["fase_aij"])
283
 
284
  def acao_botao_juiz_avancar(estado_s):
 
285
  estado_s = copy.deepcopy(estado_s)
286
  fase_atual = estado_s["fase_aij"]
287
- acao_juiz_txt = "A parte solicitou o avanço ou encerramento da fase atual."
288
 
289
  if fase_atual == FASE_ABERTURA_CONCILIACAO:
290
- if estado_s["testemunhas_autor_supostas_defs"]: estado_s["fase_aij"], acao_juiz_txt = FASE_TESTEMUNHAS_AUTOR_INICIO, "Conciliação infrutífera. Inicie oitiva testemunhas Autor."
291
- elif estado_s["testemunhas_reu_defs"]: estado_s["fase_aij"], acao_juiz_txt = FASE_TESTEMUNHAS_REU_INICIO, "Sem testemunhas Autor. Inicie oitiva testemunhas Réu."
292
- else: estado_s["fase_aij"], acao_juiz_txt = FASE_ALEGACOES_FINAIS_AUTOR, "Sem testemunhas. Prossiga alegações finais Autor."
293
- fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica=acao_juiz_txt) # Juiz comanda nova fase
294
- estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
295
- if estado_s["fase_aij"] == FASE_TESTEMUNHAS_AUTOR_INICIO: # Se for para testemunha do autor, adv autor precisa agir
296
- fala_adv_autor = gerar_resposta_advogado_autor_ia(estado_s)
297
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor)
298
  if not ("Não tenho mais testemunhas" in fala_adv_autor or "Não arrolei testemunhas" in fala_adv_autor):
299
  estado_s["testemunha_autor_atual_idx"] += 1
@@ -301,164 +527,462 @@ def acao_botao_juiz_avancar(estado_s):
301
  if idx < len(estado_s["testemunhas_autor_supostas_defs"]):
302
  t_info = estado_s["testemunhas_autor_supostas_defs"][idx]
303
  estado_s["testemunha_em_depoimento"] = {"nome": t_info["nome"], "pontos_chave": t_info["pontos_chave"], "parte": "AUTOR"}
304
- fala_test_autor = gerar_resposta_testemunha_autor_ia(estado_s, pergunta_feita=fala_adv_autor)
305
  estado_s = adicionar_fala_transcricao(estado_s, f"Testemunha {t_info['nome']} (Autor - IA)", fala_test_autor)
306
- estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_AUTOR_CONTRADITA_REU, f"Contradite {t_info['nome']} (Autor)."
307
- # Se adv autor não tem testemunhas, a lógica de transição já teria ido para o réu ou alegações
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  elif fase_atual == FASE_TESTEMUNHAS_AUTOR_INICIO or fase_atual == FASE_TESTEMUNHAS_AUTOR_PERGUNTAS_AUTOR:
309
- fala_juiz = gerar_resposta_juiz_ia(estado_s)
 
310
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
311
- fala_adv_autor = gerar_resposta_advogado_autor_ia(estado_s)
312
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor)
313
- if "Não tenho mais testemunhas" in fala_adv_autor or "Não arrolei testemunhas" in fala_adv_autor:
314
- if estado_s["testemunhas_reu_defs"]: estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_REU_INICIO, "Selecione sua testemunha."
315
- else: estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_AUTOR, "Aguarde Juiz iniciar Alegações Finais."
316
- fala_juiz_trans = gerar_resposta_juiz_ia(estado_s) # Juiz anuncia a nova fase
317
- estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz_trans)
318
- else:
319
- estado_s["testemunha_autor_atual_idx"] += 1; idx = estado_s["testemunha_autor_atual_idx"]
 
 
 
 
 
 
 
 
 
 
 
 
320
  if idx < len(estado_s["testemunhas_autor_supostas_defs"]):
321
  t_info = estado_s["testemunhas_autor_supostas_defs"][idx]
322
  estado_s["testemunha_em_depoimento"] = {"nome": t_info["nome"], "pontos_chave": t_info["pontos_chave"], "parte": "AUTOR"}
323
- fala_test_autor = gerar_resposta_testemunha_autor_ia(estado_s, pergunta_feita=fala_adv_autor)
324
  estado_s = adicionar_fala_transcricao(estado_s, f"Testemunha {t_info['nome']} (Autor - IA)", fala_test_autor)
325
- estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_AUTOR_CONTRADITA_REU, f"Contradite {t_info['nome']} (Autor)."
 
 
 
 
326
  elif fase_atual == FASE_TESTEMUNHAS_AUTOR_CONTRADITA_REU:
 
327
  estado_s["testemunha_em_depoimento"] = None
328
- acao_juiz_txt = "Adv. Réu encerrou contradita test. Autor. Verifique mais test. Autor ou prossiga."
329
- fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica=acao_juiz_txt)
330
- estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
331
  if estado_s["testemunha_autor_atual_idx"] + 1 < len(estado_s["testemunhas_autor_supostas_defs"]):
332
- estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_AUTOR_INICIO, "Aguarde Juiz/Adv.Autor chamarem próxima test. Autor."
 
 
333
  # Adv Autor precisa ser chamado para agir
334
  fala_adv_autor = gerar_resposta_advogado_autor_ia(estado_s) # Adv Autor chama/pergunta
335
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor)
336
  if not ("Não tenho mais testemunhas" in fala_adv_autor or "Não arrolei testemunhas" in fala_adv_autor):
337
- estado_s["testemunha_autor_atual_idx"] += 1; idx_new = estado_s["testemunha_autor_atual_idx"]
 
338
  if idx_new < len(estado_s["testemunhas_autor_supostas_defs"]):
339
  t_info_new = estado_s["testemunhas_autor_supostas_defs"][idx_new]
340
  estado_s["testemunha_em_depoimento"] = {"nome": t_info_new["nome"], "pontos_chave": t_info_new["pontos_chave"], "parte": "AUTOR"}
341
  fala_test_autor_new = gerar_resposta_testemunha_autor_ia(estado_s, pergunta_feita=fala_adv_autor)
342
  estado_s = adicionar_fala_transcricao(estado_s, f"Testemunha {t_info_new['nome']} (Autor - IA)", fala_test_autor_new)
343
- estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_AUTOR_CONTRADITA_REU, f"Contradite {t_info_new['nome']} (Autor)."
344
-
345
- elif estado_s["testemunhas_reu_defs"]: estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_REU_INICIO, "Selecione sua testemunha."
346
- else: estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_AUTOR, "Aguarde Juiz iniciar Alegações Finais."
347
- if fase_atual != estado_s["fase_aij"]: # Se mudou de fase principal, juiz anuncia
348
- fala_juiz_trans = gerar_resposta_juiz_ia(estado_s)
349
- estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz_trans)
350
- if estado_s["fase_aij"] == FASE_ALEGACOES_FINAIS_AUTOR: # Se for para alegações do autor
351
- fala_aleg_autor = gerar_resposta_advogado_autor_ia(estado_s)
 
 
 
 
 
 
 
 
 
 
 
 
 
352
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_aleg_autor)
353
  estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_REU, "Apresente suas Alegações Finais."
354
 
355
  elif fase_atual in [FASE_TESTEMUNHAS_REU_PERGUNTAS_REU, FASE_TESTEMUNHAS_REU_INQUIRICAO_AUTOR]:
 
 
356
  estado_s["testemunha_em_depoimento"] = None
357
- acao_juiz_txt = "Adv. Réu encerrou oitiva de sua testemunha. Verifique mais test. Réu ou Alegações Finais."
358
- fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica=acao_juiz_txt)
359
- estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
360
- if estado_s["testemunha_reu_atual_idx"] + 1 < len(estado_s["testemunhas_reu_defs"]): estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_REU_INICIO, "Selecione sua próxima testemunha."
361
- else:
362
- estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_AUTOR, "Aguarde Juiz iniciar Alegações Finais."
363
- fala_juiz_trans = gerar_resposta_juiz_ia(estado_s)
364
- estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz_trans)
365
- fala_adv_autor = gerar_resposta_advogado_autor_ia(estado_s)
 
 
 
 
 
366
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor)
367
  estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_REU, "Apresente suas Alegações Finais."
 
368
  elif fase_atual == FASE_ALEGACOES_FINAIS_AUTOR:
369
- estado_s["fase_aij"], acao_juiz_txt = FASE_ALEGACOES_FINAIS_REU, "Adv. Autor concluiu. Passe palavra ao Adv. Réu."
370
- fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica=acao_juiz_txt)
 
371
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
372
  estado_s["instrucao_para_usuario"] = "Apresente suas Alegações Finais."
373
- else:
374
- fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica="Conduza para próxima etapa.")
375
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
376
- estado_s["instrucao_para_usuario"] = "Siga instruções do Juiz."
377
 
378
  estado_s["feedback_para_usuario"] = analisar_atuacao_defesa_ia(estado_s)
 
379
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"]] + mostrar_botoes_corretos(estado_s["fase_aij"])
380
 
381
  def chamar_testemunha_reu_selecionada(estado_s, nome_testemunha_selecionada):
 
382
  estado_s = copy.deepcopy(estado_s)
383
  if not nome_testemunha_selecionada:
384
- estado_s["instrucao_para_usuario"] = "Selecione uma testemunha."
 
385
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"]] + mostrar_botoes_corretos(estado_s["fase_aij"])
 
386
  idx_testemunha = next((i for i, t in enumerate(estado_s["testemunhas_reu_defs"]) if t["nome"] == nome_testemunha_selecionada), -1)
387
  if idx_testemunha == -1:
388
- estado_s["instrucao_para_usuario"] = f"Testemunha '{nome_testemunha_selecionada}' não encontrada."
 
389
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"]] + mostrar_botoes_corretos(estado_s["fase_aij"])
390
 
391
  estado_s["testemunha_reu_atual_idx"] = idx_testemunha
392
  testemunha_obj = estado_s["testemunhas_reu_defs"][idx_testemunha]
393
  estado_s["testemunha_em_depoimento"] = {"nome": testemunha_obj["nome"], "pontos_chave": testemunha_obj["pontos_chave"], "parte": "REU"}
394
- estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Réu (Você)", f"Chamo para depor minha testemunha, Sra./Sr. {testemunha_obj['nome']}.")
395
- fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica=f"Adv. Réu chamou {testemunha_obj['nome']}. Qualifique e passe palavra para inquirição.")
 
 
396
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
397
- estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_REU_PERGUNTAS_REU, f"Pergunte à sua testemunha {testemunha_obj['nome']}. Digite PERGUNTA e RESPOSTA."
 
398
  estado_s["feedback_para_usuario"] = analisar_atuacao_defesa_ia(estado_s)
 
399
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"]] + mostrar_botoes_corretos(estado_s["fase_aij"])
400
 
401
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="orange"), title="Simulador AIJ") as demo:
402
- gr.Markdown("# ⚖️ Simulador de Audiência de Instrução e Julgamento (AIJ)")
403
- gr.Markdown("Tema: **Direito ao Esquecimento vs. Liberdade de Imprensa**. Você é **Advogado(a) do Réu (Jornal)**.")
404
- if not GEMINI_API_KEY: gr.Warning("API Key do Gemini não encontrada! Configure o Secret 'GEMINI_API_KEY' nas configurações deste Space.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
  sim_state = gr.State(value=estado_inicial_simulacao())
406
 
407
  with gr.Tabs() as abas_principais:
408
- with gr.TabItem("1. Configuração", id=0):
409
- gr.Markdown("## Detalhes do Caso")
410
- btn_gerar_caso_ia = gr.Button(" Gerar Caso Fictício com IA (Experimental)", icon="🧠")
 
 
 
411
  with gr.Row():
412
  with gr.Column(scale=2):
413
- fatos_input = gr.Textbox(lines=7, label="Resumo dos Fatos:", placeholder="Descreva ou gere com IA.")
414
- provas_reu_input = gr.Textbox(lines=4, label="Provas/Argumentos do Réu (Seu Grupo):")
415
- provas_autor_input = gr.Textbox(lines=4, label="Provas/Argumentos (Supostos) do Autor:")
416
  with gr.Column(scale=1):
417
- testemunhas_reu_input = gr.Textbox(lines=5, label="Suas Testemunhas (Réu) - Nome: Pontos Chave", placeholder="João Silva: Viu X.\nMaria Costa: Sabe Y.")
418
- testemunhas_autor_supostas_input = gr.Textbox(lines=5, label="Supostas Testemunhas do Autor - Nome: Pontos Chave", placeholder="Carlos Lima: Sofreu Z.\nAna B.: Irrelevante.")
419
- btn_config_iniciar = gr.Button("💾 Salvar e Iniciar Simulação", variant="primary")
420
- status_config_output = gr.Label(value="Aguardando configuração...")
421
- with gr.TabItem("2. Audiência", id=1):
422
- gr.Markdown("## Andamento")
423
- instrucao_usuario_output = gr.Markdown("Instrução: Preencha a configuração para começar.")
424
- chat_aij_output = gr.Chatbot(label="Transcrição", height=450, bubble_full_width=False, show_copy_button=True)
425
- fala_usuario_input = gr.Textbox(show_label=False, placeholder="Sua fala ou use botões...", scale=4, lines=3)
 
 
 
 
 
426
  btn_enviar_fala_usuario = gr.Button("🎤 Enviar Fala / Ação", variant="stop")
427
- with gr.Accordion("Ações Contextuais (Adv. Réu)", open=False):
 
 
 
 
 
428
  with gr.Row():
429
- btn_responder_conciliacao = gr.Button("Conciliação", visible=False)
430
- dropdown_testemunhas_reu_select = gr.Dropdown(label="Sua Testemunha", choices=[], visible=False)
431
- btn_chamar_testemunha_reu_action = gr.Button("Chamar Testemunha", visible=False)
432
- btn_perguntar_testemunha_autor_action = gr.Button("Perguntar Test. Autor", visible=False)
433
- btn_adv_reu_pergunta_sua_testemunha_action = gr.Button("Perguntar Minha Test.", visible=False)
434
- btn_adv_reu_responde_pela_sua_testemunha_action = gr.Button("Responder por Minha Test.", visible=False)
435
- btn_apresentar_alegacoes_finais_reu_action = gr.Button("Alegações Finais", visible=False)
436
- btn_juiz_avancar_fase_action = gr.Button("⚖️ Juiz (IA): Avançar", visible=False, variant="secondary")
437
  lista_botoes_feedback = [btn_responder_conciliacao, btn_chamar_testemunha_reu_action, dropdown_testemunhas_reu_select, btn_perguntar_testemunha_autor_action, btn_adv_reu_pergunta_sua_testemunha_action, btn_adv_reu_responde_pela_sua_testemunha_action, btn_apresentar_alegacoes_finais_reu_action, btn_juiz_avancar_fase_action]
438
- with gr.TabItem("3. Feedback IA", id=2):
439
- gr.Markdown("## 💡 Análise (Professor IA)")
440
- feedback_output = gr.Textbox(lines=15, label="Feedback sobre sua atuação:", interactive=False, show_copy_button=True)
441
 
442
- outputs_gerar_caso = [fatos_input, provas_reu_input, provas_autor_input, testemunhas_reu_input, testemunhas_autor_supostas_input, status_config_output]
443
- btn_gerar_caso_ia.click(acao_gerar_caso_ficticio_ui, inputs=None, outputs=outputs_gerar_caso)
 
 
444
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  outputs_config = [sim_state, chat_aij_output, feedback_output, instrucao_usuario_output, dropdown_testemunhas_reu_select] + lista_botoes_feedback
446
- btn_config_iniciar.click(configurar_e_iniciar_simulacao, inputs=[sim_state, fatos_input, provas_reu_input, provas_autor_input, testemunhas_reu_input, testemunhas_autor_supostas_input], outputs=outputs_config).then(lambda: gr.Textbox(value=""), outputs=[fala_usuario_input]).then(lambda: gr.Tabs(selected=1), outputs=[abas_principais])
 
 
 
 
 
447
 
448
  outputs_fala_usuario = [sim_state, chat_aij_output, feedback_output, instrucao_usuario_output, fala_usuario_input] + lista_botoes_feedback
449
  btn_enviar_fala_usuario.click(lidar_com_fala_usuario, inputs=[sim_state, fala_usuario_input], outputs=outputs_fala_usuario)
450
  fala_usuario_input.submit(lidar_com_fala_usuario, inputs=[sim_state, fala_usuario_input], outputs=outputs_fala_usuario)
451
-
452
  outputs_acao_juiz = [sim_state, chat_aij_output, feedback_output, instrucao_usuario_output] + lista_botoes_feedback
453
  btn_juiz_avancar_fase_action.click(acao_botao_juiz_avancar, inputs=[sim_state], outputs=outputs_acao_juiz).then(lambda: gr.Textbox(value=""), outputs=[fala_usuario_input])
454
  btn_chamar_testemunha_reu_action.click(chamar_testemunha_reu_selecionada, inputs=[sim_state, dropdown_testemunhas_reu_select], outputs=outputs_acao_juiz).then(lambda: gr.Textbox(value=""), outputs=[fala_usuario_input])
455
 
456
- # Links dos botões restantes para lidar_com_fala_usuario
457
- for btn in [btn_responder_conciliacao, btn_perguntar_testemunha_autor_action, btn_adv_reu_pergunta_sua_testemunha_action, btn_adv_reu_responde_pela_sua_testemunha_action, btn_apresentar_alegacoes_finais_reu_action]:
458
- btn.click(lidar_com_fala_usuario, inputs=[sim_state, fala_usuario_input], outputs=outputs_fala_usuario)
459
-
460
- def setup_initial_ui_state(s): return [gr.Dropdown(choices=[], value=None)] + mostrar_botoes_corretos(s["fase_aij"])
461
- demo.load(lambda s: (s, s["transcricao_chat"], s["feedback_para_usuario"], s["instrucao_para_usuario"]) + tuple(setup_initial_ui_state(s)), inputs=[sim_state], outputs=[sim_state, chat_aij_output, feedback_output, instrucao_usuario_output, dropdown_testemunhas_reu_select] + lista_botoes_feedback)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
462
 
463
  if __name__ == "__main__":
464
  if not GEMINI_API_KEY:
@@ -467,4 +991,4 @@ if __name__ == "__main__":
467
  print("Para rodar localmente, edite o script e insira sua chave ou defina a variável de ambiente.")
468
  print("Para Hugging Face Spaces, configure o Secret 'GEMINI_API_KEY'.")
469
  print("#####################################################################")
470
- demo.queue().launch()
 
4
  import os
5
  import copy
6
 
7
+ # --- Configuration from Script 1 & 2 (merged) ---
8
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
9
  if not GEMINI_API_KEY:
10
  print("ALERTA: GEMINI_API_KEY não encontrada como Secret no Hugging Face Space. O app não funcionará.")
11
  # Para teste local, descomente e cole sua chave, mas NÃO FAÇA COMMIT DISSO COM A CHAVE.
12
  # GEMINI_API_KEY = "SUA_CHAVE_AQUI_PARA_TESTE_LOCAL_APENAS"
13
 
14
+ MODEL_NAME = "gemini-1.5-flash-latest" # Consistent model name
 
15
  API_URL_BASE = f"https://generativelanguage.googleapis.com/v1beta/models/{MODEL_NAME}:generateContent"
16
 
17
+ # --- Fases da AIJ (from Script 1) ---
18
  FASE_INICIAL_CONFIG = "CONFIGURACAO"
19
  FASE_ABERTURA_CONCILIACAO = "ABERTURA_E_CONCILIACAO"
20
  FASE_TESTEMUNHAS_AUTOR_INICIO = "TESTEMUNHAS_AUTOR_INICIO"
 
28
  FASE_ANALISE_FINAL_PROFESSOR = "ANALISE_FINAL_PROFESSOR"
29
  FASE_CONCLUIDA = "AIJ_CONCLUIDA"
30
 
31
+ # --- Predefined Case Data (from Script 2, adapted for Script 1 structure) ---
32
+ CASO_TITULO_PREDEFINIDO = "O Caso da Reportagem Revisitada"
33
+ CASO_PARTES_PREDEFINIDO = "Autor: Carlos Alberto Mendes\nRéu: Jornal 'A Verdade Diária'"
34
+ CASO_DESCRICAO_PREDEFINIDO = """
35
+ Uma pessoa (Carlos Alberto Mendes) processou um jornal (A Verdade Diária) alegando violação do direito ao esquecimento.
36
+ O jornal publicou uma matéria relembrando um crime ocorrido há 15 anos, no qual o autor foi
37
+ acusado de fraude, mas posteriormente absolvido por falta de provas. A matéria original foi publicada na época dos fatos
38
+ e a nova matéria, parte de uma série "Crimes que Marcaram a Cidade", revisitou o caso, mencionando a absolvição.
39
+
40
+ O autor alega que a republicação da história, mesmo com a menção da absolvição, causou-lhe
41
+ constrangimentos sociais, dificuldades em obter novo emprego e reacendeu traumas passados,
42
+ afetando sua vida familiar. Ele requer a remoção da matéria do site do jornal e uma indenização
43
+ por danos morais.
44
+
45
+ O jornal (réu) defende a liberdade de imprensa e o direito à informação, argumentando que
46
+ a matéria tem interesse público histórico, é factualmente correta (inclusive quanto à absolvição)
47
+ e faz parte do acervo jornalístico que documenta a história da comunidade.
48
+ """
49
+ CASO_FATOS_COMPLETO_PREDEFINIDO = f"Título: {CASO_TITULO_PREDEFINIDO}\nPartes:\n{CASO_PARTES_PREDEFINIDO}\n\n---INÍCIO DOS FATOS---\n{CASO_DESCRICAO_PREDEFINIDO.strip()}"
50
+
51
+ ARGUMENTOS_AUTOR_PREDEFINIDOS = [
52
+ "Argumento: A matéria publicada reabriu feridas do passado e causou danos psicológicos e sociais ao autor. Prova: Laudo psicológico atestando abalo emocional e depoimentos sobre constrangimento social.",
53
+ "Argumento: O autor já foi absolvido judicialmente e tem direito a reconstruir sua vida sem o estigma do passado. Prova: Cópia da sentença absolutória.",
54
+ "Argumento: O tempo transcorrido (15 anos) torna o caso desatualizado e sem relevância pública atual que justifique a exposição. Prova: Irrelevância pública atual, foco no dano individual.",
55
+ "Argumento: A publicação violou o direito à privacidade e à honra do autor. Prova: Doutrina e jurisprudência sobre direitos da personalidade."
56
+ ]
57
+ PROVAS_AUTOR_SUPPOSTAS_TEXTO_PREDEFINIDO = "\n".join(ARGUMENTOS_AUTOR_PREDEFINIDOS)
58
+
59
+ CONTRA_ARGUMENTOS_REU_PREDEFINIDOS = [
60
+ "Argumento: A liberdade de imprensa é um direito fundamental e a matéria é de interesse público histórico. Prova: Art. 5º, IX e XIV da CF/88; Doutrina sobre liberdade de imprensa.",
61
+ "Argumento: A matéria baseia-se inteiramente em informações verídicas e de acesso público (processo judicial). Prova: Cópia da matéria original e da recente, certidão do processo.",
62
+ "Argumento: O STF (RE 1.010.606) não reconheceu o direito ao esquecimento de forma absoluta, ponderando-o com a liberdade de informação. Prova: Inteiro teor do acórdão do RE 1.010.606.",
63
+ "Argumento: A matéria destacou a absolvição do autor, não havendo intenção de difamar. Prova: Conteúdo da própria matéria."
64
+ ]
65
+ PROVAS_REU_TEXTO_PREDEFINIDO = "\n".join(CONTRA_ARGUMENTOS_REU_PREDEFINIDOS)
66
+
67
+ TESTEMUNHAS_REU_PREDEFINIDAS = [
68
+ {"nome": "João Silva", "pontos_chave": "Editor-chefe do jornal. Confirmará o processo editorial, o interesse público da série de reportagens e a ausência de intenção de prejudicar o autor."},
69
+ {"nome": "Dra. Maria Santos", "pontos_chave": "Historiadora local. Atestará a relevância histórica do caso para a comunidade e a importância de preservar a memória de tais eventos."},
70
+ {"nome": "Roberto Almeida", "pontos_chave": "Jornalista responsável pela matéria. Detalhará a pesquisa, a verificação dos fatos e a menção explícita à absolvição do autor."}
71
+ ]
72
+ TESTEMUNHAS_REU_TEXTO_PREDEFINIDO = "\n".join([f"{t['nome']}: {t['pontos_chave']}" for t in TESTEMUNHAS_REU_PREDEFINIDAS])
73
+
74
+ # Para o caso padrão, precisamos de testemunhas do autor também.
75
+ TESTEMUNHAS_AUTOR_SUPPOSTAS_PREDEFINIDAS_TEXTO = """
76
+ Dr. Felipe Antunes: Psicólogo do autor. Relatará o impacto emocional da nova reportagem na vida do autor.
77
+ Sra. Clara Dias: Vizinha do autor. Comentará sobre as mudanças no tratamento social que o autor recebeu após a reportagem.
78
+ """
79
+
80
+ LEGISLACAO_PRECEDENTES_PREDEFINIDO = {
81
+ "favoraveis_ao_reu": [
82
+ "Art. 5º, IV, IX e XIV da Constituição Federal - garantia da liberdade de expressão e acesso à informação",
83
+ "ADPF 130 (STF) - declarou a Lei de Imprensa incompatível com a ordem constitucional atual",
84
+ "RE 1.010.606 (STF) - não reconheceu o direito ao esquecimento na esfera civil de forma irrestrita",
85
+ "Pacto de San José da Costa Rica - proteção à liberdade de expressão",
86
+ ],
87
+ "favoraveis_ao_autor": [
88
+ "Art. 5º, X da Constituição Federal - inviolabilidade da intimidade, vida privada e honra",
89
+ "Art. 21 do Código Civil - proteção à vida privada",
90
+ "Enunciado 531 da VI Jornada de Direito Civil - reconhece o direito ao esquecimento",
91
+ "LGPD (Lei Geral de Proteção de Dados) - embora não diretamente, reforça a proteção a dados pessoais."
92
+ ]
93
+ }
94
+
95
+ # --- Funções de Estado e API (from Script 1) ---
96
  def estado_inicial_simulacao():
97
  return {
98
  "fase_aij": FASE_INICIAL_CONFIG, "caso_fatos": "", "provas_reu_texto": "",
 
101
  "testemunha_reu_atual_idx": -1, "testemunha_em_depoimento": None,
102
  "transcricao_chat": [], "transcricao_logica": [],
103
  "feedback_para_usuario": "Aguardando início da simulação.",
104
+ "instrucao_para_usuario": "Configure os detalhes do caso na aba 'Configuração' ou carregue o caso padrão."
105
  }
106
 
107
  def chamar_gemini_api(prompt_text, temperature=0.7, max_output_tokens=800):
 
121
  ]
122
  }
123
  try:
124
+ response = requests.post(api_url_com_chave, headers=headers, data=json.dumps(data), timeout=180) # Increased timeout
125
  response.raise_for_status()
126
  response_json = response.json()
127
  if response_json.get("candidates") and response_json["candidates"][0].get("content"):
 
129
  elif response_json.get("promptFeedback") and response_json["promptFeedback"].get("blockReason"):
130
  return f"ERRO_API: Conteúdo bloqueado. Razão: {response_json['promptFeedback']['blockReason']}"
131
  return "ERRO_API: Resposta inesperada da API."
132
+ except requests.exceptions.Timeout:
133
+ return "ERRO_CONEXAO: Timeout ao chamar a API Gemini. Tente novamente."
134
  except requests.exceptions.RequestException as e:
135
  error_msg = f"ERRO_CONEXAO: {e}"
136
  if e.response is not None:
 
148
  historico_formatado += f"- {ator}: {fala}\n"
149
  return historico_formatado
150
 
151
+ # --- Funções de Geração de Conteúdo IA (from Script 1, some new) ---
152
  def gerar_caso_ficticio_com_ia():
153
+ # (Função mantida como no Script 1 original)
154
  prompt_geracao_caso = """
155
  **Instrução de Persona:** Você é um roteirista jurídico criativo e experiente, especializado em criar casos simulados realistas para treinamento de advogados.
156
  **Tarefa:** Crie um caso fictício detalhado para uma simulação de Audiência de Instrução e Julgamento (AIJ) sobre o tema "Direito ao Esquecimento vs. Liberdade de Imprensa".
 
172
  `## Testemunhas Hipotéticas da Parte RÉ`
173
  O conteúdo de cada seção deve vir após o marcador. Para Argumentos/Provas e Testemunhas, liste cada item em uma nova linha.
174
  """
175
+ texto_caso_completo = chamar_gemini_api(prompt_geracao_caso, temperature=0.75, max_output_tokens=2500) # Increased tokens
176
  if "ERRO_" in texto_caso_completo:
177
  return {"fatos": f"Falha ao gerar caso com IA: {texto_caso_completo}", "provas_autor": "", "provas_reu": "", "testemunhas_autor": "", "testemunhas_reu": ""}
178
  return parse_caso_gerado(texto_caso_completo)
179
 
180
  def parse_caso_gerado(texto_completo_caso):
181
+ # (Função mantida como no Script 1 original)
182
  dados_caso = {"fatos": "Falha parsing: Fatos", "provas_autor": "Falha parsing: Provas Autor", "provas_reu": "Falha parsing: Provas Réu", "testemunhas_autor": "Falha parsing: Testemunhas Autor", "testemunhas_reu": "Falha parsing: Testemunhas Réu"}
183
  secoes = {"fatos": "## Resumo Detalhado dos Fatos", "provas_autor": "## Argumentos e \"Provas\" Hipotéticas da Parte AUTORA", "provas_reu": "## Argumentos e \"Provas\" Hipotéticas da Parte RÉ (Jornal)", "testemunhas_autor": "## Testemunhas Hipotéticas da Parte AUTORA", "testemunhas_reu": "## Testemunhas Hipotéticas da Parte RÉ"}
184
  fatos_prefix = ""
 
206
  dados_caso[chave_atual] = fatos_prefix + conteudo_secao if chave_atual == "fatos" and fatos_prefix else conteudo_secao
207
  current_pos = fim_conteudo
208
  for key_testemunha in ["testemunhas_autor", "testemunhas_reu"]:
209
+ if "Falha no parsing" not in dados_caso[key_testemunha] and dados_caso[key_testemunha]: # Check if not empty
210
  linhas = dados_caso[key_testemunha].split('\n')
211
+ linhas_formatadas = []
212
+ for linha in linhas:
213
+ if linha.strip():
214
+ partes = linha.split(':', 1)
215
+ if len(partes) == 2:
216
+ linhas_formatadas.append(f"{partes[0].strip()}: {partes[1].strip()}")
217
+ else:
218
+ linhas_formatadas.append(partes[0].strip()) # Handle lines without colon if necessary
219
  dados_caso[key_testemunha] = "\n".join(linhas_formatadas)
220
  return dados_caso
221
 
 
224
  dados_gerados = gerar_caso_ficticio_com_ia()
225
  return [dados_gerados["fatos"], dados_gerados["provas_reu"], dados_gerados["provas_autor"], dados_gerados["testemunhas_reu"], dados_gerados["testemunhas_autor"], "Caso fictício gerado. Revise e salve."]
226
 
227
+ def acao_carregar_caso_padrao_ui():
228
+ gr.Info("Carregando caso padrão...")
229
+ return [
230
+ CASO_FATOS_COMPLETO_PREDEFINIDO,
231
+ PROVAS_REU_TEXTO_PREDEFINIDO,
232
+ PROVAS_AUTOR_SUPPOSTAS_TEXTO_PREDEFINIDO,
233
+ TESTEMUNHAS_REU_TEXTO_PREDEFINIDO,
234
+ TESTEMUNHAS_AUTOR_SUPPOSTAS_PREDEFINIDAS_TEXTO,
235
+ "Caso padrão carregado. Revise e salve."
236
+ ]
237
+
238
  def gerar_resposta_juiz_ia(estado_simulacao, acao_especifica=""):
239
+ # (Função mantida como no Script 1 original)
240
  fase = estado_simulacao["fase_aij"]
241
  historico = formatar_historico_para_prompt(estado_simulacao["transcricao_logica"])
242
  prompt = f"**Persona:** Juiz(a) experiente em AIJ (Direito Esquecimento vs Liberdade Imprensa).\n**Fatos:** {estado_simulacao['caso_fatos'] or 'Não detalhado.'}\n{historico}**Fase Atual:** {fase}\n"
 
248
  elif fase == FASE_ANALISE_FINAL_PROFESSOR: prompt += "**Tarefa:** Declare audiência encerrada para julgamento (simulado)."
249
  else: prompt += f"**Tarefa:** Conduza a audiência. Ação específica: {acao_especifica or 'Nenhuma'}. Mantenha ordem e fluxo."
250
  prompt += "\n**Sua Fala (Juiz):**"
251
+ return chamar_gemini_api(prompt, temperature=0.6, max_output_tokens=300)
252
 
253
  def gerar_resposta_advogado_autor_ia(estado_simulacao, fala_adv_reu=""):
254
+ # (Função mantida como no Script 1 original)
255
  fase = estado_simulacao["fase_aij"]
256
  historico = formatar_historico_para_prompt(estado_simulacao["transcricao_logica"])
257
  prompt = f"**Persona:** Advogado(a) do AUTOR em AIJ (Direito Esquecimento vs Liberdade Imprensa). Cliente busca esquecimento/reparação.\n**Réu:** Jornal.\n**Fatos:** {estado_simulacao['caso_fatos'] or 'Não detalhado.'}\n**Provas/Argumentos Autor:** {estado_simulacao['provas_autor_supostas_texto'] or 'Passagem tempo, desinteresse público, dano vida privada.'}\n{historico}**Fase Atual:** {fase}\n"
 
272
  elif fase == FASE_ALEGACOES_FINAIS_AUTOR: prompt += "**Tarefa:** Juiz concedeu palavra para alegações finais. Apresente resumo persuasivo e reitere pedidos."
273
  else: prompt += f"**Contexto:** Adv. Réu (Usuário) disse: \"{fala_adv_reu}\"\n**Tarefa:** Responda estrategicamente."
274
  prompt += "\n**Sua Resposta (Advogado Autor):**"
275
+ return chamar_gemini_api(prompt, temperature=0.75, max_output_tokens=450)
276
 
277
  def gerar_resposta_testemunha_autor_ia(estado_simulacao, pergunta_feita):
278
+ # (Função mantida como no Script 1 original)
279
  testemunha_obj = estado_simulacao.get("testemunha_em_depoimento")
280
  if not testemunha_obj or testemunha_obj["parte"] != "AUTOR": return "Testemunha do Autor (IA): (Erro interno - Nenhuma testemunha do autor em depoimento)"
281
  historico = formatar_historico_para_prompt(estado_simulacao["transcricao_logica"])
282
  prompt = f"**Persona:** Testemunha {testemunha_obj['nome']} (AUTOR).\n**Caso:** Direito Esquecimento vs Liberdade Imprensa.\n**Fatos:** {estado_simulacao['caso_fatos'] or 'Não detalhado.'}\n**Seus Pontos Chave:** {testemunha_obj['pontos_chave'] or 'Conhecimento geral sobre autor e impactos.'}\n{historico}**Pergunta Feita:** \"{pergunta_feita}\"\n**Tarefa:** Responda claro, conciso, baseado nos seus pontos. Se Adv. Réu, seja cauteloso(a).\n**Sua Resposta (Testemunha {testemunha_obj['nome']}):**"
283
+ return chamar_gemini_api(prompt, temperature=0.6, max_output_tokens=250)
284
 
285
  def analisar_atuacao_defesa_ia(estado_simulacao, ultima_fala_reu=""):
286
+ # (Função mantida como no Script 1 original)
287
  historico_completo_dialogo = formatar_historico_para_prompt(estado_simulacao["transcricao_logica"], max_turns=len(estado_simulacao["transcricao_logica"]))
288
  prompt_analise = f"**Persona:** Professor(a) de Prática Jurídica experiente.\n**Tarefa:** Feedback construtivo para aluno (Adv. RÉU - Jornal) em AIJ (Direito Esquecimento vs Liberdade Imprensa).\n**Fatos:** {estado_simulacao['caso_fatos'] or 'Não detalhado.'}\n**Provas/Argumentos Réu:** {estado_simulacao['provas_reu_texto'] or 'Não detalhado.'}\n**Transcrição AIJ:** {historico_completo_dialogo}\n**Última Intervenção Réu:** \"{ultima_fala_reu}\"\n**Feedback Detalhado (Pontos Fortes, Melhorias, Sugestões, Fundamentação, Estratégia):**"
289
+ return chamar_gemini_api(prompt_analise, temperature=0.65, max_output_tokens=1200)
290
+
291
+ # --- Novas Funções de IA para Treinamento (inspiradas em Script 2) ---
292
+ def avaliar_argumentos_defesa_ia(fatos_caso, provas_reu, tipo_argumento, argumento_usuario):
293
+ if not argumento_usuario.strip():
294
+ return "Por favor, insira seus argumentos para avaliação."
295
+
296
+ contexto_caso = f"""
297
+ Você está avaliando argumentos no contexto de um caso jurídico no Brasil sobre direito ao esquecimento vs. liberdade de imprensa.
298
+ O usuário representa a defesa (jornal).
299
+ **Fatos do Caso:** {fatos_caso if fatos_caso else CASO_DESCRICAO_PREDEFINIDO}
300
+ **Principais Argumentos/Provas da Defesa (Jornal):** {provas_reu if provas_reu else "\n".join(CONTRA_ARGUMENTOS_REU_PREDEFINIDOS)}
301
+ """
302
+ prompt = f"""
303
+ {contexto_caso}
304
+
305
+ **Persona:** Você é um Juiz experiente em um tribunal brasileiro, com especialidade em casos de liberdade de imprensa e direitos da personalidade.
306
+ **Tarefa:** Avalie o seguinte argumento apresentado pelo advogado de defesa (jornal) para a peça/momento processual: "{tipo_argumento}".
307
+ Forneça feedback detalhado e construtivo em português brasileiro, incluindo:
308
+ 1. **Pontos Fortes:** Destaque aspectos positivos (ex: fundamentação legal sólida, coerência lógica, clareza, persuasão, uso de fatos).
309
+ 2. **Pontos a Melhorar:** Identifique fraquezas (ex: falta de aprofundamento, generalizações, omissão de contrapontos importantes, linguagem inadequada, falta de nexo com os fatos/provas do réu).
310
+ 3. **Sugestões Específicas:** Ofereça conselhos práticos para aprimoramento (ex: citar precedentes específicos como o RE 1.010.606/STF, refutar explicitamente possíveis argumentos do autor, conectar melhor o argumento às provas do réu, sugerir redação alternativa).
311
+ 4. **Nota Geral (0 a 5):** Atribua uma nota considerando:
312
+ * Fundamentação Legal/Jurisprudencial (Peso 3)
313
+ * Coerência e Lógica (Peso 2)
314
+ * Persuasão e Clareza (Peso 2)
315
+ * Adequação ao tipo de peça/momento (Peso 1)
316
+ * Conexão com os fatos/provas do caso (Peso 2)
317
+
318
+ Formato da Resposta: Utilize linguagem formal e jurídica. Estruture a resposta rigorosamente com os títulos:
319
+ `### Pontos Fortes`
320
+ `### Pontos a Melhorar`
321
+ `### Sugestões Específicas`
322
+ `### Nota Geral`
323
+
324
+ **Argumento do Advogado de Defesa (Jornal):**
325
+ "{argumento_usuario}"
326
+
327
+ **Sua Avaliação:**
328
+ """
329
+ return chamar_gemini_api(prompt, temperature=0.6, max_output_tokens=1000)
330
+
331
+ def gerar_resposta_testemunha_defesa_para_treino_ia(fatos_caso, nome_testemunha, pontos_chave_testemunha, historico_perguntas_respostas, pergunta_atual_adv_defesa):
332
+ contexto_caso = f"""
333
+ Você está simulando o depoimento de uma testemunha de DEFESA (Jornal) em uma Audiência de Instrução e Julgamento (AIJ) no Brasil.
334
+ O caso envolve Direito ao Esquecimento vs. Liberdade de Imprensa. O jornal (réu) é processado por relembrar um crime antigo (com absolvição) do autor.
335
+ **Fatos do Caso:** {fatos_caso if fatos_caso else CASO_DESCRICAO_PREDEFINIDO}
336
+ """
337
+ historico_formatado = "\nDepoimento até agora:\n"
338
+ for p, r in historico_perguntas_respostas:
339
+ historico_formatado += f"- Advogado Defesa: {p}\n- {nome_testemunha}: {r}\n"
340
+
341
+ prompt = f"""
342
+ {contexto_caso}
343
+
344
+ **Persona:** Você é {nome_testemunha}, testemunha arrolada pela DEFESA (Jornal).
345
+ **Seus Pontos Chave a Defender/Explicar:** {pontos_chave_testemunha}
346
+ Você deve responder às perguntas do advogado de defesa de forma consistente com esses pontos e com a tese da defesa (liberdade de imprensa, interesse público, veracidade, ausência de dolo/culpa, destaque à absolvição do autor no caso original).
347
+ Use linguagem formal, mas acessível para uma testemunha. Seja objetivo e direto. Evite admitir qualquer falha ou negligência por parte do jornal.
348
+ {historico_formatado if historico_perguntas_respostas else "Este é o início do seu depoimento."}
349
+
350
+ **Pergunta do Advogado de Defesa (Jornal):** "{pergunta_atual_adv_defesa}"
351
+
352
+ **Sua Resposta ({nome_testemunha}):**
353
+ """
354
+ return chamar_gemini_api(prompt, temperature=0.5, max_output_tokens=300)
355
+
356
+
357
+ # --- Funções de Lógica da Simulação e UI (from Script 1, adaptadas e com novas) ---
358
  def adicionar_fala_transcricao(estado_simulacao, ator, fala):
359
+ # (Função mantida como no Script 1 original)
360
  estado_simulacao["transcricao_logica"].append((ator, fala))
361
  if ator == "Advogado do Réu (Você)": estado_simulacao["transcricao_chat"].append((fala, None))
362
  else:
 
366
  return estado_simulacao
367
 
368
  def mostrar_botoes_corretos(fase_atual):
369
+ # (Função mantida como no Script 1 original)
370
  vis = {
371
  "btn_responder_conciliacao": fase_atual == FASE_ABERTURA_CONCILIACAO,
372
  "btn_chamar_testemunha_reu": fase_atual == FASE_TESTEMUNHAS_REU_INICIO,
 
379
  }
380
  return [gr.update(visible=vis[k]) for k in sorted(vis.keys())]
381
 
 
382
  def configurar_e_iniciar_simulacao(estado_s, fatos, p_reu, p_autor, t_reu_str, t_autor_str):
383
+ # (Função adaptada do Script 1)
384
  novo_estado = estado_inicial_simulacao()
385
+ if not fatos or not p_reu or not p_autor: # Basic validation
386
+ gr.Warning("Por favor, preencha todos os campos de configuração do caso ou carregue o caso padrão.")
387
+ return [novo_estado, novo_estado["transcricao_chat"], "Erro: Configuração incompleta.", "Preencha a configuração.", gr.Dropdown(choices=[], value=None)] + mostrar_botoes_corretos(novo_estado["fase_aij"])
388
+
389
  novo_estado["caso_fatos"], novo_estado["provas_reu_texto"], novo_estado["provas_autor_supostas_texto"] = fatos, p_reu, p_autor
390
  def parse_testemunhas(t_str):
391
+ defs = []
392
+ if t_str and t_str.strip():
393
+ for linha in t_str.strip().split('\n'):
394
+ if linha.strip():
395
+ partes = linha.split(':', 1)
396
+ if len(partes) == 2:
397
+ defs.append({"nome": partes[0].strip(), "pontos_chave": partes[1].strip()})
398
+ elif len(partes) == 1 and partes[0].strip(): # Testemunha sem pontos chave explícitos
399
+ defs.append({"nome": partes[0].strip(), "pontos_chave": "Não especificado."})
400
+ return defs
401
+
402
+ novo_estado["testemunhas_reu_defs"] = parse_testemunhas(t_reu_str)
403
+ novo_estado["testemunhas_autor_supostas_defs"] = parse_testemunhas(t_autor_str)
404
+
405
  novo_estado["fase_aij"] = FASE_ABERTURA_CONCILIACAO
406
  novo_estado = adicionar_fala_transcricao(novo_estado, "Sistema", "Configuração salva. Iniciando simulação...")
407
+ gr.Info("Iniciando simulação... Gerando falas iniciais da IA.")
408
  fala_juiz = gerar_resposta_juiz_ia(novo_estado)
409
  novo_estado = adicionar_fala_transcricao(novo_estado, "Juiz (IA)", fala_juiz)
410
  fala_adv_autor = gerar_resposta_advogado_autor_ia(novo_estado)
411
  novo_estado = adicionar_fala_transcricao(novo_estado, "Advogado do Autor (IA)", fala_adv_autor)
412
  novo_estado["instrucao_para_usuario"] = "Responda à proposta de conciliação do Autor ou declare sua posição."
413
  novo_estado["feedback_para_usuario"] = analisar_atuacao_defesa_ia(novo_estado)
414
+ nomes_testemunhas_reu = [t["nome"] for t in novo_estado["testemunhas_reu_defs"]] if novo_estado["testemunhas_reu_defs"] else []
415
  botoes_vis = mostrar_botoes_corretos(novo_estado["fase_aij"])
416
+ gr.Info("Simulação iniciada.")
417
+ return [novo_estado, novo_estado["transcricao_chat"], novo_estado["feedback_para_usuario"], novo_estado["instrucao_para_usuario"], gr.Dropdown(choices=nomes_testemunhas_reu, value=None, interactive=True)] + botoes_vis
418
 
419
  def lidar_com_fala_usuario(estado_s, fala_usuario_txt):
420
+ # (Função mantida como no Script 1 original, com pequenas adaptações)
421
  if not fala_usuario_txt and estado_s["fase_aij"] not in [FASE_TESTEMUNHAS_REU_INICIO]:
422
  estado_s["instrucao_para_usuario"] = "Por favor, digite sua fala ou selecione uma ação."
423
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"], gr.Textbox(value="")] + mostrar_botoes_corretos(estado_s["fase_aij"])
424
 
425
  estado_s = copy.deepcopy(estado_s)
426
  ator_usuario = "Advogado do Réu (Você)"
427
+ if estado_s["fase_aij"] == FASE_TESTEMUNHAS_REU_PERGUNTAS_REU and estado_s.get("testemunha_em_depoimento"):
428
+ ator_usuario = f"Advogado do Réu (Você) perguntando a {estado_s['testemunha_em_depoimento']['nome']}"
429
+ elif estado_s["fase_aij"] == FASE_TESTEMUNHAS_REU_INQUIRICAO_AUTOR and estado_s.get("testemunha_em_depoimento"):
430
+ ator_usuario = f"Testemunha {estado_s['testemunha_em_depoimento']['nome']} (Réu) respondendo"
431
+
432
+ if fala_usuario_txt:
433
+ estado_s = adicionar_fala_transcricao(estado_s, ator_usuario, fala_usuario_txt)
434
+ gr.Info(f"Sua fala registrada. Aguardando respostas da IA...")
435
 
436
+ # Lógica de transição de fases e respostas da IA
437
  if estado_s["fase_aij"] == FASE_ABERTURA_CONCILIACAO:
438
  fala_adv_autor = gerar_resposta_advogado_autor_ia(estado_s, fala_adv_reu=fala_usuario_txt)
439
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor)
440
  fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica="Partes se manifestaram sobre conciliação. Decida o prosseguimento.")
441
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
442
+ if any(k in fala_juiz.lower() for k in ["testemunha", "instrução", "prossegu", "oitiva"]):
443
+ if estado_s["testemunhas_autor_supostas_defs"]:
444
+ estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_AUTOR_INICIO, "Aguarde Juiz/Adv.Autor chamarem testemunha."
445
+ # Adicionar fala do Adv. Autor chamando a testemunha
446
+ fala_adv_autor_chamando = gerar_resposta_advogado_autor_ia(estado_s)
447
+ estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor_chamando)
448
+ if not ("Não tenho mais testemunhas" in fala_adv_autor_chamando or "Não arrolei testemunhas" in fala_adv_autor_chamando):
449
+ estado_s["testemunha_autor_atual_idx"] += 1
450
+ idx = estado_s["testemunha_autor_atual_idx"]
451
+ if idx < len(estado_s["testemunhas_autor_supostas_defs"]):
452
+ t_info = estado_s["testemunhas_autor_supostas_defs"][idx]
453
+ estado_s["testemunha_em_depoimento"] = {"nome": t_info["nome"], "pontos_chave": t_info["pontos_chave"], "parte": "AUTOR"}
454
+ fala_test_autor = gerar_resposta_testemunha_autor_ia(estado_s, pergunta_feita=fala_adv_autor_chamando)
455
+ estado_s = adicionar_fala_transcricao(estado_s, f"Testemunha {t_info['nome']} (Autor - IA)", fala_test_autor)
456
+ estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_AUTOR_CONTRADITA_REU, f"Contradite/pergunte à testemunha {t_info['nome']} (Autor)."
457
+ elif estado_s["testemunhas_reu_defs"]:
458
+ estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_REU_INICIO, "Selecione sua testemunha para chamar."
459
+ else:
460
+ estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_AUTOR, "Aguarde Juiz iniciar Alegações Finais."
461
+ # Se for para alegações do autor, o juiz deve dar a palavra e o adv. autor falar
462
+ fala_juiz_aleg = gerar_resposta_juiz_ia(estado_s)
463
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz_aleg)
464
+ fala_aleg_autor = gerar_resposta_advogado_autor_ia(estado_s)
465
+ estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_aleg_autor)
466
+ estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_REU, "Apresente suas Alegações Finais."
467
+ else:
468
+ estado_s["instrucao_para_usuario"] = "Responda ao Juiz ou Adv. Autor sobre conciliação."
469
+
470
  elif estado_s["fase_aij"] == FASE_TESTEMUNHAS_AUTOR_CONTRADITA_REU:
471
  fala_test_autor = gerar_resposta_testemunha_autor_ia(estado_s, pergunta_feita=fala_usuario_txt)
472
  estado_s = adicionar_fala_transcricao(estado_s, f"Testemunha {estado_s['testemunha_em_depoimento']['nome']} (Autor - IA)", fala_test_autor)
473
+ estado_s["instrucao_para_usuario"] = f"Faça outra pergunta à testemunha {estado_s['testemunha_em_depoimento']['nome']} (Autor) ou clique 'Juiz Avançar'."
474
+
475
+ elif estado_s["fase_aij"] == FASE_TESTEMUNHAS_REU_PERGUNTAS_REU: # Usuário (Adv Réu) perguntou à sua testemunha
476
+ # Aqui, o usuário está *atuando* como sua testemunha para responder à sua própria pergunta.
477
+ # A IA do Adv. Autor fará perguntas à testemunha do Réu.
478
+ # O usuário deve então responder como se fosse sua testemunha.
479
+ # Após a pergunta do usuário à sua testemunha, e a resposta simulada (pelo usuário mesmo, no chat),
480
+ # o Adv. Autor (IA) deve ter a chance de inquirir.
481
  estado_s["fase_aij"] = FASE_TESTEMUNHAS_REU_INQUIRICAO_AUTOR
482
+ fala_adv_autor_ia = gerar_resposta_advogado_autor_ia(estado_s) # Adv. Autor IA pergunta à testemunha do Réu
483
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor_ia)
484
+ estado_s["instrucao_para_usuario"] = f"Como testemunha {estado_s['testemunha_em_depoimento']['nome']}, responda à pergunta do Adv. Autor."
485
+
486
+ elif estado_s["fase_aij"] == FASE_TESTEMUNHAS_REU_INQUIRICAO_AUTOR: # Usuário respondeu como sua testemunha à pergunta do Adv. Autor
487
+ # Advogado do Autor (IA) pode fazer mais perguntas ou encerrar.
488
+ fala_adv_autor_ia = gerar_resposta_advogado_autor_ia(estado_s, fala_adv_reu=fala_usuario_txt) # Passa a resposta da testemunha do réu
489
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor_ia)
490
+ if "pergunta" in fala_adv_autor_ia.lower() or "?" in fala_adv_autor_ia and "não tenho mais perguntas" not in fala_adv_autor_ia.lower():
491
+ estado_s["instrucao_para_usuario"] = f"Como testemunha {estado_s['testemunha_em_depoimento']['nome']}, responda à nova pergunta do Adv. Autor."
492
+ else: # Adv. Autor não tem mais perguntas
493
+ fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica=f"Adv. Autor encerrou inquirição da testemunha {estado_s['testemunha_em_depoimento']['nome']}. Adv. Réu pode fazer mais perguntas ou dispensar.")
494
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
495
+ estado_s["fase_aij"] = FASE_TESTEMUNHAS_REU_PERGUNTAS_REU # Volta para Adv. Réu perguntar
496
+ estado_s["instrucao_para_usuario"] = f"Faça mais perguntas à sua testemunha {estado_s['testemunha_em_depoimento']['nome']}, ou clique 'Juiz Avançar' para dispensá-la."
497
+
498
  elif estado_s["fase_aij"] == FASE_ALEGACOES_FINAIS_REU:
 
499
  estado_s["fase_aij"] = FASE_ANALISE_FINAL_PROFESSOR
500
  fala_juiz = gerar_resposta_juiz_ia(estado_s)
501
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
502
+ estado_s["instrucao_para_usuario"] = "Audiência encerrada para sentença (simulada). Veja o feedback final do Professor IA."
503
+ # Analise final é chamada abaixo
504
+
505
  estado_s["feedback_para_usuario"] = analisar_atuacao_defesa_ia(estado_s, ultima_fala_reu=fala_usuario_txt if ator_usuario == "Advogado do Réu (Você)" else "")
506
+ gr.Info("Respostas da IA geradas.")
507
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"], gr.Textbox(value="")] + mostrar_botoes_corretos(estado_s["fase_aij"])
508
 
509
  def acao_botao_juiz_avancar(estado_s):
510
+ # (Função mantida e adaptada do Script 1)
511
  estado_s = copy.deepcopy(estado_s)
512
  fase_atual = estado_s["fase_aij"]
513
+ gr.Info(f"Avançando fase a partir de: {fase_atual}. Aguarde IA...")
514
 
515
  if fase_atual == FASE_ABERTURA_CONCILIACAO:
516
+ # Se partes não chegaram a acordo, ou se o usuário pulou a conciliação.
517
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", "Considerando frustrada a tentativa de conciliação, passaremos à instrução.")
518
+ if estado_s["testemunhas_autor_supostas_defs"]:
519
+ estado_s["fase_aij"] = FASE_TESTEMUNHAS_AUTOR_INICIO
520
+ fala_juiz = gerar_resposta_juiz_ia(estado_s)
521
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
522
+ fala_adv_autor = gerar_resposta_advogado_autor_ia(estado_s) # Adv Autor chama/pergunta
523
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor)
524
  if not ("Não tenho mais testemunhas" in fala_adv_autor or "Não arrolei testemunhas" in fala_adv_autor):
525
  estado_s["testemunha_autor_atual_idx"] += 1
 
527
  if idx < len(estado_s["testemunhas_autor_supostas_defs"]):
528
  t_info = estado_s["testemunhas_autor_supostas_defs"][idx]
529
  estado_s["testemunha_em_depoimento"] = {"nome": t_info["nome"], "pontos_chave": t_info["pontos_chave"], "parte": "AUTOR"}
530
+ fala_test_autor = gerar_resposta_testemunha_autor_ia(estado_s, pergunta_feita=fala_adv_autor) # Testemunha responde à pergunta inicial
531
  estado_s = adicionar_fala_transcricao(estado_s, f"Testemunha {t_info['nome']} (Autor - IA)", fala_test_autor)
532
+ estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_AUTOR_CONTRADITA_REU, f"Contradite ou faça perguntas à testemunha {t_info['nome']} (Autor)."
533
+ else: # Adv Autor não tem testemunhas, mesmo que tenha sido definido
534
+ if estado_s["testemunhas_reu_defs"]: estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_REU_INICIO, "Selecione sua testemunha para chamar."
535
+ else: estado_s["fase_aij"] = FASE_ALEGACOES_FINAIS_AUTOR # Pula para alegações finais
536
+ elif estado_s["testemunhas_reu_defs"]:
537
+ estado_s["fase_aij"] = FASE_TESTEMUNHAS_REU_INICIO
538
+ fala_juiz = gerar_resposta_juiz_ia(estado_s)
539
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
540
+ estado_s["instrucao_para_usuario"] = "Selecione sua testemunha para chamar."
541
+ else: # Sem testemunhas de nenhuma parte
542
+ estado_s["fase_aij"] = FASE_ALEGACOES_FINAIS_AUTOR
543
+ fala_juiz = gerar_resposta_juiz_ia(estado_s) # Juiz anuncia alegações
544
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
545
+ fala_adv_autor = gerar_resposta_advogado_autor_ia(estado_s) # Adv Autor faz alegações
546
+ estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor)
547
+ estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_REU, "Apresente suas Alegações Finais."
548
+
549
  elif fase_atual == FASE_TESTEMUNHAS_AUTOR_INICIO or fase_atual == FASE_TESTEMUNHAS_AUTOR_PERGUNTAS_AUTOR:
550
+ # Juiz pede ao Adv. Autor para chamar a *próxima* testemunha ou encerrar
551
+ fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica="Verificar se há mais testemunhas do Autor ou encerrar esta fase.")
552
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
553
+ fala_adv_autor = gerar_resposta_advogado_autor_ia(estado_s) # Adv. Autor chama próxima ou diz que não tem mais
554
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor)
555
+
556
+ if "Não tenho mais testemunhas" in fala_adv_autor or "Não arrolei testemunhas" in fala_adv_autor or estado_s["testemunha_autor_atual_idx"] +1 >= len(estado_s["testemunhas_autor_supostas_defs"]):
557
+ estado_s["testemunha_em_depoimento"] = None
558
+ if estado_s["testemunhas_reu_defs"]:
559
+ estado_s["fase_aij"] = FASE_TESTEMUNHAS_REU_INICIO
560
+ fala_juiz_trans = gerar_resposta_juiz_ia(estado_s) # Juiz anuncia oitiva das testemunhas do Réu
561
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz_trans)
562
+ estado_s["instrucao_para_usuario"] = "Selecione sua testemunha para chamar."
563
+ else: # Sem testemunhas do Réu, vai para alegações finais
564
+ estado_s["fase_aij"] = FASE_ALEGACOES_FINAIS_AUTOR
565
+ fala_juiz_trans = gerar_resposta_juiz_ia(estado_s) # Juiz anuncia alegações
566
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz_trans)
567
+ fala_aleg_autor = gerar_resposta_advogado_autor_ia(estado_s) # Adv Autor faz alegações
568
+ estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_aleg_autor)
569
+ estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_REU, "Apresente suas Alegações Finais."
570
+ else: # Adv Autor chamou próxima testemunha
571
+ estado_s["testemunha_autor_atual_idx"] += 1
572
+ idx = estado_s["testemunha_autor_atual_idx"]
573
+ # Garantir que o índice é válido
574
  if idx < len(estado_s["testemunhas_autor_supostas_defs"]):
575
  t_info = estado_s["testemunhas_autor_supostas_defs"][idx]
576
  estado_s["testemunha_em_depoimento"] = {"nome": t_info["nome"], "pontos_chave": t_info["pontos_chave"], "parte": "AUTOR"}
577
+ fala_test_autor = gerar_resposta_testemunha_autor_ia(estado_s, pergunta_feita=fala_adv_autor) # Testemunha responde à pergunta inicial do Adv. Autor
578
  estado_s = adicionar_fala_transcricao(estado_s, f"Testemunha {t_info['nome']} (Autor - IA)", fala_test_autor)
579
+ estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_AUTOR_CONTRADITA_REU, f"Contradite ou faça perguntas à testemunha {t_info['nome']} (Autor)."
580
+ else: # Caso raro de lógica inconsistente, trata como se não houvesse mais testemunhas
581
+ estado_s["fase_aij"] = FASE_TESTEMUNHAS_REU_INICIO # Ou alegações finais, conforme lógica acima
582
+ # ... (repetir lógica de transição para Réu ou Alegações)
583
+
584
  elif fase_atual == FASE_TESTEMUNHAS_AUTOR_CONTRADITA_REU:
585
+ # Usuário (Adv. Réu) terminou de perguntar à testemunha do Autor.
586
  estado_s["testemunha_em_depoimento"] = None
587
+ # Verificar se mais testemunhas do Autor
 
 
588
  if estado_s["testemunha_autor_atual_idx"] + 1 < len(estado_s["testemunhas_autor_supostas_defs"]):
589
+ estado_s["fase_aij"] = FASE_TESTEMUNHAS_AUTOR_INICIO # Volta para o juiz pedir ao Adv. Autor chamar a próxima
590
+ fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica="Advogado do Réu encerrou perguntas à testemunha do Autor. Verificar próxima testemunha do Autor.")
591
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
592
  # Adv Autor precisa ser chamado para agir
593
  fala_adv_autor = gerar_resposta_advogado_autor_ia(estado_s) # Adv Autor chama/pergunta
594
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor)
595
  if not ("Não tenho mais testemunhas" in fala_adv_autor or "Não arrolei testemunhas" in fala_adv_autor):
596
+ estado_s["testemunha_autor_atual_idx"] += 1
597
+ idx_new = estado_s["testemunha_autor_atual_idx"]
598
  if idx_new < len(estado_s["testemunhas_autor_supostas_defs"]):
599
  t_info_new = estado_s["testemunhas_autor_supostas_defs"][idx_new]
600
  estado_s["testemunha_em_depoimento"] = {"nome": t_info_new["nome"], "pontos_chave": t_info_new["pontos_chave"], "parte": "AUTOR"}
601
  fala_test_autor_new = gerar_resposta_testemunha_autor_ia(estado_s, pergunta_feita=fala_adv_autor)
602
  estado_s = adicionar_fala_transcricao(estado_s, f"Testemunha {t_info_new['nome']} (Autor - IA)", fala_test_autor_new)
603
+ estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_AUTOR_CONTRADITA_REU, f"Contradite ou faça perguntas à testemunha {t_info_new['nome']} (Autor)."
604
+ else: # Adv. Autor não tem mais, mesmo que houvesse na lista (raro)
605
+ if estado_s["testemunhas_reu_defs"]: estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_TESTEMUNHAS_REU_INICIO, "Selecione sua testemunha para chamar."
606
+ else: estado_s["fase_aij"] = FASE_ALEGACOES_FINAIS_AUTOR
607
+ fala_juiz_trans = gerar_resposta_juiz_ia(estado_s) # Juiz comanda nova fase
608
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz_trans)
609
+ if estado_s["fase_aij"] == FASE_ALEGACOES_FINAIS_AUTOR:
610
+ fala_aleg_autor = gerar_resposta_advogado_autor_ia(estado_s)
611
+ estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_aleg_autor)
612
+ estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_REU, "Apresente suas Alegações Finais."
613
+
614
+ else: # Não há mais testemunhas do Autor
615
+ if estado_s["testemunhas_reu_defs"]:
616
+ estado_s["fase_aij"] = FASE_TESTEMUNHAS_REU_INICIO
617
+ fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica="Encerrada oitiva das testemunhas do Autor. Iniciar oitiva das testemunhas do Réu.")
618
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
619
+ estado_s["instrucao_para_usuario"] = "Selecione sua testemunha para chamar."
620
+ else: # Sem testemunhas do Réu, vai para alegações finais
621
+ estado_s["fase_aij"] = FASE_ALEGACOES_FINAIS_AUTOR
622
+ fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica="Instrução encerrada. Passar para alegações finais do Autor.")
623
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
624
+ fala_aleg_autor = gerar_resposta_advogado_autor_ia(estado_s) # Adv Autor faz alegações
625
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_aleg_autor)
626
  estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_REU, "Apresente suas Alegações Finais."
627
 
628
  elif fase_atual in [FASE_TESTEMUNHAS_REU_PERGUNTAS_REU, FASE_TESTEMUNHAS_REU_INQUIRICAO_AUTOR]:
629
+ # Usuário (Adv. Réu) dispensou sua testemunha atual.
630
+ nome_test_dispensada = estado_s.get("testemunha_em_depoimento", {}).get("nome", "a testemunha do Réu")
631
  estado_s["testemunha_em_depoimento"] = None
632
+ fala_juiz_dispensa = f"Juiz (IA): Dispensada {nome_test_dispensada}."
633
+ if estado_s.get("testemunha_em_depoimento"): # Adiciona só se havia uma testemunha em depoimento
634
+ fala_juiz_dispensa = gerar_resposta_juiz_ia(estado_s, acao_especifica=f"Dispensar {nome_test_dispensada}. Perguntar ao Adv. Réu se tem mais testemunhas.")
635
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz_dispensa)
636
+
637
+
638
+ if estado_s["testemunha_reu_atual_idx"] + 1 < len(estado_s["testemunhas_reu_defs"]):
639
+ estado_s["fase_aij"] = FASE_TESTEMUNHAS_REU_INICIO # Volta para o usuário selecionar a próxima
640
+ estado_s["instrucao_para_usuario"] = "Selecione sua próxima testemunha para chamar ou clique 'Juiz Avançar' para encerrar oitiva das suas testemunhas."
641
+ else: # Não há mais testemunhas do Réu
642
+ estado_s["fase_aij"] = FASE_ALEGACOES_FINAIS_AUTOR
643
+ fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica="Encerrada oitiva das testemunhas do Réu. Passar para alegações finais do Autor.")
644
+ estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
645
+ fala_adv_autor = gerar_resposta_advogado_autor_ia(estado_s) # Adv Autor faz alegações
646
  estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Autor (IA)", fala_adv_autor)
647
  estado_s["fase_aij"], estado_s["instrucao_para_usuario"] = FASE_ALEGACOES_FINAIS_REU, "Apresente suas Alegações Finais."
648
+
649
  elif fase_atual == FASE_ALEGACOES_FINAIS_AUTOR:
650
+ # Adv. Autor terminou alegações, Juiz passa palavra ao Réu
651
+ estado_s["fase_aij"] = FASE_ALEGACOES_FINAIS_REU
652
+ fala_juiz = gerar_resposta_juiz_ia(estado_s) # Juiz passa a palavra ao Réu
653
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
654
  estado_s["instrucao_para_usuario"] = "Apresente suas Alegações Finais."
655
+ else: # Fallback para fases não explicitamente tratadas acima
656
+ fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica="Conduza para a próxima etapa lógica da audiência.")
657
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
658
+ estado_s["instrucao_para_usuario"] = "Siga as instruções do Juiz ou avance a fase."
659
 
660
  estado_s["feedback_para_usuario"] = analisar_atuacao_defesa_ia(estado_s)
661
+ gr.Info("Fase avançada. Interações da IA geradas.")
662
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"]] + mostrar_botoes_corretos(estado_s["fase_aij"])
663
 
664
  def chamar_testemunha_reu_selecionada(estado_s, nome_testemunha_selecionada):
665
+ # (Função mantida como no Script 1 original)
666
  estado_s = copy.deepcopy(estado_s)
667
  if not nome_testemunha_selecionada:
668
+ estado_s["instrucao_para_usuario"] = "Nenhuma testemunha selecionada. Por favor, selecione uma testemunha da lista."
669
+ gr.Warning("Selecione uma testemunha da lista.")
670
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"]] + mostrar_botoes_corretos(estado_s["fase_aij"])
671
+
672
  idx_testemunha = next((i for i, t in enumerate(estado_s["testemunhas_reu_defs"]) if t["nome"] == nome_testemunha_selecionada), -1)
673
  if idx_testemunha == -1:
674
+ estado_s["instrucao_para_usuario"] = f"Testemunha '{nome_testemunha_selecionada}' não encontrada na configuração."
675
+ gr.Error(f"Testemunha '{nome_testemunha_selecionada}' não encontrada.")
676
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"]] + mostrar_botoes_corretos(estado_s["fase_aij"])
677
 
678
  estado_s["testemunha_reu_atual_idx"] = idx_testemunha
679
  testemunha_obj = estado_s["testemunhas_reu_defs"][idx_testemunha]
680
  estado_s["testemunha_em_depoimento"] = {"nome": testemunha_obj["nome"], "pontos_chave": testemunha_obj["pontos_chave"], "parte": "REU"}
681
+
682
+ gr.Info(f"Chamando testemunha {testemunha_obj['nome']}. Aguarde IA...")
683
+ estado_s = adicionar_fala_transcricao(estado_s, "Advogado do Réu (Você)", f"Chamo para depor minha testemunha, Sr(a). {testemunha_obj['nome']}.")
684
+ fala_juiz = gerar_resposta_juiz_ia(estado_s, acao_especifica=f"Advogado do Réu chamou a testemunha {testemunha_obj['nome']}. Qualifique-a e passe a palavra ao Advogado do Réu para inquirição inicial.")
685
  estado_s = adicionar_fala_transcricao(estado_s, "Juiz (IA)", fala_juiz)
686
+ estado_s["fase_aij"] = FASE_TESTEMUNHAS_REU_PERGUNTAS_REU
687
+ estado_s["instrucao_para_usuario"] = f"Faça sua primeira pergunta à sua testemunha, {testemunha_obj['nome']}. Após sua pergunta e a resposta (que você digitará no chat como se fosse a testemunha), o Advogado do Autor (IA) poderá inquirir."
688
  estado_s["feedback_para_usuario"] = analisar_atuacao_defesa_ia(estado_s)
689
+ gr.Info("Testemunha chamada. Interações da IA geradas.")
690
  return [estado_s, estado_s["transcricao_chat"], estado_s["feedback_para_usuario"], estado_s["instrucao_para_usuario"]] + mostrar_botoes_corretos(estado_s["fase_aij"])
691
 
692
+ # --- UI Callbacks para Novas Abas ---
693
+ def avaliar_argumentos_defesa_ia_ui(fatos_caso_atual, provas_reu_atual, tipo_argumento_selecionado, argumento_digitado):
694
+ if not GEMINI_API_KEY: return "ERRO: API Key não configurada."
695
+ if not argumento_digitado or not tipo_argumento_selecionado:
696
+ return "Por favor, selecione o tipo de argumento e digite seu texto."
697
+ gr.Info(f"Avaliando seu argumento ({tipo_argumento_selecionado})... Aguarde.")
698
+ feedback = avaliar_argumentos_defesa_ia(fatos_caso_atual, provas_reu_atual, tipo_argumento_selecionado, argumento_digitado)
699
+ gr.Info("Avaliação concluída.")
700
+ return feedback
701
+
702
+ _historico_treino_testemunha_atual = [] # Simples cache para o diálogo de treino
703
+ def gerar_dialogo_testemunha_defesa_para_treino_ui(fatos_caso_atual, testemunhas_reu_defs_atual_str, testemunha_selecionada_nome, pergunta_adv_defesa):
704
+ global _historico_treino_testemunha_atual
705
+ if not GEMINI_API_KEY:
706
+ return _historico_treino_testemunha_atual + [ (None, "ERRO: API Key não configurada.") ]
707
+
708
+ if not testemunha_selecionada_nome:
709
+ return _historico_treino_testemunha_atual + [ (None, "Por favor, selecione uma testemunha da sua lista na aba 'Configuração'.") ]
710
+ if not pergunta_adv_defesa:
711
+ return _historico_treino_testemunha_atual + [ (None, "Por favor, digite sua pergunta para a testemunha.") ]
712
+
713
+ # Recriar testemunhas_reu_defs a partir da string (se fornecida e mudou) ou usar a padrão
714
+ testemunhas_reu_defs_usar = []
715
+ if testemunhas_reu_defs_atual_str:
716
+ try:
717
+ # Re-parse a string de testemunhas do réu da aba de configuração
718
+ linhas = testemunhas_reu_defs_atual_str.strip().split('\n')
719
+ for linha in linhas:
720
+ if linha.strip():
721
+ partes = linha.split(':', 1)
722
+ if len(partes) == 2:
723
+ testemunhas_reu_defs_usar.append({"nome": partes[0].strip(), "pontos_chave": partes[1].strip()})
724
+ elif len(partes) == 1: # Nome sem pontos chave
725
+ testemunhas_reu_defs_usar.append({"nome": partes[0].strip(), "pontos_chave": "Não especificado."})
726
+ except Exception as e:
727
+ print(f"Erro ao parsear testemunhas_reu_defs_atual_str: {e}")
728
+ testemunhas_reu_defs_usar = TESTEMUNHAS_REU_PREDEFINIDAS # Fallback
729
+ else:
730
+ testemunhas_reu_defs_usar = TESTEMUNHAS_REU_PREDEFINIDAS
731
+
732
+
733
+ testemunha_obj = next((t for t in testemunhas_reu_defs_usar if t["nome"] == testemunha_selecionada_nome), None)
734
+
735
+ if not testemunha_obj:
736
+ # Se não achou na lista dinâmica, tenta na lista padrão
737
+ testemunha_obj = next((t for t in TESTEMUNHAS_REU_PREDEFINIDAS if t["nome"] == testemunha_selecionada_nome), None)
738
+ if not testemunha_obj:
739
+ return _historico_treino_testemunha_atual + [ (None, f"Testemunha '{testemunha_selecionada_nome}' não encontrada. Verifique a aba 'Configuração'.") ]
740
+
741
+ # Reinicia o histórico se a testemunha mudou (simplificado)
742
+ if not _historico_treino_testemunha_atual or \
743
+ (_historico_treino_testemunha_atual and not _historico_treino_testemunha_atual[0][1].startswith(f"**{testemunha_obj['nome']}**:")):
744
+ _historico_treino_testemunha_atual = []
745
+ _historico_treino_testemunha_atual.append( (None, f"Iniciando inquirição de **{testemunha_obj['nome']}**. Pontos chave: {testemunha_obj['pontos_chave']}") )
746
+
747
+ gr.Info(f"Gerando resposta da testemunha {testemunha_obj['nome']}... Aguarde.")
748
+ resposta_testemunha = gerar_resposta_testemunha_defesa_para_treino_ia(
749
+ fatos_caso_atual if fatos_caso_atual else CASO_FATOS_COMPLETO_PREDEFINIDO,
750
+ testemunha_obj['nome'],
751
+ testemunha_obj['pontos_chave'],
752
+ [(q,r) for q,r in _historico_treino_testemunha_atual if q is not None], # Passa apenas Q/A anteriores
753
+ pergunta_adv_defesa
754
+ )
755
+ _historico_treino_testemunha_atual.append( (pergunta_adv_defesa, resposta_testemunha) )
756
+ gr.Info("Resposta da testemunha gerada.")
757
+ return _historico_treino_testemunha_atual, "" # Retorna o histórico e limpa o campo de pergunta
758
+
759
+
760
+ # --- Interface Gráfica (Gradio UI) ---
761
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="orange"), title="Simulador AIJ Interativo") as demo:
762
+ gr.Markdown("# ⚖️ Simulador Interativo de Audiência de Instrução e Julgamento (AIJ)")
763
+ gr.Markdown("Tema: **Direito ao Esquecimento vs. Liberdade de Imprensa**. Você assume o papel de **Advogado(a) do Réu (Jornal)**.")
764
+ if not GEMINI_API_KEY:
765
+ gr.Warning("API Key do Gemini (GEMINI_API_KEY) não encontrada! O aplicativo pode não funcionar corretamente. Configure-a como Secret neste Space ou localmente como variável de ambiente.")
766
+
767
  sim_state = gr.State(value=estado_inicial_simulacao())
768
 
769
  with gr.Tabs() as abas_principais:
770
+ with gr.TabItem("1. Configuração do Caso", id=0):
771
+ gr.Markdown("## Detalhes do Caso para Simulação")
772
+ gr.Markdown("Preencha os campos abaixo ou use os botões para gerar/carregar um caso.")
773
+ with gr.Row():
774
+ btn_gerar_caso_ia = gr.Button("✨ Gerar Novo Caso com IA", icon="🧠", scale=1)
775
+ btn_carregar_caso_padrao = gr.Button("📄 Carregar Caso Padrão (Esquecimento)", icon="📜", scale=1)
776
  with gr.Row():
777
  with gr.Column(scale=2):
778
+ fatos_input = gr.Textbox(lines=7, label="Resumo dos Fatos, Partes e Título:", placeholder="Descreva o caso ou gere/carregue.")
779
+ provas_reu_input = gr.Textbox(lines=4, label="Argumentos e Provas do Réu (Seu Cliente - Jornal):", placeholder="Ex: Arg: Liberdade de imprensa. Prova: Art. 5 CF.")
780
+ provas_autor_input = gr.Textbox(lines=4, label="Argumentos e Provas (Supostas) do Autor:", placeholder="Ex: Arg: Dano à imagem. Prova: Laudo X.")
781
  with gr.Column(scale=1):
782
+ testemunhas_reu_input = gr.Textbox(lines=5, label="Suas Testemunhas (Réu) - Formato: Nome: Pontos Chave a Depor", placeholder="João Silva: Viu X e Y.\nMaria Costa: Sabe Z.")
783
+ testemunhas_autor_supostas_input = gr.Textbox(lines=5, label="Supostas Testemunhas do Autor - Formato: Nome: Pontos Chave", placeholder="Carlos Lima: Sofreu Z.\nAna B.: Testemunhará sobre Q.")
784
+ btn_config_iniciar = gr.Button("💾 Salvar Configurações e Iniciar Simulação Interativa", variant="primary")
785
+ status_config_output = gr.Label(value="Aguardando configuração do caso...")
786
+
787
+ outputs_gerar_caso = [fatos_input, provas_reu_input, provas_autor_input, testemunhas_reu_input, testemunhas_autor_supostas_input, status_config_output]
788
+ btn_gerar_caso_ia.click(acao_gerar_caso_ficticio_ui, inputs=None, outputs=outputs_gerar_caso)
789
+ btn_carregar_caso_padrao.click(acao_carregar_caso_padrao_ui, inputs=None, outputs=outputs_gerar_caso)
790
+
791
+ with gr.TabItem("2. Audiência Interativa", id=1):
792
+ gr.Markdown("## Andamento da Audiência Simulada")
793
+ instrucao_usuario_output = gr.Markdown("Instrução: Configure o caso na aba 'Configuração' e clique em 'Salvar e Iniciar' para começar.")
794
+ chat_aij_output = gr.Chatbot(label="Transcrição da Audiência", height=500, bubble_full_width=False, show_copy_button=True, avatar_images=(None, "https://img.icons8.com/fluency/96/robot-2.png"))
795
+ fala_usuario_input = gr.Textbox(show_label=False, placeholder="Digite sua fala aqui ou use os botões de ação abaixo...", scale=4, lines=3)
796
  btn_enviar_fala_usuario = gr.Button("🎤 Enviar Fala / Ação", variant="stop")
797
+
798
+ with gr.Accordion("Ações Contextuais do Advogado do Réu (Você)", open=True):
799
+ with gr.Row():
800
+ btn_responder_conciliacao = gr.Button("Responder à Conciliação", visible=False)
801
+ dropdown_testemunhas_reu_select = gr.Dropdown(label="Sua Testemunha a Chamar:", choices=[], visible=False, interactive=True)
802
+ btn_chamar_testemunha_reu_action = gr.Button("Chamar Testemunha Selecionada", visible=False)
803
  with gr.Row():
804
+ btn_perguntar_testemunha_autor_action = gr.Button("Perguntar à Test. do Autor", visible=False)
805
+ btn_adv_reu_pergunta_sua_testemunha_action = gr.Button("Perguntar à Minha Testemunha", visible=False)
806
+ btn_adv_reu_responde_pela_sua_testemunha_action = gr.Button("Responder pela Minha Testemunha (à IA)", visible=False)
807
+ btn_apresentar_alegacoes_finais_reu_action = gr.Button("Apresentar Alegações Finais", visible=False)
808
+ btn_juiz_avancar_fase_action = gr.Button("⚖️ Juiz (IA): Concluir Etapa / Avançar Fase", visible=False, variant="secondary")
 
 
 
809
  lista_botoes_feedback = [btn_responder_conciliacao, btn_chamar_testemunha_reu_action, dropdown_testemunhas_reu_select, btn_perguntar_testemunha_autor_action, btn_adv_reu_pergunta_sua_testemunha_action, btn_adv_reu_responde_pela_sua_testemunha_action, btn_apresentar_alegacoes_finais_reu_action, btn_juiz_avancar_fase_action]
 
 
 
810
 
811
+ with gr.TabItem("3. Feedback da Atuação (Professor IA)", id=2):
812
+ gr.Markdown("## 💡 Análise da Sua Atuação na Audiência Interativa")
813
+ gr.Markdown("Este feedback é gerado pela IA com base na sua participação na aba 'Audiência Interativa'.")
814
+ feedback_output = gr.Textbox(lines=20, label="Feedback Detalhado:", interactive=False, show_copy_button=True)
815
 
816
+ with gr.TabItem("4. Treinamento de Argumentação (Defesa)", id=3):
817
+ gr.Markdown("## 🗣️ Pratique e Avalie Seus Argumentos (Advogado de Defesa)")
818
+ gr.Markdown("Use esta seção para redigir e obter feedback sobre argumentos específicos para o caso configurado.")
819
+ with gr.Row():
820
+ fatos_caso_treino_arg_display = gr.Textbox(label="Fatos do Caso (da Configuração):", value=CASO_FATOS_COMPLETO_PREDEFINIDO, lines=5, interactive=False) # Mostra fatos do caso padrão ou o configurado
821
+ provas_reu_treino_arg_display = gr.Textbox(label="Provas do Réu (da Configuração):", value=PROVAS_REU_TEXTO_PREDEFINIDO, lines=5, interactive=False)
822
+ tipo_argumento_treino = gr.Radio(
823
+ ["Contestação (teses principais)", "Perguntas para Testemunha do Autor", "Perguntas para Testemunha do Réu", "Alegações Finais (memoriais)"],
824
+ label="Selecione o Tipo de Argumento/Peça para Treinar:", value="Alegações Finais (memoriais)"
825
+ )
826
+ argumento_input_treino = gr.Textbox(lines=10, label="Digite seu argumento aqui:", placeholder="Ex: 'Excelência, a matéria jornalística é um retrato fiel dos fatos públicos...'")
827
+ btn_avaliar_argumento_treino = gr.Button("🤖 Avaliar Argumento com IA", variant="primary")
828
+ avaliacao_output_treino = gr.Markdown(label="Feedback da IA sobre o Argumento:")
829
+
830
+ # Atualizar displays quando a configuração mudar
831
+ fatos_input.change(lambda x: x, inputs=fatos_input, outputs=fatos_caso_treino_arg_display)
832
+ provas_reu_input.change(lambda x: x, inputs=provas_reu_input, outputs=provas_reu_treino_arg_display)
833
+
834
+ btn_avaliar_argumento_treino.click(
835
+ avaliar_argumentos_defesa_ia_ui,
836
+ inputs=[fatos_caso_treino_arg_display, provas_reu_treino_arg_display, tipo_argumento_treino, argumento_input_treino],
837
+ outputs=avaliacao_output_treino
838
+ )
839
+
840
+ with gr.TabItem("5. Preparar Testemunhas (Defesa)", id=4):
841
+ gr.Markdown("## 🎙️ Simule a Inquirição das Suas Testemunhas (Defesa)")
842
+ gr.Markdown("Pratique como você (Advogado de Defesa) inquiriria suas próprias testemunhas. A IA responderá como a testemunha selecionada.")
843
+ fatos_caso_treino_test_display = gr.Textbox(label="Fatos do Caso (da Configuração):", value=CASO_FATOS_COMPLETO_PREDEFINIDO, lines=5, interactive=False)
844
+ testemunhas_reu_config_treino_display = gr.Textbox(label="Definição das Testemunhas do Réu (da Configuração):", value=TESTEMUNHAS_REU_TEXTO_PREDEFINIDO, lines=3, interactive=False)
845
+
846
+ # Atualizar displays quando a configuração mudar
847
+ fatos_input.change(lambda x: x, inputs=fatos_input, outputs=fatos_caso_treino_test_display)
848
+ testemunhas_reu_input.change(lambda x: x, inputs=testemunhas_reu_input, outputs=testemunhas_reu_config_treino_display)
849
+
850
+ # Dropdown para selecionar testemunha do réu para treino
851
+ dropdown_testemunhas_reu_treino = gr.Dropdown(label="Selecione Sua Testemunha para Inquirir:", choices=[t['nome'] for t in TESTEMUNHAS_REU_PREDEFINIDAS], interactive=True)
852
+ # Atualizar choices do dropdown quando testemunhas_reu_input mudar
853
+ def update_dropdown_treino_choices(t_reu_str):
854
+ nomes = []
855
+ if t_reu_str and t_reu_str.strip():
856
+ for linha in t_reu_str.strip().split('\n'):
857
+ if linha.strip():
858
+ partes = linha.split(':', 1)
859
+ nomes.append(partes[0].strip())
860
+ return gr.Dropdown(choices=nomes if nomes else [t['nome'] for t in TESTEMUNHAS_REU_PREDEFINIDAS], value=nomes[0] if nomes else None)
861
+ testemunhas_reu_input.change(update_dropdown_treino_choices, inputs=testemunhas_reu_input, outputs=dropdown_testemunhas_reu_treino)
862
+
863
+
864
+ chat_treino_testemunha = gr.Chatbot(label="Simulação de Depoimento (Treino)", height=300, show_copy_button=True, bubble_full_width=False, avatar_images=(None, "https://img.icons8.com/officel/80/person-male.png"))
865
+ pergunta_testemunha_treino_input = gr.Textbox(label="Sua Pergunta para a Testemunha:", placeholder="Ex: 'Senhor Silva, poderia descrever o procedimento editorial?'")
866
+ btn_perguntar_testemunha_treino = gr.Button("💬 Perguntar à Testemunha (IA)", variant="primary")
867
+ btn_limpar_chat_treino_testemunha = gr.Button("🗑️ Limpar Chat de Treino")
868
+
869
+ def limpar_chat_treino():
870
+ global _historico_treino_testemunha_atual
871
+ _historico_treino_testemunha_atual = []
872
+ return [], ""
873
+ btn_limpar_chat_treino_testemunha.click(limpar_chat_treino, outputs=[chat_treino_testemunha, pergunta_testemunha_treino_input])
874
+
875
+ btn_perguntar_testemunha_treino.click(
876
+ gerar_dialogo_testemunha_defesa_para_treino_ui,
877
+ inputs=[fatos_caso_treino_test_display, testemunhas_reu_config_treino_display, dropdown_testemunhas_reu_treino, pergunta_testemunha_treino_input],
878
+ outputs=[chat_treino_testemunha, pergunta_testemunha_treino_input] # Limpa input após envio
879
+ )
880
+
881
+
882
+ with gr.TabItem("ℹ️ Ajuda / Sobre o Caso Padrão", id=5):
883
+ gr.Markdown("## Sobre o Caso Padrão: Direito ao Esquecimento vs. Liberdade de Imprensa")
884
+ gr.Markdown(f"**Título:** {CASO_TITULO_PREDEFINIDO}")
885
+ gr.Markdown(f"**Partes:**\n{CASO_PARTES_PREDEFINIDO.replace('\n', '\n\n')}")
886
+ gr.Markdown(f"**Resumo do Caso:**\n{CASO_DESCRICAO_PREDEFINIDO}")
887
+ with gr.Accordion("Argumentos Principais do Autor (Caso Padrão)", open=False):
888
+ gr.Markdown("\n".join([f"- {arg}" for arg in ARGUMENTOS_AUTOR_PREDEFINIDOS]))
889
+ with gr.Accordion("Argumentos Principais do Réu/Jornal (Caso Padrão)", open=False):
890
+ gr.Markdown("\n".join([f"- {arg}" for arg in CONTRA_ARGUMENTOS_REU_PREDEFINIDOS]))
891
+ with gr.Accordion("Testemunhas do Réu/Jornal (Caso Padrão)", open=False):
892
+ gr.Markdown("\n".join([f"- **{t['nome']}**: {t['pontos_chave']}" for t in TESTEMUNHAS_REU_PREDEFINIDAS]))
893
+
894
+ gr.Markdown("### Legislação e Precedentes Relevantes (Geral)")
895
+ with gr.Row():
896
+ with gr.Column():
897
+ gr.Markdown("**Potencialmente Favoráveis ao Réu (Jornal):**")
898
+ gr.Markdown("\n".join([f"- {lei}" for lei in LEGISLACAO_PRECEDENTES_PREDEFINIDO["favoraveis_ao_reu"]]))
899
+ with gr.Column():
900
+ gr.Markdown("**Potencialmente Favoráveis ao Autor:**")
901
+ gr.Markdown("\n".join([f"- {lei}" for lei in LEGISLACAO_PRECEDENTES_PREDEFINIDO["favoraveis_ao_autor"]]))
902
+ gr.Markdown("""
903
+ ## Como utilizar este simulador:
904
+ 1. **Configuração (Aba 1):**
905
+ * **Gerar Novo Caso com IA:** Cria um caso fictício aleatório sobre o tema.
906
+ * **Carregar Caso Padrão:** Preenche os campos com o "Caso da Reportagem Revisitada".
907
+ * Ou preencha manualmente os detalhes do seu próprio caso.
908
+ * **Salve e Inicie:** Fundamental para começar a simulação interativa.
909
+ 2. **Audiência Interativa (Aba 2):**
910
+ * O núcleo da simulação. Siga as instruções e interaja como Advogado(a) do Réu.
911
+ * Use o campo de texto para suas falas ou os botões de ação contextual.
912
+ * O "Juiz (IA): Avançar Fase" é usado para progredir quando você conclui sua parte em uma etapa ou quando a IA indica.
913
+ 3. **Feedback da Atuação (Aba 3):**
914
+ * Após interagir na Aba 2, verifique aqui a análise da IA sobre sua performance.
915
+ 4. **Treinamento de Argumentação (Aba 4):**
916
+ * Use para praticar a redação de argumentos específicos (ex: para contestação, alegações finais) e receber feedback da IA. Baseia-se nos fatos e provas configurados na Aba 1.
917
+ 5. **Preparar Testemunhas (Aba 5):**
918
+ * Treine a inquirição das suas testemunhas (do Réu). Você faz as perguntas, e a IA responde como se fosse a testemunha selecionada, baseando-se nos "pontos chave" definidos na Aba 1.
919
+ ## Dicas para Atuação como Advogado(a) do Réu (Jornal):
920
+ * **Liberdade de Imprensa:** Seu principal argumento. Fundamente com a Constituição.
921
+ * **Interesse Público:** Demonstre a relevância da matéria.
922
+ * **Veracidade dos Fatos:** Crucial. A matéria deve ser factualmente correta.
923
+ * **Ausência de Dolo/Culpa:** Argumente que não houve intenção de prejudicar, apenas informar.
924
+ * **Menção à Absolvição:** Se o autor foi absolvido e a matéria menciona isso, é um ponto forte para a defesa.
925
+ * **Precedentes (STF):** Cite o RE 1.010.606, que ponderou o direito ao esquecimento com a liberdade de informação.
926
+ * **Contraditório:** Explore as perguntas às testemunhas do Autor para enfraquecer a tese dele.
927
+ * **Suas Testemunhas:** Prepare-as para reforçar a tese da defesa.
928
+ """)
929
+
930
+ # --- Conexões dos Componentes da UI (Event Handlers) ---
931
  outputs_config = [sim_state, chat_aij_output, feedback_output, instrucao_usuario_output, dropdown_testemunhas_reu_select] + lista_botoes_feedback
932
+ btn_config_iniciar.click(
933
+ configurar_e_iniciar_simulacao,
934
+ inputs=[sim_state, fatos_input, provas_reu_input, provas_autor_input, testemunhas_reu_input, testemunhas_autor_supostas_input],
935
+ outputs=outputs_config
936
+ ).then(lambda: gr.Textbox(value=""), outputs=[fala_usuario_input] # Limpa o campo de fala
937
+ ).then(lambda: gr.Tabs(selected=1), outputs=[abas_principais]) # Muda para aba Audiência
938
 
939
  outputs_fala_usuario = [sim_state, chat_aij_output, feedback_output, instrucao_usuario_output, fala_usuario_input] + lista_botoes_feedback
940
  btn_enviar_fala_usuario.click(lidar_com_fala_usuario, inputs=[sim_state, fala_usuario_input], outputs=outputs_fala_usuario)
941
  fala_usuario_input.submit(lidar_com_fala_usuario, inputs=[sim_state, fala_usuario_input], outputs=outputs_fala_usuario)
942
+
943
  outputs_acao_juiz = [sim_state, chat_aij_output, feedback_output, instrucao_usuario_output] + lista_botoes_feedback
944
  btn_juiz_avancar_fase_action.click(acao_botao_juiz_avancar, inputs=[sim_state], outputs=outputs_acao_juiz).then(lambda: gr.Textbox(value=""), outputs=[fala_usuario_input])
945
  btn_chamar_testemunha_reu_action.click(chamar_testemunha_reu_selecionada, inputs=[sim_state, dropdown_testemunhas_reu_select], outputs=outputs_acao_juiz).then(lambda: gr.Textbox(value=""), outputs=[fala_usuario_input])
946
 
947
+ # Links dos botões de ação específicos para lidar_com_fala_usuario (eles apenas enviam o texto do botão como "fala")
948
+ # Estes botões agora estão mais para indicar o contexto da fala do usuário no input principal.
949
+ # A lógica de o que fazer com a fala do usuário está centralizada em `lidar_com_fala_usuario`.
950
+ # Se o botão for para uma ação específica que não envolve fala direta, ele precisa de seu próprio handler.
951
+ # Ex: Responder conciliação, apresentar alegações finais - podem usar o `lidar_com_fala_usuario` se o usuário digitar no campo.
952
+ # Se forem "ações puras" sem texto, podem precisar de lógica adaptada ou de um `fala_usuario_txt` especial.
953
+ # Para simplificar, vamos assumir que o usuário digita a resposta no campo de texto principal após clicar nesses botões (que agora servem mais como lembretes visuais).
954
+ # A alternativa seria esses botões passarem um placeholder de texto para `lidar_com_fala_usuario`.
955
+ # Por exemplo, btn_responder_conciliacao.click(lambda s: lidar_com_fala_usuario(s, "Réu se manifesta sobre conciliação (detalhes no campo de texto)."), ...)
956
+ # Mas a implementação atual já faz o `lidar_com_fala_usuario` receber o texto do `fala_usuario_input`.
957
+
958
+ # Botões que enviam a fala do input principal
959
+ btn_responder_conciliacao.click(lambda: gr.Info("Digite sua resposta à conciliação no campo de fala e envie."), inputs=[], outputs=[]).then(
960
+ lidar_com_fala_usuario, inputs=[sim_state, fala_usuario_input], outputs=outputs_fala_usuario
961
+ )
962
+ btn_perguntar_testemunha_autor_action.click(lambda: gr.Info("Digite sua pergunta à testemunha do Autor no campo de fala e envie."), inputs=[], outputs=[]).then(
963
+ lidar_com_fala_usuario, inputs=[sim_state, fala_usuario_input], outputs=outputs_fala_usuario
964
+ )
965
+ btn_adv_reu_pergunta_sua_testemunha_action.click(lambda: gr.Info("Digite sua pergunta à sua testemunha no campo de fala e envie. Você também digitará a RESPOSTA dela em seguida."), inputs=[], outputs=[]).then(
966
+ lidar_com_fala_usuario, inputs=[sim_state, fala_usuario_input], outputs=outputs_fala_usuario
967
+ )
968
+ btn_adv_reu_responde_pela_sua_testemunha_action.click(lambda: gr.Info("Digite a resposta da sua testemunha (à pergunta do Adv. Autor) no campo de fala e envie."), inputs=[], outputs=[]).then(
969
+ lidar_com_fala_usuario, inputs=[sim_state, fala_usuario_input], outputs=outputs_fala_usuario
970
+ )
971
+ btn_apresentar_alegacoes_finais_reu_action.click(lambda: gr.Info("Digite suas alegações finais no campo de fala e envie."), inputs=[], outputs=[]).then(
972
+ lidar_com_fala_usuario, inputs=[sim_state, fala_usuario_input], outputs=outputs_fala_usuario
973
+ )
974
+
975
+ # Estado inicial da UI no carregamento
976
+ def setup_initial_ui_state_load(s):
977
+ initial_fase = s["fase_aij"]
978
+ dropdown_choices = [t["nome"] for t in s.get("testemunhas_reu_defs", [])] if s.get("testemunhas_reu_defs") else []
979
+ return [gr.Dropdown(choices=dropdown_choices, value=None, interactive=True)] + mostrar_botoes_corretos(initial_fase)
980
+
981
+ demo.load(
982
+ lambda s: (s, s["transcricao_chat"], s["feedback_para_usuario"], s["instrucao_para_usuario"]) + tuple(setup_initial_ui_state_load(s)),
983
+ inputs=[sim_state],
984
+ outputs=[sim_state, chat_aij_output, feedback_output, instrucao_usuario_output, dropdown_testemunhas_reu_select] + lista_botoes_feedback
985
+ )
986
 
987
  if __name__ == "__main__":
988
  if not GEMINI_API_KEY:
 
991
  print("Para rodar localmente, edite o script e insira sua chave ou defina a variável de ambiente.")
992
  print("Para Hugging Face Spaces, configure o Secret 'GEMINI_API_KEY'.")
993
  print("#####################################################################")
994
+ demo.queue(max_size=20).launch(debug=False) # Adicionado max_size para melhor gerenciamento de fila.