caarleexx commited on
Commit
a6d72c9
·
verified ·
1 Parent(s): 18e002c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -46
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # --- INÍCIO DO CÓDIGO FINAL ---
2
 
3
  import gradio as gr
4
  import os
@@ -14,7 +14,7 @@ if not api_key:
14
  genai.configure(api_key=api_key)
15
  model = genai.GenerativeModel('gemini-2.5-pro')
16
 
17
- # --- PROMPT DE SISTEMA MESTRE (SEGUINDO SEU PROTOCOLO) ---
18
  PROMPT_SISTEMA = """
19
  Você é um especialista em análise de intenções que opera sob um protocolo de 5 passos.
20
  Sua função é conduzir uma conversa para entender completamente a dúvida de um usuário ANTES de respondê-la.
@@ -29,7 +29,7 @@ Analise o `estado_pipeline` atual e o `historico_conversa`. Decida qual passo ex
29
  - **Meta:** A dúvida é compreensível?
30
  - **Ação:** Analise o `duvida_inicial`.
31
  - **Decisão:**
32
- - Se a clareza for 'baixa' (ex: "flibbertigibbet quântico"), sua resposta JSON DEVE conter: `{"proximo_passo": "aguardando_usuario", "pergunta_para_usuario": "Interessante! O termo que você usou não é padrão. Poderia me dar mais contexto?", ...}`.
33
  - Se a clareza for 'media' ou 'alta', atualize `estado.clareza.confianca` para 'alta' e defina `proximo_passo` como `"passo_2_proposito"`.
34
 
35
  ---
@@ -37,7 +37,7 @@ Analise o `estado_pipeline` atual e o `historico_conversa`. Decida qual passo ex
37
  - **Meta:** Para qual fim a resposta servirá?
38
  - **Ação:** Analise o histórico para inferir o objetivo prático (`para_que`).
39
  - **Decisão:**
40
- - Se a confiança for 'baixa' (ex: uma pergunta ampla como "o que é asteroide?"), sua resposta JSON DEVE conter: `{"proximo_passo": "aguardando_usuario", "pergunta_para_usuario": "Claro! Para te dar a melhor resposta, qual o seu objetivo? Você está estudando, curioso, escrevendo uma história...?", ...}`.
41
  - Se a confiança for 'media' ou 'alta', preencha `estado.proposito.valor` e `estado.proposito.confianca`, e defina `proximo_passo` como `"passo_3_motivacao"`.
42
 
43
  ---
@@ -51,9 +51,9 @@ Analise o `estado_pipeline` atual e o `historico_conversa`. Decida qual passo ex
51
  ---
52
  **Passo 4: Análise de Coerência**
53
  - **Meta:** As informações coletadas fazem sentido juntas?
54
- - **Ação:** Revise `clareza`, `proposito` e `motivacao` em busca de contradições ou lacunas.
55
  - **Decisão:**
56
- - Se a coerência for 'baixa' (ex: propósito é 'estudo', motivação é 'medo de impacto'), formule uma pergunta para resolver a incerteza. Ex: `{"pergunta_para_usuario": "Ok, entendi que é para estudo, mas notei uma preocupação. Você gostaria de focar nos aspectos científicos ou também nos riscos de impacto?", ...}` e `proximo_passo` como `aguardando_usuario`.
57
  - Se a coerência for 'alta', atualize `estado.coerencia.confianca` e defina `proximo_passo` como `"passo_5_resposta_final"`.
58
 
59
  ---
@@ -61,21 +61,22 @@ Analise o `estado_pipeline` atual e o `historico_conversa`. Decida qual passo ex
61
  - **Meta:** Tenho tudo para dar uma resposta completa e personalizada.
62
  - **Ação:** Verifique se todos os passos anteriores têm confiança 'media' ou 'alta'.
63
  - **Decisão:**
64
- - Se sim, construa uma resposta final detalhada, adaptada ao propósito e motivação do usuário. Coloque essa resposta no campo `"resposta_final"` do JSON. Defina `"proximo_passo"` como `"concluido"`.
65
  - Se não, volte ao passo com a confiança mais baixa e formule uma nova pergunta.
66
 
67
  **ESTRUTURA JSON DE SAÍDA OBRIGATÓRIA:**
68
  {
69
- "raciocinio_do_passo": "Sua breve justificativa interna para a decisão tomada.",
70
- "proximo_passo": "string", // "passo_2_proposito", "passo_3_motivacao", "aguardando_usuario", "concluido", etc.
71
- "pergunta_para_usuario": "string | null", // A pergunta exata a ser feita ao usuário, se houver.
72
- "estado_pipeline_atualizado": { ... }, // O objeto de estado completo e atualizado.
73
- "resposta_final": "string | null" // A resposta final, apenas no Passo 5.
74
  }
75
  """
