rwayz commited on
Commit
a31d1ab
·
verified ·
1 Parent(s): e967af6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +187 -95
app.py CHANGED
@@ -1,21 +1,16 @@
1
  import os
2
  import time
3
  import shutil
4
- import logging
5
  import pandas as pd
6
- import asyncio
7
- from dotenv import load_dotenv
8
  from sqlalchemy import create_engine
9
- from sqlalchemy.types import DateTime, Integer, Float
10
- from langchain_community.utilities import SQLDatabase
11
  from langchain_openai import ChatOpenAI
12
  from langchain_community.agent_toolkits import create_sql_agent
 
13
  from huggingface_hub import InferenceClient
14
- from langgraph.graph import StateGraph, END
15
- from langgraph.prebuilt import ToolNode
16
- from langchain_core.tools import tool
17
- from langgraph.checkpoint.sqlite import SqliteSaver
18
  import gradio as gr
 
 
 
19
 
20
  load_dotenv()
21
 
@@ -25,6 +20,7 @@ os.makedirs(UPLOAD_DIR, exist_ok=True)
25
  DEFAULT_CSV_PATH = "tabela.csv"
26
  UPLOADED_CSV_PATH = os.path.join(UPLOAD_DIR, "tabela.csv")
27
  SQL_DB_PATH = "data.db"
 
28
  HUGGINGFACE_API_KEY = os.getenv("HUGGINGFACE_API_KEY")
29
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
30
 
@@ -40,27 +36,37 @@ MAX_TOKENS_MAP = {
40
  "Qwen/QwQ-32B": 8192
41
  }
42
 
43
- hf_client = InferenceClient(provider="together", api_key=HUGGINGFACE_API_KEY)
 
 
 
44
  os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
45
 
46
  query_cache = {}
47
- history_log = []
48
- recent_history = []
49
  show_history_flag = False
50
- advanced_mode_enabled = False
51
- engine = None
 
52
 
53
  def get_active_csv_path():
 
54
  if os.path.exists(UPLOADED_CSV_PATH):
 
55
  return UPLOADED_CSV_PATH
56
  else:
 
57
  return DEFAULT_CSV_PATH
58
 
59
  def create_engine_and_load_db(csv_path, sql_db_path):
60
  if os.path.exists(sql_db_path):
 
61
  return create_engine(f"sqlite:///{sql_db_path}")
62
  else:
 
63
  engine = create_engine(f"sqlite:///{sql_db_path}")
 
64
  df = pd.read_csv(
65
  csv_path,
66
  sep=";",
@@ -69,16 +75,25 @@ def create_engine_and_load_db(csv_path, sql_db_path):
69
  dayfirst=True,
70
  on_bad_lines="skip"
71
  )
72
- colunas_para_float = ["PRECO_VISTA", "PRECO_CHEIO"]
73
- colunas_para_int = ["QUANTIDADE", "TOTAL_PAGINAS_CAPA", "VALOR_MEDIDA", "DIAS_VALIDADE"]
 
 
 
 
 
 
 
74
  for col in colunas_para_float:
75
  if col in df.columns:
76
  df[col] = pd.to_numeric(df[col].replace("-", None), errors="coerce")
 
77
  for col in colunas_para_int:
78
  if col in df.columns:
79
  df[col] = pd.to_numeric(df[col].replace("-", None), errors="coerce")
80
  df[col] = df[col].where(df[col].dropna() == df[col].dropna().astype(int))
81
  df[col] = df[col].astype("Int64")
 
82
  sql_dtype = {
83
  "DATA_INICIAL": DateTime(),
84
  "DATA_FINAL": DateTime(),
@@ -88,40 +103,73 @@ def create_engine_and_load_db(csv_path, sql_db_path):
88
  "TOTAL_PAGINAS_CAPA": Integer(),
89
  "VALOR_MEDIDA": Integer(),
90
  "DIAS_VALIDADE": Integer()
 
91
  }
 
 
 
 
