caarleexx commited on
Commit
6f461bc
·
verified ·
1 Parent(s): 6dbf398

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +98 -11
app.py CHANGED
@@ -13,7 +13,7 @@ import google.generativeai as genai
13
  # ==================== 1. CONFIGURAÇÃO ====================
14
 
15
  api_key = os.getenv("GOOGLE_API_KEY", "SUA_API_KEY_AQUI")
16
- if api_key:
17
  genai.configure(api_key=api_key)
18
 
19
  model_flash = genai.GenerativeModel("gemini-2.0-flash-exp")
@@ -28,19 +28,86 @@ def carregar_protocolo():
28
  """Carrega configuração do protocolo"""
29
  try:
30
  with open(ARQUIVO_CONFIG, "r", encoding="utf-8") as f:
31
- return f.read()
32
- except:
 
 
 
 
 
 
 
 
 
 
33
  return "[]"
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  def salvar_protocolo(conteudo):
36
  """Salva e valida JSON do protocolo"""
37
  try:
38
- json.loads(conteudo)
 
 
 
 
 
 
 
 
 
39
  with open(ARQUIVO_CONFIG, "w", encoding="utf-8") as f:
40
  f.write(conteudo)
41
- return "✅ Protocolo salvo com sucesso"
42
- except Exception as e:
 
43
  return f"❌ Erro no JSON: {str(e)}"
 
 
44
 
45
  def ler_anexo(arquivo):
46
  """Lê arquivo anexado"""
@@ -153,6 +220,14 @@ def orquestrador(texto, arquivo, history, json_config):
153
 
154
  try:
155
  protocolo = json.loads(json_config)
 
 
 
 
 
 
 
 
156
  except Exception as e:
157
  history[-1][1] = f"❌ **Erro no JSON de Configuração**\n\n```\n{str(e)}\n```"
158
  yield history, {}, f"Erro JSON: {e}"
@@ -196,6 +271,18 @@ def orquestrador(texto, arquivo, history, json_config):
196
  iteracao = 0
197
  fase_7_passou = False
198
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  while iteracao < MAX_ITERACOES and not fase_7_passou:
200
  iteracao += 1
201
  logs += f"\n{'='*60}\n🔄 ITERAÇÃO {iteracao}/{MAX_ITERACOES}\n{'='*60}\n"
@@ -219,7 +306,6 @@ def orquestrador(texto, arquivo, history, json_config):
219
  yield history, timeline, logs
220
 
221
  # Executar Fase 7: TESTE_CRUCIALIDADE
222
- cfg_fase7 = next(f for f in protocolo if f['fase'] == 7)
223
  history[-1][1] = f"🧪 **Fase 7/10: Teste de Crucialidade** (Iteração {iteracao})\n\nValidando..."
224
  yield history, timeline, logs
225
 
@@ -233,7 +319,7 @@ def orquestrador(texto, arquivo, history, json_config):
233
  return
234
 
235
  # Verificar se passou no teste
236
- teste_resultado = resultado['content']
237
  fase_7_passou = teste_resultado.get('PASSOU', False)
238
  score = teste_resultado.get('SCORE_CRUCIALIDADE', 0)
239
 
@@ -243,7 +329,7 @@ def orquestrador(texto, arquivo, history, json_config):
243
  else:
244
  logs += f"⚠️ TESTE FALHOU (score: {score:.3f})\n"
245
  fragilidades = teste_resultado.get('FRAGILIDADES_IDENTIFICADAS', [])
246
- history[-1][1] = f"⚠️ **Validação Reprovada** (Score: {score:.3f})\n\nFragilidades:\n" + "\n".join(f"- {f}" for f in fragilidades)
247
 
248
  yield history, timeline, logs
249
 
@@ -269,7 +355,7 @@ def orquestrador(texto, arquivo, history, json_config):
269
 
270
  # Se for a fase final (9 - RELATORIO_FINAL), mostrar resultado
271
  if cfg['fase'] == 9 and cfg['tipo_saida'] == 'texto':
272
- final_response = resultado['content']
273
  history[-1][1] = final_response
274
 
275
  yield history, timeline, logs