76
 
77
  # --- GERENCIAMENTO DE ESTADO ---
78
  def resetar_estado():
 
79
  return {
80
  "passo_atual": "passo_1_clareza",
81
  "duvida_inicial": None,
@@ -86,62 +87,55 @@ def resetar_estado():
86
  }
87
 
88
  estado_pipeline_global = resetar_estado()
89
- historico_conversa_global = []
90
 
91
  # --- FUNÇÃO PRINCIPAL DO CHATBOT ---
92
  def handle_chat(mensagem, historico_chat_gradio):
93
- global estado_pipeline_global, historico_conversa_global
94
 
95
- # Adiciona a mensagem atual ao histórico da conversa
96
- historico_conversa_global.append({"role": "user", "content": mensagem})
 
 
 
 
97
 
98
- # Se for a primeira mensagem, define a dúvida inicial no estado
 
99
  if estado_pipeline_global["duvida_inicial"] is None:
100
  estado_pipeline_global["duvida_inicial"] = mensagem
101
 
102
- # Constrói o prompt para o Gemini
103
  prompt_completo = f"""
104
  {PROMPT_SISTEMA}
105
-
106
  ---
107
- **HISTÓRICO DA CONVERSA ATÉ AGORA:**
108
- {json.dumps(historico_conversa_global, indent=2)}
109
-
110
  ---
111
  **ESTADO ATUAL DA PIPELINE:**
112
  {json.dumps(estado_pipeline_global, indent=2)}
113
  ---
114
-
115
- **Instrução Final:** Baseado no estado e no histórico, execute o próximo passo do protocolo e gere o JSON de saída correspondente.
116
  """
117
 
118
  try:
119
  response = model.generate_content(prompt_completo)
120
-
121
- # Limpa e extrai o JSON da resposta
122
  resposta_texto = response.text.strip().replace("```json", "").replace("```", "")
123
  decisao_json = json.loads(resposta_texto)
124
 
125
- # O LLM é a fonte da verdade: atualiza o estado global com o que foi retornado
126
  estado_pipeline_global = decisao_json.get("estado_pipeline_atualizado", estado_pipeline_global)
127
 
128
- # Decide o que mostrar ao usuário
129
  if decisao_json.get("resposta_final"):
130
  resposta_para_usuario = decisao_json["resposta_final"]
131
- historico_conversa_global.append({"role": "model", "content": resposta_para_usuario})
132
- # Reseta tudo para a próxima conversa
133
- estado_pipeline_global = resetar_estado()
134
- historico_conversa_global = []
135
  return resposta_para_usuario
136
 
137
  elif decisao_json.get("pergunta_para_usuario"):
138
  resposta_para_usuario = decisao_json["pergunta_para_usuario"]
139
- historico_conversa_global.append({"role": "model", "content": resposta_para_usuario})
140
  return resposta_para_usuario
141
 
142
  else:
143
- # Caso de erro onde o JSON é válido mas não tem ação para o usuário
144
- return "Ocorreu um erro no meu raciocínio. Poderia tentar reformular sua pergunta?"
145
 
146
  except (json.JSONDecodeError, AttributeError, Exception) as e:
147
  print(f"Erro ao processar resposta da API: {e}")
@@ -149,17 +143,10 @@ def handle_chat(mensagem, historico_chat_gradio):
149
  print(f"Resposta recebida: {response.text}")
150
  except:
151
  print("Não foi possível extrair o texto da resposta.")
152
- return "Desculpe, tive um problema técnico ao processar sua solicitação. Por favor, tente novamente."
153
-
154
 
155
  # --- INTERFACE GRADIO ---