92
  df.to_sql("tabela", engine, index=False, if_exists="replace", dtype=sql_dtype)
 
93
  return engine
94
 
95
  def handle_csv_upload(file):
96
  global engine, db, sql_agent
 
97
  try:
98
  file_path = file.name
99
  shutil.copy(file_path, UPLOADED_CSV_PATH)
 
 
100
  engine = create_engine_and_load_db(UPLOADED_CSV_PATH, SQL_DB_PATH)
101
  db = SQLDatabase(engine=engine)
102
- sql_agent = create_sql_agent(ChatOpenAI(model="gpt-4o-mini", temperature=0), db=db, agent_type="openai-tools", verbose=True, max_iterations=40, return_intermediate_steps=True)
 
 
 
 
 
 
 
 
 
 
 
103
  query_cache.clear()
104
  history_log.clear()
105
  recent_history.clear()
 
106
  return "✅ CSV carregado com sucesso!"
 
107
  except Exception as e:
 
108
  return f"❌ Erro ao processar CSV: {e}"
109
 
110
  def reset_app():
111
  global engine, db, sql_agent, query_cache, history_log, recent_history
 
112
  try:
113
  if os.path.exists(UPLOADED_CSV_PATH):
114
  os.remove(UPLOADED_CSV_PATH)
 
 
115
  engine = create_engine_and_load_db(DEFAULT_CSV_PATH, SQL_DB_PATH)
116
  db = SQLDatabase(engine=engine)
117
  sql_agent = create_sql_agent(ChatOpenAI(model="gpt-4o-mini", temperature=0), db=db, agent_type="openai-tools", verbose=True, max_iterations=40, return_intermediate_steps=True)
118
  query_cache.clear()
119
  history_log.clear()
120
  recent_history.clear()
 
121
  return "🔄 Sistema resetado para o estado inicial."
 
122
  except Exception as e:
123
  return f"❌ Erro ao resetar: {e}"
124
 
 
 
 
 
 
125
  def generate_initial_context(db_sample):
126
  return (
127
  f"Você é um assistente que gera queries SQL objetivas e eficientes. Sempre inclua LIMIT 20 nas queries. Aqui está o banco de dados:\n\n"
@@ -129,103 +177,146 @@ def generate_initial_context(db_sample):
129
  "\n***IMPORTANTE***: Detecte automaticamente o idioma da pergunta do usuário e responda sempre no mesmo idioma."
130
  "\nEsta base contém os SKUs (produtos) que foram promocionados por meio de TABLOIDE OU PROMOCAO OU ANUNCIO.\n"
131
  "Cada linha representa um SKU OU PRODUTO único PRESENTE NO TABLOIDE OU PROMOCAO OU ANUNCIO, incluindo sua descrição completa, os veículos OU MIDIAS de promoção utilizados e o respectivo período em que a promoção ocorreu.\n"
 
132
  "\nInformações imporatantes:\n"
133
  "- Use `LIKE '%<palavras-chave>%'` para buscas em colunas de texto.\n"
134
  "- Quando o usuário mencionar uma categoria, procure nas colunas: `CATEGORIA_PRODUTO_SKU`.\n"
135
  "- Se o usuário se referir a Nestle, o jeito correto de se escrever é Nestle sem acento e não Nestlé.\n"
136
  "- Você está usando um banco de dados SQLite.\n"
 
137
  "\nRetorne apenas a pergunta e a query SQL mais eficiente para entregar ao agent SQL do LangChain para gerar uma resposta para a pergunta. O formato deve ser:\n"
138
  "\nPergunta: <pergunta do usuário>\n"
139
  "\nOpção de Query SQL:\n<query SQL>"
140
  "\nIdioma: <idioma>"
141
  )
142
 