@@ -314,7 +400,8 @@ def criar_ui():
314
  show_label=False,
315
  height=650,
316
  show_copy_button=True,
317
- render_markdown=True
 
318
  )
319
 
320
  with gr.Row():
 
13
  # ==================== 1. CONFIGURAÇÃO ====================
14
 
15
  api_key = os.getenv("GOOGLE_API_KEY", "SUA_API_KEY_AQUI")
16
+ if api_key and api_key != "SUA_API_KEY_AQUI":
17
  genai.configure(api_key=api_key)
18
 
19
  model_flash = genai.GenerativeModel("gemini-2.0-flash-exp")
 
28
  """Carrega configuração do protocolo"""
29
  try:
30
  with open(ARQUIVO_CONFIG, "r", encoding="utf-8") as f:
31
+ conteudo = f.read()
32
+ # Validar se é JSON válido
33
+ json.loads(conteudo)
34
+ return conteudo
35
+ except FileNotFoundError:
36
+ print(f"⚠️ Arquivo {ARQUIVO_CONFIG} não encontrado. Criando protocolo padrão...")
37
+ return criar_protocolo_padrao()
38
+ except json.JSONDecodeError as e:
39
+ print(f"⚠️ JSON inválido: {e}")
40
+ return criar_protocolo_padrao()
41
+ except Exception as e:
42
+ print(f"⚠️ Erro ao carregar protocolo: {e}")
43
  return "[]"
44
 