156
- def on_clear_chat():
157
- """Função para ser chamada quando o botão 'Clear' do Gradio é pressionado."""
158
- global estado_pipeline_global, historico_conversa_global
159
- estado_pipeline_global = resetar_estado()
160
- historico_conversa_global = []
161
- print("Chat e estado resetados.")
162
-
163
  iface = gr.ChatInterface(
164
  fn=handle_chat,
165
  title="🤖 Protótipo de IA com Protocolo de Raciocínio",
@@ -167,9 +154,8 @@ iface = gr.ChatInterface(
167
  chatbot=gr.Chatbot(height=500),
168
  textbox=gr.Textbox(placeholder="Qual é a sua dúvida?", container=False, scale=7),
169
  )
170
- iface.clear_btn.click(on_clear_chat) # Garante que o estado interno seja limpo junto com o chat
171
 
172
  if __name__ == "__main__":
173
  iface.launch()
174
 
175
- # --- FIM DO CÓDIGO FINAL ---
 
1
+ # --- INÍCIO DO CÓDIGO CORRIGIDO E FINAL ---
2
 
3
  import gradio as gr
4
  import os
 
14
  genai.configure(api_key=api_key)
15
  model = genai.GenerativeModel('gemini-2.5-pro')
16
 
17
+ # --- PROMPT DE SISTEMA MESTRE ---
18
  PROMPT_SISTEMA = """
19
  Você é um especialista em análise de intenções que opera sob um protocolo de 5 passos.
20
  Sua função é conduzir uma conversa para entender completamente a dúvida de um usuário ANTES de respondê-la.
 
29
  - **Meta:** A dúvida é compreensível?
30
  - **Ação:** Analise o `duvida_inicial`.
31
  - **Decisão:**
32
+ - Se a clareza for 'baixa', sua resposta JSON DEVE conter: `{"proximo_passo": "aguardando_usuario", "pergunta_para_usuario": "Interessante! O termo que você usou não é padrão. Poderia me dar mais contexto?", ...}`.
33
  - Se a clareza for 'media' ou 'alta', atualize `estado.clareza.confianca` para 'alta' e defina `proximo_passo` como `"passo_2_proposito"`.
34
 
35
  ---
 
37
  - **Meta:** Para qual fim a resposta servirá?
38
  - **Ação:** Analise o histórico para inferir o objetivo prático (`para_que`).
39
  - **Decisão:**
40
+ - Se a confiança for 'baixa', sua resposta JSON DEVE conter: `{"proximo_passo": "aguardando_usuario", "pergunta_para_usuario": "Claro! Para te dar a melhor resposta, qual o seu objetivo? Você está estudando, curioso, escrevendo uma história...?", ...}`.
41
  - Se a confiança for 'media' ou 'alta', preencha `estado.proposito.valor` e `estado.proposito.confianca`, e defina `proximo_passo` como `"passo_3_motivacao"`.
42
 
43
  ---
 
51
  ---
52
  **Passo 4: Análise de Coerência**
53
  - **Meta:** As informações coletadas fazem sentido juntas?
54
+ - **Ação:** Revise `clareza`, `proposito` e `motivacao`.
55
  - **Decisão:**
56
+ - Se a coerência for 'baixa', formule uma pergunta para resolver a incerteza e defina `proximo_passo` como `aguardando_usuario`.
57
  - Se a coerência for 'alta', atualize `estado.coerencia.confianca` e defina `proximo_passo` como `"passo_5_resposta_final"`.
58
 
59
  ---
 
61
  - **Meta:** Tenho tudo para dar uma resposta completa e personalizada.
62
  - **Ação:** Verifique se todos os passos anteriores têm confiança 'media' ou 'alta'.
63
  - **Decisão:**
64
+ - Se sim, construa uma resposta final adaptada. Coloque essa resposta no campo `"resposta_final"` do JSON. Defina `"proximo_passo"` como `"concluido"`.
65
  - Se não, volte ao passo com a confiança mais baixa e formule uma nova pergunta.
66
 
67
  **ESTRUTURA JSON DE SAÍDA OBRIGATÓRIA:**
68
  {
69
+ "raciocinio_do_passo": "Sua breve justificativa interna.",
70
+ "proximo_passo": "string",
71
+ "pergunta_para_usuario": "string | null",
72
+ "estado_pipeline_atualizado": { ... },
73
+ "resposta_final": "string | null"
74
  }
75
  """
76
 
77
  # --- GERENCIAMENTO DE ESTADO ---
78
  def resetar_estado():
79
+ print("Resetando o estado da pipeline para uma nova conversa.")
80
  return {
81
  "passo_atual": "passo_1_clareza",
82
  "duvida_inicial": None,
 
87
  }
88
 
89
  estado_pipeline_global = resetar_estado()
90
+ historico_conversa_llm = []
91
 
92
  # --- FUNÇÃO PRINCIPAL DO CHATBOT ---
93
  def handle_chat(mensagem, historico_chat_gradio):
94
+ global estado_pipeline_global, historico_conversa_llm
95
 
96
+ # CORREÇÃO PRINCIPAL: Detecta se é o início de uma conversa.
97
+ # O histórico do Gradio estar vazio significa que o usuário acabou de abrir
98
+ # a página ou clicou em "Clear".
99
+ if not historico_chat_gradio:
100
+ estado_pipeline_global = resetar_estado()
101
+ historico_conversa_llm = []
102
 
103
+ historico_conversa_llm.append({"role": "user", "parts": [mensagem]})
104
+
105
  if estado_pipeline_global["duvida_inicial"] is None:
106
  estado_pipeline_global["duvida_inicial"] = mensagem
107
 
 
108
  prompt_completo = f"""
109
  {PROMPT_SISTEMA}
 
110
  ---
111
+ **HISTÓRICO DA CONVERSA PARA O LLM:**
112
+ {json.dumps(historico_conversa_llm, indent=2)}
 
113
  ---
114
  **ESTADO ATUAL DA PIPELINE:**
115
  {json.dumps(estado_pipeline_global, indent=2)}
116
  ---
117
+ **Instrução Final:** Baseado no estado e no histórico, execute o próximo passo do protocolo e gere o JSON de saída.
 
118
  """
119
 
120
  try:
121
  response = model.generate_content(prompt_completo)
 
 
122
  resposta_texto = response.text.strip().replace("```json", "").replace("```", "")
123
  decisao_json = json.loads(resposta_texto)
124
 
 
125
  estado_pipeline_global = decisao_json.get("estado_pipeline_atualizado", estado_pipeline_global)
126
 
 
127
  if decisao_json.get("resposta_final"):
128
  resposta_para_usuario = decisao_json["resposta_final"]
129
+ historico_conversa_llm.append({"role": "model", "parts": [resposta_para_usuario]})
 
 
 
130
  return resposta_para_usuario
131
 
132
  elif decisao_json.get("pergunta_para_usuario"):
133
  resposta_para_usuario = decisao_json["pergunta_para_usuario"]
134
+ historico_conversa_llm.append({"role": "model", "parts": [resposta_para_usuario]})
135
  return resposta_para_usuario
136
 
137
  else:
138
+ return "Ocorreu um erro no meu raciocínio. Poderia tentar reformular?"
 
139
 
140
  except (json.JSONDecodeError, AttributeError, Exception) as e:
141
  print(f"Erro ao processar resposta da API: {e}")
 
143
  print(f"Resposta recebida: {response.text}")
144
  except:
145
  print("Não foi possível extrair o texto da resposta.")
146
+ return "Desculpe, tive um problema técnico. Por favor, clique em 'Clear' e tente novamente."
 
147
 
148
  # --- INTERFACE GRADIO ---
149
+ # REMOVIDO: A função on_clear_chat e a linha iface.clear_btn.click não são mais necessárias.
 
 
 
 
 
 
150
  iface = gr.ChatInterface(
151
  fn=handle_chat,
152
  title="🤖 Protótipo de IA com Protocolo de Raciocínio",
 
154
  chatbot=gr.Chatbot(height=500),
155
  textbox=gr.Textbox(placeholder="Qual é a sua dúvida?", container=False, scale=7),
156
  )
 
157
 
158
  if __name__ == "__main__":
159
  iface.launch()
160
 
161
+ # --- FIM DO CÓDIGO CORRIGIDO E FINAL ---