143
- @tool
144
- def llama_to_sql(question: str) -> str:
145
- column_data = pd.read_sql_query("SELECT * FROM tabela LIMIT 10", engine)
146
- initial_context = generate_initial_context(column_data)
147
- formatted_history = "\n".join([f"{msg['role'].capitalize()}: {msg['content']}" for msg in recent_history[-2:]])
148
- full_prompt = f"{initial_context}\n\nHistórico recente:\n{formatted_history}\n\nPergunta do usuário:\n{question}"
149
- model_id = LLAMA_MODELS["LLaMA 70B"]
150
- response = hf_client.chat.completions.create(
151
- model=model_id,
152
- messages=[{"role": "system", "content": full_prompt}],
153
- max_tokens=MAX_TOKENS_MAP[model_id],
154
- stream=False
155
  )
156
- return response["choices"][0]["message"]["content"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
 
158
- @tool
159
- def execute_sql_query(sql_query: str) -> str:
160
- response = sql_agent.invoke({"input": sql_query})
161
- return response.get("output", "Erro ao obter a resposta do agente.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
- @tool
164
- def refine_answer(answer: str, question: str) -> str:
165
- if not advanced_mode_enabled:
166
- return answer
167
  prompt = (
168
- f"Pergunta do usuário:\n{question}\n\n"
169
- f"Resposta gerada pelo agente SQL:\n{answer}\n\n"
170
- "Sua tarefa é refinar, complementar e melhorar a resposta. Adicione interpretações estatísticas ou insights relevantes."
 
171
  )
172
- response = hf_client.chat.completions.create(
173
- model=LLAMA_MODELS["LLaMA 70B"],
174
- messages=[{"role": "system", "content": prompt}],
175
- max_tokens=1200,
176
- stream=False
177
- )
178
- return response["choices"][0]["message"]["content"]
179
-
180
- tool_node = ToolNode([llama_to_sql, execute_sql_query, refine_answer])
181
-
182
- class GraphState(dict):
183
- question: str
184
- tool: str
185
- tool_input: dict
186
- result: str
187
-
188
- async def node_generate_sql(state: GraphState):
189
- state["tool"] = "llama_to_sql"
190
- state["tool_input"] = {"question": state["question"]}
191
- return await tool_node.ainvoke(state)
192
-
193
- async def node_execute_sql(state: GraphState):
194
- state["tool"] = "execute_sql_query"
195
- state["tool_input"] = {"sql_query": state["result"]}
196
- return await tool_node.ainvoke(state)
197
-
198
- async def node_refine_if_enabled(state: GraphState):
199
- state["tool"] = "refine_answer"
200
- state["tool_input"] = {"answer": state["result"], "question": state["question"]}
201
- return await tool_node.ainvoke(state)
202
-
203
- builder = StateGraph(GraphState)
204
- builder.add_node("generate_sql", node_generate_sql)
205
- builder.add_node("execute_sql", node_execute_sql)
206
- builder.add_node("refine", node_refine_if_enabled)
207
- builder.set_entry_point("generate_sql")
208
- builder.add_edge("generate_sql", "execute_sql")
209
- builder.add_edge("execute_sql", "refine")
210
- builder.add_edge("refine", END)
211
-
212
- memory = SqliteSaver("graph_checkpoint")
213
- graph = builder.compile(checkpointer=memory)
214
-
215
- async def async_chatbot_response(question, model_name):
216
- inputs = {"question": question}
217
- result = await graph.ainvoke(inputs)
218
- return result["result"]
219
 
220
  def toggle_history():
221
  global show_history_flag
222
  show_history_flag = not show_history_flag
223
  return history_log if show_history_flag else {}
224
 
225
- def toggle_advanced_mode(state):
226
- global advanced_mode_enabled
227
- advanced_mode_enabled = state
228
- return "Modo avançado ativado." if state else "Modo avançado desativado."
229
 
230
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
231
  with gr.Row():
@@ -236,6 +327,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
236
  upload_feedback = gr.Markdown()
237
  advanced_checkbox = gr.Checkbox(label="Refinar Resposta")
238
  reset_btn = gr.Button("Resetar")
 
239
  with gr.Column(scale=4):
240
  gr.Markdown("## Reasoning Agent")
241
  chatbot = gr.Chatbot(height=500)
@@ -245,8 +337,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
245
  history_output = gr.JSON()
246
  download_file = gr.File(visible=False)
247
 
248
- async def respond(message, chat_history, selected_model):
249
- response = await async_chatbot_response(message, selected_model)
250
  chat_history.append((message, response))
251
  return "", chat_history
252
 
@@ -266,4 +358,4 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
266
  advanced_checkbox.change(toggle_advanced_mode, inputs=advanced_checkbox, outputs=[])
267
 
268
  if __name__ == "__main__":
269
- demo.launch(share=False)
 
1
  import os
2
  import time
3
  import shutil
 
4
  import pandas as pd
 
 
5
  from sqlalchemy import create_engine
 
 
6
  from langchain_openai import ChatOpenAI
7
  from langchain_community.agent_toolkits import create_sql_agent
8
+ from langchain_community.utilities import SQLDatabase
9
  from huggingface_hub import InferenceClient
 
 
 
 
10
  import gradio as gr
11
+ from dotenv import load_dotenv
12
+ import logging
13
+ from sqlalchemy.types import DateTime, Integer, Float
14
 
15
  load_dotenv()
16
 
 
20
  DEFAULT_CSV_PATH = "tabela.csv"
21
  UPLOADED_CSV_PATH = os.path.join(UPLOAD_DIR, "tabela.csv")
22
  SQL_DB_PATH = "data.db"
23
+
24
  HUGGINGFACE_API_KEY = os.getenv("HUGGINGFACE_API_KEY")
25
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
26
 
 
36
  "Qwen/QwQ-32B": 8192
37
  }
38
 
39
+ hf_client = InferenceClient(
40
+ provider="together", api_key=HUGGINGFACE_API_KEY
41
+ )
42
+
43
  os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
44
 
45
  query_cache = {}
46
+ history_log = []
47
+ recent_history = []
48
  show_history_flag = False
49
+ engine = None
50
+
51
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
52
 
53
  def get_active_csv_path():
54
+ """Retorna o CSV ativo: o carregado ou o padrão.."""
55
  if os.path.exists(UPLOADED_CSV_PATH):
56
+ logging.info(f"[CSV] Usando arquivo CSV carregado: {UPLOADED_CSV_PATH}")
57
  return UPLOADED_CSV_PATH
58
  else:
59
+ logging.info(f"[CSV] Usando arquivo CSV padrão: {DEFAULT_CSV_PATH}")
60
  return DEFAULT_CSV_PATH
61
 
62
  def create_engine_and_load_db(csv_path, sql_db_path):
63
  if os.path.exists(sql_db_path):
64
+ print("Banco de dados SQL já existe. Carregando...")
65
  return create_engine(f"sqlite:///{sql_db_path}")
66
  else:
67
+ print("Banco de dados SQL não encontrado. Criando...")
68
  engine = create_engine(f"sqlite:///{sql_db_path}")
69
+
70
  df = pd.read_csv(
71
  csv_path,
72
  sep=";",
 
75
  dayfirst=True,
76
  on_bad_lines="skip"
77
  )
78
+
79
+ colunas_para_float = [
80
+ "PRECO_VISTA", "PRECO_CHEIO"
81
+ ]
82
+
83
+ colunas_para_int = [
84
+ "QUANTIDADE", "TOTAL_PAGINAS_CAPA", "VALOR_MEDIDA", "DIAS_VALIDADE"
85
+ ]
86
+
87
  for col in colunas_para_float:
88
  if col in df.columns:
89
  df[col] = pd.to_numeric(df[col].replace("-", None), errors="coerce")
90
+
91
  for col in colunas_para_int:
92
  if col in df.columns:
93
  df[col] = pd.to_numeric(df[col].replace("-", None), errors="coerce")
94
  df[col] = df[col].where(df[col].dropna() == df[col].dropna().astype(int))
95
  df[col] = df[col].astype("Int64")
96
+
97
  sql_dtype = {
98
  "DATA_INICIAL": DateTime(),
99
  "DATA_FINAL": DateTime(),
 
103
  "TOTAL_PAGINAS_CAPA": Integer(),
104
  "VALOR_MEDIDA": Integer(),
105
  "DIAS_VALIDADE": Integer()
106
+
107
  }
108
+
109
+ print("[DEBUG] Tipos das colunas:")
110
+ print(df.dtypes)
111
+
112
  df.to_sql("tabela", engine, index=False, if_exists="replace", dtype=sql_dtype)
113
+ print("Banco de dados SQL criado com sucesso!")
114
  return engine
115
 
116
  def handle_csv_upload(file):
117
  global engine, db, sql_agent
118
+
119
  try:
120
  file_path = file.name
121
  shutil.copy(file_path, UPLOADED_CSV_PATH)
122
+ logging.info(f"[UPLOAD] CSV salvo como: {UPLOADED_CSV_PATH}")
123
+
124
  engine = create_engine_and_load_db(UPLOADED_CSV_PATH, SQL_DB_PATH)
125
  db = SQLDatabase(engine=engine)
126
+ logging.info("[UPLOAD] Novo banco carregado e DB atualizado.")
127
+
128
+ sql_agent = create_sql_agent(
129
+ ChatOpenAI(model="gpt-4o-mini", temperature=0),
130
+ db=db,
131
+ agent_type="openai-tools",
132
+ verbose=True,
133
+ max_iterations=40,
134
+ return_intermediate_steps=True
135
+ )
136
+
137
+ logging.info("[UPLOAD] Novo banco carregado e agente recriado. Cache limpo.")
138
  query_cache.clear()
139
  history_log.clear()
140
  recent_history.clear()
141
+
142
  return "✅ CSV carregado com sucesso!"
143
+
144
  except Exception as e:
145
+ logging.error(f"[ERRO] Falha ao processar novo CSV: {e}")
146
  return f"❌ Erro ao processar CSV: {e}"
147
 
148
  def reset_app():
149
  global engine, db, sql_agent, query_cache, history_log, recent_history
150
+
151
  try:
152
  if os.path.exists(UPLOADED_CSV_PATH):
153
  os.remove(UPLOADED_CSV_PATH)
154
+ logging.info("[RESET] CSV personalizado removido.")
155
+
156
  engine = create_engine_and_load_db(DEFAULT_CSV_PATH, SQL_DB_PATH)
157
  db = SQLDatabase(engine=engine)
158
  sql_agent = create_sql_agent(ChatOpenAI(model="gpt-4o-mini", temperature=0), db=db, agent_type="openai-tools", verbose=True, max_iterations=40, return_intermediate_steps=True)
159
  query_cache.clear()
160
  history_log.clear()
161
  recent_history.clear()
162
+
163
  return "🔄 Sistema resetado para o estado inicial."
164
+
165
  except Exception as e:
166
  return f"❌ Erro ao resetar: {e}"
167
 
168
+ engine = create_engine_and_load_db(get_active_csv_path(), SQL_DB_PATH)
169
+ db = SQLDatabase(engine=engine)
170
+ llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
171
+ sql_agent = create_sql_agent(llm, db=db, agent_type="openai-tools", verbose=True, max_iterations=40, return_intermediate_steps=True)
172
+
173
  def generate_initial_context(db_sample):
174
  return (
175
  f"Você é um assistente que gera queries SQL objetivas e eficientes. Sempre inclua LIMIT 20 nas queries. Aqui está o banco de dados:\n\n"
 
177
  "\n***IMPORTANTE***: Detecte automaticamente o idioma da pergunta do usuário e responda sempre no mesmo idioma."
178
  "\nEsta base contém os SKUs (produtos) que foram promocionados por meio de TABLOIDE OU PROMOCAO OU ANUNCIO.\n"
179
  "Cada linha representa um SKU OU PRODUTO único PRESENTE NO TABLOIDE OU PROMOCAO OU ANUNCIO, incluindo sua descrição completa, os veículos OU MIDIAS de promoção utilizados e o respectivo período em que a promoção ocorreu.\n"
180
+
181
  "\nInformações imporatantes:\n"
182
  "- Use `LIKE '%<palavras-chave>%'` para buscas em colunas de texto.\n"
183
  "- Quando o usuário mencionar uma categoria, procure nas colunas: `CATEGORIA_PRODUTO_SKU`.\n"
184
  "- Se o usuário se referir a Nestle, o jeito correto de se escrever é Nestle sem acento e não Nestlé.\n"
185
  "- Você está usando um banco de dados SQLite.\n"
186
+
187
  "\nRetorne apenas a pergunta e a query SQL mais eficiente para entregar ao agent SQL do LangChain para gerar uma resposta para a pergunta. O formato deve ser:\n"
188
  "\nPergunta: <pergunta do usuário>\n"
189
  "\nOpção de Query SQL:\n<query SQL>"
190
  "\nIdioma: <idioma>"
191
  )
192
 
193
+ def is_greeting(user_query):
194
+ greetings = ["olá", "oi", "bom dia", "boa tarde", "boa noite", "oi, tudo bem?"]
195
+ return user_query.lower().strip() in greetings
196
+
197
+ def query_with_llama(user_query, db_sample, selected_model_name):
198
+ model_id = LLAMA_MODELS[selected_model_name]
199
+ max_tokens = MAX_TOKENS_MAP.get(model_id, 512)
200
+
201
+ initial_context = generate_initial_context(db_sample)
202
+ formatted_history = "\n".join(
203
+ [f"{msg['role'].capitalize()}: {msg['content']}" for msg in recent_history[-2:]]
 
204
  )
205
+
206
+ full_prompt = f"{initial_context}\n\nHistórico recente:\n{formatted_history}\n\nPergunta do usuário:\n{user_query}"
207
+
208
+ logging.info(f"[DEBUG] Contexto enviado ao ({selected_model_name}):\n{full_prompt}\n")
209
+
210
+ start_time = time.time()
211
+
212
+ try:
213
+ response = hf_client.chat.completions.create(
214
+ model=model_id,
215
+ messages=[{"role": "system", "content": full_prompt}],
216
+ max_tokens=max_tokens,
217
+ stream=False
218
+ )
219
+
220
+ llama_response = response["choices"][0]["message"]["content"]
221
+ end_time = time.time()
222
+ logging.info(f"[DEBUG] Resposta do {selected_model_name} para o Agent SQL:\n{llama_response.strip()}\n[Tempo de execução: {end_time - start_time:.2f}s]\n")
223
+ return llama_response.strip(), model_id
224
+
225
+ except Exception as e:
226
+ logging.error(f"[ERRO] Falha ao interagir com o modelo {selected_model_name}: {e}")
227
+ return None, model_id
228
 
229
+ def query_sql_agent(user_query, selected_model_name):
230
+ try:
231
+ if user_query in query_cache:
232
+ print(f"[CACHE] Retornando resposta do cache para a consulta: {user_query}")
233
+ return query_cache[user_query]
234
+
235
+ if is_greeting(user_query):
236
+ greeting_response = "Olá! Estou aqui para ajudar com suas consultas. Pergunte algo relacionado aos dados carregados no agente!"
237
+ query_cache[user_query] = greeting_response
238
+ return greeting_response
239
+
240
+ column_data = pd.read_sql_query("SELECT * FROM tabela LIMIT 10", engine)
241
+ llama_instruction = query_with_llama(user_query, column_data, selected_model_name)
242
+
243
+ if not llama_instruction:
244
+ return "Erro: O modelo Llama não conseguiu gerar uma instrução válida."
245
+
246
+ print("------- Agent SQL: Executando query -------")
247
+ response = sql_agent.invoke({"input": llama_instruction})
248
+ sql_response = response.get("output", "Erro ao obter a resposta do agente.")
249
+
250
+ query_cache[user_query] = sql_response
251
+ return sql_response
252
+
253
+ except Exception as e:
254
+ return f"Erro ao consultar o agente SQL: {e}"
255
+
256
+ advanced_mode_enabled = False # Novo estado global
257
+
258
+ def toggle_advanced_mode(state):
259
+ global advanced_mode_enabled
260
+ advanced_mode_enabled = state
261
+ logging.info(f"[MODO AVANÇADO] {'Ativado' if state else 'Desativado'}")
262
+ return "Modo avançado ativado." if state else "Modo avançado desativado."
263
 
264
+ def refine_response_with_llm(user_question, sql_response, chart_md=""):
 
 
 
265
  prompt = (
266
+ f"Pergunta do usuário:\n{user_question}\n\n"
267
+ f"Resposta gerada pelo agente SQL:\n{sql_response}\n\n"
268
+ "Sua tarefa é refinar, complementar e melhorar a resposta.\n"
269
+ "Adicione interpretações estatísticas ou insights relevantes."
270
  )
271
+
272
+ logging.info(f"[DEBUG] Prompt enviado ao modelo de refinamento:\n{prompt}\n")
273
+
274
+ try:
275
+ response = hf_client.chat.completions.create(
276
+ model=LLAMA_MODELS["LLaMA 70B"],
277
+ messages=[{"role": "system", "content": prompt}],
278
+ max_tokens=1200,
279
+ stream=False
280
+ )
281
+ improved_response = response["choices"][0]["message"]["content"]
282
+ logging.info(f"[DEBUG] Resposta do modelo de refinamento:\n{improved_response}\n")
283
+ return improved_response + ("\n\n" + chart_md if chart_md else "")
284
+
285
+ except Exception as e:
286
+ logging.error(f"[ERRO] Falha ao refinar resposta com LLM: {e}")
287
+ return sql_response + ("\n\n" + chart_md if chart_md else "")
288
+
289
+ def chatbot_response(user_input, selected_model_name):
290
+ start_time = time.time()
291
+ response = query_sql_agent(user_input, selected_model_name)
292
+ end_time = time.time()
293
+
294
+ model_id = LLAMA_MODELS[selected_model_name]
295
+
296
+ if advanced_mode_enabled:
297
+ response = refine_response_with_llm(user_input, response)
298
+
299
+ history_log.append({
300
+ "Modelo LLM": model_id,
301
+ "Pergunta": user_input,
302
+ "Resposta": response,
303
+ "Tempo de Resposta (s)": round(end_time - start_time, 2)
304
+ })
305
+
306
+ recent_history.append({"role": "user", "content": user_input})
307
+ recent_history.append({"role": "assistant", "content": response})
308
+
309
+ if len(recent_history) > 4:
310
+ recent_history.pop(0)
311
+ recent_history.pop(0)
312
+
313
+ return response
 
 
 
 
314
 
315
  def toggle_history():
316
  global show_history_flag
317
  show_history_flag = not show_history_flag
318
  return history_log if show_history_flag else {}
319
 
 
 
 
 
320
 
321
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
322
  with gr.Row():
 
327
  upload_feedback = gr.Markdown()
328
  advanced_checkbox = gr.Checkbox(label="Refinar Resposta")
329
  reset_btn = gr.Button("Resetar")
330
+
331
  with gr.Column(scale=4):
332
  gr.Markdown("## Reasoning Agent")
333
  chatbot = gr.Chatbot(height=500)
 
337
  history_output = gr.JSON()
338
  download_file = gr.File(visible=False)
339
 
340
+ def respond(message, chat_history, selected_model):
341
+ response = chatbot_response(message, selected_model)
342
  chat_history.append((message, response))
343
  return "", chat_history
344
 
 
358
  advanced_checkbox.change(toggle_advanced_mode, inputs=advanced_checkbox, outputs=[])
359
 
360
  if __name__ == "__main__":
361
+ demo.launch(share=False)