45
+ def criar_protocolo_padrao():
46
+ """Cria protocolo padrão se não existir"""
47
+ protocolo_minimo = [
48
+ {"fase": 0, "nome": "ESTADO_INICIAL", "modelo": "flash", "tipo_saida": "json",
49
+ "missao": "Registre o input inicial em JSON com: PERGUNTA_NORMALIZADA, CONTEXTO_IDENTIFICADO, TIPO_CASO, PARTES_ENVOLVIDAS, INCERTEZA_INICIAL (0-1), EVIDENCIAS_DISPONIVEIS."},
50
+
51
+ {"fase": 1, "nome": "MAPEAMENTO_OBJETIVO", "modelo": "flash", "tipo_saida": "json",
52
+ "missao": "Analise o estado inicial e retorne JSON com: OBJETIVO_CLARIFICADO, TIPO_RESPOSTA_ESPERADA, CRITERIOS_VALIDACAO (3-5), PRESSUPOSTOS_IMPLICITOS, PERGUNTAS_DERIVADAS, METODOLOGIA_SUGERIDA."},
53
+
54
+ {"fase": 2, "nome": "INVENTARIO_EPISTEMICO", "modelo": "flash", "tipo_saida": "json",
55
+ "missao": "Mapeie conhecimento em 4 categorias JSON: CONHECIMENTO_CERTO (P≈1.0), CONHECIMENTO_PROVAVEL (P≈0.7-0.9), CONHECIMENTO_INCERTO (P≈0.3-0.6), DESCONHECIMENTO_TOTAL, PERCENTUAL_COBERTURA (0-100), GAPS_CRITICOS."},
56
+
57
+ {"fase": 3, "nome": "GERACAO_CENARIOS", "modelo": "flash", "tipo_saida": "json",
58
+ "missao": "Gere array de 3+ cenários em JSON. Cada um com: ID (C1, C2...), DESCRICAO, PROBABILIDADE_PRIOR (soma=1.0), SUPOSICOES, COMPATIBILIDADE, EVIDENCIAS_SUPORTE, EVIDENCIAS_CONTRA, PLAUSIBILIDADE_SCORE."},
59
+
60
+ {"fase": 4, "nome": "ANALISE_CONTRAFACTUAL", "modelo": "flash", "tipo_saida": "json",
61
+ "missao": "Teste 'E SE?' para cada suposição. Retorne JSON: VARIAVEIS_CRITICAS, MAPA_CAUSAL, PONTOS_INFLEXAO (que se falsos invertem conclusões), TESTES_RECOMENDADOS."},
62
+
63
+ {"fase": 5, "nome": "CADEIA_INVESTIGATIVA", "modelo": "flash", "tipo_saida": "json",
64
+ "missao": "Construa cadeia de perguntas priorizadas. JSON: CADEIA_PERGUNTAS (array ordenado com id, pergunta, justificativa, reducao_entropia_estimada, metodo_busca, proximos_passos, prioridade), ARVORE_DECISAO, EVIDENCIAS_NECESSARIAS."},
65
+
66
+ {"fase": 6, "nome": "COLETA_ATUALIZACAO_BAYESIANA", "modelo": "pro", "tipo_saida": "json",
67
+ "missao": "Aplique P(C|E) = P(E|C) × P(C) / P(E). JSON: EVIDENCIAS_ANALISADAS (com likelihoods), CENARIOS_ATUALIZADOS (prior→posterior), GANHO_INFORMACAO (KL divergence), CONVERGENCIA (bool), CENARIO_DOMINANTE."},
68
+
69
+ {"fase": 7, "nome": "TESTE_CRUCIALIDADE", "modelo": "pro", "tipo_saida": "json",
70
+ "missao": "Valide contra 7 critérios (cada 0.0-1.0): CONSISTENCIA_INTERNA, COMPATIBILIDADE_EVIDENCIAS, EXPLICACOES_ALTERNATIVAS, FALSIFICABILIDADE, PARSIMONIA, ESCOPO, PREDICOES_VERIFICAVEIS. JSON: TESTES (dict), SCORE_CRUCIALIDADE (média), LIMIAR_CONFIANCA (0.70), PASSOU (bool), ACAO (PROSSEGUIR ou VOLTAR_FASE_3), FRAGILIDADES_IDENTIFICADAS (array)."},
71
+
72
+ {"fase": 8, "nome": "GERACAO_RESPOSTA", "modelo": "pro", "tipo_saida": "json",
73
+ "missao": "Sintetize em JSON: AFIRMACAO_PRINCIPAL, NIVEL_CONFIANCA (0-1), EVIDENCIAS_SUPORTE, SUPOSICOES_CRITICAS, CENARIOS_ALTERNATIVOS (P>0.1), PROXIMOS_PASSOS, FRONTEIRAS_CONHECIMENTO, CALIBRACAO_EPISTEMICA (honest/overconfident/underconfident), QUALIFICADORES."},
74
+
75
+ {"fase": 9, "nome": "RELATORIO_FINAL", "modelo": "pro", "tipo_saida": "texto",
76
+ "missao": "Escreva relatório completo em Markdown com estrutura: # RELATÓRIO DE ANÁLISE EPISTÊMICA\n\n## SUMÁRIO EXECUTIVO\n(Caso, Conclusão, Confiança, Calibração)\n\n## 1. ESTADO INICIAL\n## 2. OBJETIVO\n## 3. INVENTÁRIO DE CONHECIMENTO\n(Certo, Provável, Incerto, Gaps)\n\n## 4. CENÁRIOS CONSIDERADOS\n## 5. ANÁLISE BAYESIANA\n(Tabela Prior→Posterior)\n\n## 6. VALIDAÇÃO\n(Tabela 7 critérios)\n\n## 7. CONCLUSÃO E RECOMENDAÇÕES\n(Afirmação, Evidências-chave, Suposições críticas, Próximos passos)\n\n## 8. FRONTEIRAS DO CONHECIMENTO\n## 9. CALIBRAÇÃO EPISTÊMICA\n## 10. METADADOS\n(Fases, Iterações, Timestamp)"}
77
+ ]
78
+
79
+ protocolo_json = json.dumps(protocolo_minimo, ensure_ascii=False, indent=2)
80
+
81
+ try:
82
+ with open(ARQUIVO_CONFIG, "w", encoding="utf-8") as f:
83
+ f.write(protocolo_json)
84
+ print(f"✅ Protocolo padrão criado: {ARQUIVO_CONFIG}")
85
+ except Exception as e:
86
+ print(f"⚠️ Não foi possível salvar protocolo: {e}")
87
+
88
+ return protocolo_json
89
+
90
  def salvar_protocolo(conteudo):
91
  """Salva e valida JSON do protocolo"""
92
  try:
