caarleexx commited on
Commit
d30ba55
·
verified ·
1 Parent(s): b8be6be

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -560
app.py DELETED
@@ -1,560 +0,0 @@
1
-
2
- #!/usr/bin/env python3
3
- # -*- coding: utf-8 -*-
4
-
5
- """
6
- PIPELINE v19 - MOTOR CAUSAL COMPLETO
7
- Análise reflexiva com causalidade transparente e interface simplificada.
8
-
9
- Estrutura:
10
- 1. Engine causal (loop iterativo)
11
- 2. Formulário universal (N0 → CENARIOS → PRINCIPIOS → METACOG → RESPOSTA)
12
- 3. Interface Gradio v19 (chat + progresso + cópia)
13
-
14
- Requisitos:
15
- - pip install gradio google-generativeai
16
- """
17
-
18
- import json
19
- import re
20
- import sys
21
- from typing import Dict, List, Tuple, Optional
22
- from datetime import datetime
23
- import gradio as gr
24
-
25
- # ==================== CONFIG ====================
26
-
27
- API_KEY = "" # Preencher com sua chave API Gemini
28
- MODEL_NAME = "gemini-flash-latest"
29
- MAX_ITERACOES = 10
30
- TEMPERATURA_PADRAO = 0.6
31
-
32
- # ==================== IMPORTS (google generative AI) ====================
33
-
34
- try:
35
- import google.generativeai as genai
36
- genai.configure(api_key=API_KEY)
37
- counselor_model = genai.GenerativeModel(MODEL_NAME)
38
- except Exception as e:
39
- print(f"⚠️ Erro ao configurar Gemini: {e}")
40
- print(" Usando mock para testes")
41
- counselor_model = None
42
-
43
-
44
- # ==================== DNA SCHEMA ====================
45
-
46
- def criar_dna_vazio() -> Dict:
47
- """Cria estrutura de DNA vazia para novo chat."""
48
- return {
49
- "versao": "19.0",
50
- "criado_em": datetime.now().isoformat(),
51
-
52
- "historico_chat": [],
53
-
54
- "historico_passos": {
55
- "passo_causal": [],
56
- "passo_verificador": []
57
- },
58
-
59
- "memoria_contextual": {
60
- "ultimos_10_turnos": {
61
- "memoria_tipo": "clara",
62
- "indices_chat": [],
63
- "passos_completos": True
64
- },
65
- "turnos_anteriores": {
66
- "memoria_tipo": "vaga",
67
- "total_turnos_comprimidos": 0,
68
- "resumo_contexto_global": "",
69
- "temas_principais": [],
70
- "aprendizados_chave": []
71
- }
72
- },
73
-
74
- "metadados": {
75
- "total_turnos": 0,
76
- "ultimo_turno_limpeza": 0,
77
- "total_iteracoes": 0,
78
- "modo_sabio_enabled": False,
79
- "modo_supervisor_enabled": True
80
- }
81
- }
82
-
83
-
84
- # ==================== CHAMAR MODELO ====================
85
-
86
- def chamar_gemini(prompt: str, temperatura: float = 0.6) -> str:
87
- """Chama Gemini API com fallback para mock."""
88
-
89
- if not counselor_model:
90
- # Mock para testes
91
- return json.dumps({
92
- "tipo_input": "subjetiva_aberta",
93
- "proximo_passo": "CENARIOS",
94
- "cenarios": [
95
- {"id": 1, "desc": "Cenário A", "probabilidade": "mais_provavel"},
96
- {"id": 2, "desc": "Cenário B", "probabilidade": "menos_provavel"}
97
- ]
98
- })
99
-
100
- try:
101
- response = counselor_model.generate_content(
102
- prompt,
103
- generation_config=genai.types.GenerationConfig(temperature=temperatura)
104
- )
105
- return response.text
106
- except Exception as e:
107
- print(f"❌ Erro ao chamar Gemini: {e}")
108
- return json.dumps({"erro": str(e)})
109
-
110
-
111
- # ==================== FORMULÁRIO CAUSAL ====================
112
-
113
- class FormularioCausal:
114
- """Schema JSON do formulário universal."""
115
-
116
- @staticmethod
117
- def criar_inicial(
118
- input_usuario: str,
119
- ultimos_K_turnos: List[Dict],
120
- ultimos_5_passos: List[Dict],
121
- resumo_contextual: str = ""
122
- ) -> Dict:
123
- """Inicializa formulário para novo turno."""
124
- return {
125
- "turno_id": datetime.now().isoformat()[:19],
126
- "input_usuario_atual": input_usuario,
127
- "tipo_input": None,
128
-
129
- "contexto": {
130
- "ultimos_K_turnos": ultimos_K_turnos[-5:],
131
- "ultimos_5_passos": ultimos_5_passos[-5:] if ultimos_5_passos else [],
132
- "resumo_contextual": resumo_contextual
133
- },
134
-
135
- "formulario_causal": {
136
- "questoes_herdadas": [],
137
- "cenarios": [],
138
- "principios": [],
139
- "principios_ordenados": [],
140
- "principio_dominante": None,
141
- "solucao_parcial": "",
142
- "justificativa": [],
143
- "estado_duvida": None,
144
- "motivo_nao_resolvida": "",
145
- "proximo_passo": "N0",
146
- "questoes_para_proximo_passo": [],
147
- "o_que_ainda_nao_sei": []
148
- },
149
-
150
- "resposta_cognitiva": None,
151
- "iteracao_atual": 0
152
- }
153
-
154
-
155
- # ==================== PARSER ====================
156
-
157
- class ParserRespostaCausal:
158
- """Extrai JSON + RESPOSTA COGNITIVA."""
159
-
160
- @staticmethod
161
- def parsear(resposta_raw: str) -> Tuple[Dict, Optional[str]]:
162
- """Extrai formulário preenchido e RESPOSTA COGNITIVA."""
163
-
164
- formulario_preenchido = {}
165
- resposta_cognitiva = None
166
-
167
- # 1. Extrair JSON
168
- try:
169
- match_json = re.search(r'\{[\s\S]*\}', resposta_raw)
170
- if match_json:
171
- json_str = match_json.group(0)
172
- formulario_preenchido = json.loads(json_str)
173
- except json.JSONDecodeError:
174
- pass
175
-
176
- # 2. Extrair RESPOSTA COGNITIVA
177
- if "RESPOSTA COGNITIVA:" in resposta_raw:
178
- parts = resposta_raw.split("RESPOSTA COGNITIVA:")
179
- if len(parts) > 1:
180
- resposta_cognitiva = parts[1].strip()
181
-
182
- return formulario_preenchido, resposta_cognitiva
183
-
184
- @staticmethod
185
- def extrair_progresso_visual(formulario: Dict, iteracao: int) -> str:
186
- """Gera textbox visual do progresso."""
187
- form = formulario.get("formulario_causal", {})
188
- linhas = []
189
-
190
- linhas.append(f"📊 TURNO #{formulario.get('iteracao_atual', iteracao)}")
191
- linhas.append("=" * 50)
192
-
193
- # N0
194
- tipo = form.get("tipo_input", "?")
195
- linhas.append(f"\n🎓 PASSO N0: Aluno")
196
- linhas.append(f" ├─ Tipo: {tipo}")
197
- linhas.append(f" └─ ✓ Próximo: {form.get('proximo_passo', '?')}")
198
-
199
- # Cenários
200
- cenarios = form.get("cenarios", [])
201
- if cenarios:
202
- linhas.append(f"\n🎯 PASSO CENARIOS: {len(cenarios)} cenário(s)")
203
- for i, cen in enumerate(cenarios[:6], 1):
204
- prob_icon = "🟢" if cen.get("probabilidade") == "mais_provavel" else "🔵"
205
- desc = cen.get('desc', '?')[:40]
206
- linhas.append(f" {prob_icon} C{i}: {desc}...")
207
- linhas.append(f" └─ ✓ Próximo: {form.get('proximo_passo', '?')}")
208
-
209
- # Princípios
210
- princ_ord = form.get("principios_ordenados", [])
211
- if princ_ord:
212
- linhas.append(f"\n🔀 PASSO PRINCIPIOS: {len(princ_ord)} princípio(s)")
213
- medals = ["🥇", "🥈", "🥉"]
214
- for i, nome in enumerate(princ_ord[:3], 1):
215
- medal = medals[i-1] if i <= 3 else "▪"
216
- linhas.append(f" {medal} {nome}")
217
- linhas.append(f" └─ ✓ Próximo: {form.get('proximo_passo', '?')}")
218
-
219
- # Metacognição
220
- estado = form.get("estado_duvida")
221
- if estado:
222
- linhas.append(f"\n✨ PASSO METACOG: Avaliando...")
223
- linhas.append(f" ├─ Estado: {estado.upper()}")
224
- linhas.append(f" └─ ✓ Próximo: {form.get('proximo_passo', '?')}")
225
-
226
- # Status final
227
- linhas.append("\n" + "─" * 50)
228
- proximo = form.get("proximo_passo", "?")
229
- if proximo == "PERGUNTAR_USUARIO":
230
- linhas.append("⚠️ AGUARDANDO SUA RESPOSTA...")
231
- elif proximo == "SAIDA_FINAL":
232
- linhas.append("✅ PREPARANDO RESPOSTA FINAL...")
233
- else:
234
- linhas.append(f"🔄 Processando: {proximo}...")
235
-
236
- return "\n".join(linhas)
237
-
238
-
239
- # ==================== CONSTRUTORES DE PROMPT ====================
240
-
241
- class ConstrutorPromptsCausal:
242
- """Prompts dinâmicos por passo."""
243
-
244
- @staticmethod
245
- def construir(
246
- formulario: Dict,
247
- modo_sabio: bool = False,
248
- tipo_passo: str = "N0"
249
- ) -> str:
250
- """Constrói prompt para o passo."""
251
-
252
- form = formulario["formulario_causal"]
253
- contexto_str = json.dumps(formulario["contexto"], indent=2, ensure_ascii=False)
254
- form_str = json.dumps(form, indent=2, ensure_ascii=False)
255
- input_usuario = formulario["input_usuario_atual"]
256
-
257
- if tipo_passo == "N0":
258
- return f"""PASSO N0: ALUNO - CLASSIFICANDO INPUT
259
-
260
- INPUT DO USUÁRIO:
261
- "{input_usuario}"
262
-
263
- CONTEXTO:
264
- {contexto_str}
265
-
266
- TAREFA:
267
- 1. Classifique: factual | subjetiva_aberta | correcao | comentario | outro
268
- 2. Próximo passo: N0 | CENARIOS | EXPLORACAO | PRINCIPIOS | METACOG | PERGUNTAR_USUARIO | SAIDA_FINAL
269
-
270
- RETORNE JSON:
271
- {{"tipo_input": "...", "proximo_passo": "..."}}
272
- """
273
-
274
- elif tipo_passo == "CENARIOS":
275
- return f"""PASSO CENARIOS: MAPEANDO 1-6 CENÁRIOS
276
-
277
- INPUT: "{input_usuario}"
278
-
279
- CONTEXTO: {contexto_str}
280
-
281
- TAREFA:
282
- Mapeie 1-6 cenários com: desc, probabilidade (mais_provavel|menos_provavel), certezas, dúvidas.
283
-
284
- RETORNE JSON:
285
- {{"cenarios": [{{"id": 1, "desc": "...", "probabilidade": "...", "certezas": [...], "duvidas": [...]}}], "proximo_passo": "PRINCIPIOS"}}
286
- """
287
-
288
- elif tipo_passo == "PRINCIPIOS":
289
- return f"""PASSO PRINCIPIOS: ORDENANDO
290
-
291
- CENÁRIOS: {form_str}
292
-
293
- TAREFA:
294
- Identifique princípios (máx 5), atribua peso 1-5, ordene por relevância.
295
-
296
- RETORNE JSON:
297
- {{"principios": [...], "principios_ordenados": [...], "principio_dominante": "...", "proximo_passo": "METACOG"}}
298
- """
299
-
300
- elif tipo_passo == "METACOG":
301
- return f"""PASSO METACOG: CERTEZAS vs DÚVIDAS
302
-
303
- FORMULÁRIO: {form_str}
304
-
305
- TAREFA:
306
- Aplique princípio dominante. Se houver empate: estado_duvida="parcial", proximo_passo="PERGUNTAR_USUARIO".
307
- Senão: estado_duvida="resolvida", proximo_passo="SAIDA_FINAL".
308
-
309
- RETORNE JSON:
310
- {{"estado_duvida": "...", "proximo_passo": "...", "pergunta_desempate": "..."}}
311
- """
312
-
313
- elif tipo_passo == "PERGUNTAR_USUARIO":
314
- return f"""PASSO PERGUNTAR_USUARIO: DESEMPATE
315
-
316
- CENÁRIOS EM QUESTÃO: {form_str}
317
-
318
- Formule pergunta clara. Finalize com: RESPOSTA COGNITIVA: [pergunta]
319
-
320
- RETORNE JSON:
321
- {{"proximo_passo": "N0"}}
322
-
323
- RESPOSTA:
324
- """
325
-
326
- else:
327
- return f"Passo desconhecido: {tipo_passo}"
328
-
329
-
330
- # ==================== ENGINE CAUSAL ====================
331
-
332
- class EngineCausal:
333
- """Motor iterativo v19."""
334
-
335
- def __init__(self, dna: Dict, modo_sabio: bool = False, max_iteracoes: int = 10):
336
- self.dna = dna
337
- self.modo_sabio = modo_sabio
338
- self.max_iteracoes = max_iteracoes
339
-
340
- def processar_turno(self) -> Tuple[str, str, Dict]:
341
- """Executa loop causal completo."""
342
-
343
- if len(self.dna["historico_chat"]) == 0:
344
- return "", "Erro: nenhuma mensagem", self.dna
345
-
346
- mensagem_usuario = self.dna["historico_chat"][-1]["user"]
347
-
348
- # Inicializar formulário
349
- formulario = FormularioCausal.criar_inicial(
350
- input_usuario=mensagem_usuario,
351
- ultimos_K_turnos=self.dna["historico_chat"][-5:],
352
- ultimos_5_passos=self.dna["historico_passos"]["passo_causal"][-5:],
353
- resumo_contextual=self.dna["memoria_contextual"]["turnos_anteriores"].get(
354
- "resumo_contexto_global", ""
355
- )
356
- )
357
-
358
- resposta_final = None
359
- progresso_text = ""
360
-
361
- # Loop iterativo
362
- for iteracao in range(1, self.max_iteracoes + 1):
363
- formulario["iteracao_atual"] = iteracao
364
-
365
- print(f"\n🔄 Iteração {iteracao}")
366
- print(f" Passo: {formulario['formulario_causal']['proximo_passo']}")
367
-
368
- # Construir e chamar
369
- prompt = ConstrutorPromptsCausal.construir(
370
- formulario=formulario,
371
- modo_sabio=self.modo_sabio,
372
- tipo_passo=formulario["formulario_causal"]["proximo_passo"]
373
- )
374
-
375
- resposta_raw = chamar_gemini(prompt, temperatura=TEMPERATURA_PADRAO)
376
-
377
- # Parsear
378
- formulario_novo, resposta_cognitiva = ParserRespostaCausal.parsear(resposta_raw)
379
-
380
- # Mesclar
381
- if formulario_novo and "formulario_causal" in formulario_novo:
382
- formulario["formulario_causal"].update(formulario_novo["formulario_causal"])
383
-
384
- # Progresso visual
385
- progresso_text = ParserRespostaCausal.extrair_progresso_visual(formulario, iteracao)
386
-
387
- # Registrar
388
- self.dna["historico_passos"]["passo_causal"].append({
389
- "iteracao": iteracao,
390
- "passo_tipo": formulario["formulario_causal"].get("proximo_passo", "N0"),
391
- "timestamp": datetime.now().isoformat()
392
- })
393
-
394
- # Verificar RESPOSTA COGNITIVA
395
- if resposta_cognitiva:
396
- print(f" ✅ RESPOSTA COGNITIVA em iteração {iteracao}")
397
- resposta_final = resposta_cognitiva
398
- break
399
-
400
- # Fallback
401
- if not resposta_final:
402
- resposta_final = (
403
- "Não consegui chegar a uma resposta dentro do limite. "
404
- "Poderia esclarecer melhor sua pergunta?"
405
- )
406
-
407
- # Atualizar chat
408
- self.dna["historico_chat"][-1]["assistant"] = resposta_final
409
-
410
- return resposta_final, progresso_text, self.dna
411
-
412
-
413
- # ==================== INTERFACE GRADIO ====================
414
-
415
- def criar_interface_gradio() -> gr.Blocks:
416
- """Cria interface Gradio v19."""
417
-
418
- dna_global = criar_dna_vazio()
419
-
420
- with gr.Blocks(title="Pipeline v19 - Causal", theme=gr.themes.Soft()) as interface:
421
-
422
- gr.Markdown("""
423
- # 🧠 Pipeline v19 - Motor Causal
424
-
425
- Análise reflexiva com causalidade transparente.
426
- O modelo escolhe os próximos passos com base em dúvidas abertas.
427
- """)
428
-
429
- with gr.Row():
430
- with gr.Column(scale=3):
431
-
432
- # Chat
433
- chat_display = gr.Chatbot(
434
- label="💬 Conversa",
435
- height=400,
436
- show_label=True
437
- )
438
-
439
- # Progresso
440
- progresso_text = gr.Textbox(
441
- label="📊 Progresso dos Passos",
442
- lines=8,
443
- interactive=False,
444
- value="Aguardando primeira mensagem..."
445
- )
446
-
447
- with gr.Row():
448
- msg_input = gr.Textbox(
449
- label="Sua mensagem",
450
- placeholder="Digite sua pergunta...",
451
- lines=2,
452
- interactive=True,
453
- scale=9
454
- )
455
- enviar_btn = gr.Button("📤", scale=1, variant="primary")
456
-
457
-
458
-
459
- # Botões
460
- with gr.Row():
461
- #enviar_btn = gr.Button("📤 Enviar", variant="primary")
462
- limpar_btn = gr.Button("🗑️ Limpar")
463
- copiar_btn = gr.Button("📋 Copiar")
464
-
465
- # Checkboxes
466
- with gr.Row():
467
- modo_sabio = gr.Checkbox(label="💚 Modo Sábio", value=True)
468
- modo_supervisor = gr.Checkbox(label="🛡️ Supervisor", value=True)
469
-
470
- # Cópia
471
- copia_display = gr.Textbox(
472
- label="📄 Cópia da Conversa",
473
- lines=6,
474
- interactive=True
475
- )
476
-
477
- # Callbacks
478
- def processar():
479
- msg = msg_input.value
480
- if not msg.strip():
481
- return chat_display.value, "", ""
482
-
483
- # Adicionar ao chat
484
- chat_list = chat_display.value if chat_display.value else []
485
- dna_global["historico_chat"].append({
486
- "user": msg,
487
- "assistant": None,
488
- "timestamp": datetime.now().isoformat()
489
- })
490
- dna_global["metadados"]["total_turnos"] += 1
491
-
492
- # Processar
493
- engine = EngineCausal(dna_global, modo_sabio=modo_sabio.value)
494
- resposta, progresso, _ = engine.processar_turno()
495
-
496
- # Atualizar displays
497
- chat_list.append([msg, resposta])
498
-
499
- copia_linhas = []
500
- for i, (user, bot) in enumerate(chat_list, 1):
501
- copia_linhas.append(f"Turno {i}:\n👤 {user}\n🤖 {bot}\n")
502
- copia_text = "\n".join(copia_linhas)
503
-
504
- return chat_list, progresso, copia_text
505
-
506
- def limpar():
507
- nonlocal dna_global
508
- dna_global = criar_dna_vazio()
509
- return [], "", ""
510
-
511
- def copiar():
512
- chat_list = chat_display.value if chat_display.value else []
513
- copia_linhas = []
514
- for i, (user, bot) in enumerate(chat_list, 1):
515
- copia_linhas.append(f"Turno {i}:\n👤 {user}\n🤖 {bot}\n")
516
- return "\n".join(copia_linhas)
517
-
518
- enviar_btn.click(
519
- processar,
520
- inputs=[],
521
- outputs=[chat_display, progresso_text, copia_display]
522
- )
523
-
524
- msg_input.submit(
525
- processar,
526
- inputs=[],
527
- outputs=[chat_display, progresso_text, copia_display]
528
- )
529
-
530
- limpar_btn.click(
531
- limpar,
532
- inputs=[],
533
- outputs=[chat_display, progresso_text, msg_input, copia_display]
534
- )
535
-
536
- copiar_btn.click(
537
- copiar,
538
- inputs=[],
539
- outputs=[copia_display]
540
- )
541
-
542
- return interface
543
-
544
-
545
- # ==================== MAIN ====================
546
-
547
- if __name__ == "__main__":
548
- print("\n" + "="*70)
549
- print("🚀 PIPELINE v19 - MOTOR CAUSAL")
550
- print("="*70)
551
- print(f"Modelo: {MODEL_NAME}")
552
- print(f"Max iterações: {MAX_ITERACOES}")
553
- print("="*70 + "\n")
554
-
555
- interface = criar_interface_gradio()
556
- interface.launch(
557
- share=False,
558
- server_name="0.0.0.0",
559
- server_port=7860
560
- )