93
+ protocolo = json.loads(conteudo)
94
+
95
+ # Validar estrutura
96
+ if not isinstance(protocolo, list):
97
+ return "❌ Erro: Protocolo deve ser um array JSON"
98
+
99
+ fases = {f.get('fase') for f in protocolo if isinstance(f, dict) and 'fase' in f}
100
+ if len(fases) < 10:
101
+ return f"⚠️ Aviso: Protocolo tem apenas {len(fases)} fases (esperado: 10)"
102
+
103
  with open(ARQUIVO_CONFIG, "w", encoding="utf-8") as f:
104
  f.write(conteudo)
105
+
106
+ return f"✅ Protocolo salvo com sucesso ({len(fases)} fases)"
107
+ except json.JSONDecodeError as e:
108
  return f"❌ Erro no JSON: {str(e)}"
109
+ except Exception as e:
110
+ return f"❌ Erro: {str(e)}"
111
 
112
  def ler_anexo(arquivo):
113
  """Lê arquivo anexado"""
 
220
 
221
  try:
222
  protocolo = json.loads(json_config)
223
+
224
+ # Validar que protocolo tem todas as fases necessárias
225
+ fases_disponiveis = {f['fase'] for f in protocolo if isinstance(f, dict) and 'fase' in f}
226
+ if 7 not in fases_disponiveis:
227
+ history[-1][1] = "❌ **Erro: Fase 7 não encontrada no protocolo**\n\nO protocolo deve ter 10 fases (0-9)."
228
+ yield history, {}, "Erro: Fase 7 ausente"
229
+ return
230
+
231
  except Exception as e:
232
  history[-1][1] = f"❌ **Erro no JSON de Configuração**\n\n```\n{str(e)}\n```"
233
  yield history, {}, f"Erro JSON: {e}"
 
271
  iteracao = 0
272
  fase_7_passou = False
273
 
274
+ # Buscar configuração da fase 7 com segurança
275
+ cfg_fase7 = None
276
+ for f in protocolo:
277
+ if f.get('fase') == 7:
278
+ cfg_fase7 = f
279
+ break
280
+
281
+ if cfg_fase7 is None:
282
+ history[-1][1] = "❌ **Erro: Fase 7 (TESTE_CRUCIALIDADE) não encontrada**"
283
+ yield history, timeline, logs
284
+ return
285
+
286
  while iteracao < MAX_ITERACOES and not fase_7_passou:
287
  iteracao += 1
288
  logs += f"\n{'='*60}\n🔄 ITERAÇÃO {iteracao}/{MAX_ITERACOES}\n{'='*60}\n"
 
306
  yield history, timeline, logs
307
 
308
  # Executar Fase 7: TESTE_CRUCIALIDADE
 
309
  history[-1][1] = f"🧪 **Fase 7/10: Teste de Crucialidade** (Iteração {iteracao})\n\nValidando..."
310
  yield history, timeline, logs
311
 
 
319
  return
320
 
321
  # Verificar se passou no teste
322
+ teste_resultado = resultado.get('content', {})
323
  fase_7_passou = teste_resultado.get('PASSOU', False)
324
  score = teste_resultado.get('SCORE_CRUCIALIDADE', 0)
325
 
 
329
  else:
330
  logs += f"⚠️ TESTE FALHOU (score: {score:.3f})\n"
331
  fragilidades = teste_resultado.get('FRAGILIDADES_IDENTIFICADAS', [])
332
+ history[-1][1] = f"⚠️ **Validação Reprovada** (Score: {score:.3f})\n\nFragilidades:\n" + "\n".join(f"- {f}" for f in fragilidades[:5])
333
 
334
  yield history, timeline, logs
335
 
 
355
 
356
  # Se for a fase final (9 - RELATORIO_FINAL), mostrar resultado
357
  if cfg['fase'] == 9 and cfg['tipo_saida'] == 'texto':
358
+ final_response = resultado.get('content', 'Erro ao gerar relatório')
359
  history[-1][1] = final_response
360
 
361
  yield history, timeline, logs
 
400
  show_label=False,
401
  height=650,
402
  show_copy_button=True,
403
+ render_markdown=True,
404
+ type="tuples" # Explicitamente definido
405
  )
406
 
407
  with gr.Row():