Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,17 +1,18 @@
|
|
| 1 |
import os
|
| 2 |
-
import
|
| 3 |
-
from groq import Groq
|
| 4 |
import traceback
|
|
|
|
|
|
|
| 5 |
|
| 6 |
-
# 1.
|
| 7 |
-
client = Groq()
|
| 8 |
-
|
| 9 |
-
# 2. Configurações do Modelo
|
| 10 |
MODEL_ID = "groq/compound"
|
|
|
|
|
|
|
| 11 |
|
| 12 |
-
#
|
| 13 |
@cl.on_chat_start
|
| 14 |
def start_chat():
|
|
|
|
| 15 |
system_prompt = (
|
| 16 |
"Você é um assistente de pesquisa avançado. "
|
| 17 |
"Quando um usuário perguntar sobre o conteúdo de um site (ex: 'o que tem no site X?'), "
|
|
@@ -24,9 +25,10 @@ def start_chat():
|
|
| 24 |
[{"role": "system", "content": system_prompt}]
|
| 25 |
)
|
| 26 |
|
| 27 |
-
#
|
| 28 |
@cl.on_message
|
| 29 |
async def main(message: cl.Message):
|
|
|
|
| 30 |
message_history = cl.user_session.get("message_history")
|
| 31 |
message_history.append({"role": "user", "content": message.content})
|
| 32 |
|
|
@@ -35,37 +37,58 @@ async def main(message: cl.Message):
|
|
| 35 |
|
| 36 |
full_response = ""
|
| 37 |
try:
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
|
|
|
| 55 |
|
| 56 |
except Exception as e:
|
| 57 |
-
print(f"--- ERRO
|
| 58 |
traceback.print_exc()
|
| 59 |
-
await msg.update(content=f"Desculpe, ocorreu um erro
|
| 60 |
return
|
| 61 |
|
| 62 |
-
#
|
| 63 |
-
|
| 64 |
-
# garantindo que mesmo uma resposta vazia não quebre a sessão.
|
| 65 |
-
if full_response.strip(): # Verifica se a resposta não está vazia ou só com espaços
|
| 66 |
await msg.update()
|
| 67 |
message_history.append({"role": "assistant", "content": full_response})
|
| 68 |
cl.user_session.set("message_history", message_history)
|
| 69 |
else:
|
| 70 |
-
# Se
|
| 71 |
-
await msg.
|
|
|
|
| 1 |
import os
|
| 2 |
+
import json
|
|
|
|
| 3 |
import traceback
|
| 4 |
+
import chainlit as cl
|
| 5 |
+
import httpx # Importamos a nova biblioteca
|
| 6 |
|
| 7 |
+
# 1. Configurações do Modelo e API
|
|
|
|
|
|
|
|
|
|
| 8 |
MODEL_ID = "groq/compound"
|
| 9 |
+
GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
|
| 10 |
+
API_URL = "https://api.groq.com/openai/v1/chat/completions"
|
| 11 |
|
| 12 |
+
# 2. Início do Chat
|
| 13 |
@cl.on_chat_start
|
| 14 |
def start_chat():
|
| 15 |
+
"""Define o prompt de sistema para guiar o comportamento do modelo."""
|
| 16 |
system_prompt = (
|
| 17 |
"Você é um assistente de pesquisa avançado. "
|
| 18 |
"Quando um usuário perguntar sobre o conteúdo de um site (ex: 'o que tem no site X?'), "
|
|
|
|
| 25 |
[{"role": "system", "content": system_prompt}]
|
| 26 |
)
|
| 27 |
|
| 28 |
+
# 3. Lógica Principal de Mensagem (usando httpx)
|
| 29 |
@cl.on_message
|
| 30 |
async def main(message: cl.Message):
|
| 31 |
+
"""Processa a mensagem do usuário usando httpx para mais controle sobre o stream."""
|
| 32 |
message_history = cl.user_session.get("message_history")
|
| 33 |
message_history.append({"role": "user", "content": message.content})
|
| 34 |
|
|
|
|
| 37 |
|
| 38 |
full_response = ""
|
| 39 |
try:
|
| 40 |
+
# Montamos os headers e o payload manualmente
|
| 41 |
+
headers = {
|
| 42 |
+
"Authorization": f"Bearer {GROQ_API_KEY}",
|
| 43 |
+
"Content-Type": "application/json",
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
payload = {
|
| 47 |
+
"model": MODEL_ID,
|
| 48 |
+
"messages": message_history,
|
| 49 |
+
"temperature": 0.7,
|
| 50 |
+
"max_tokens": 4096,
|
| 51 |
+
"stream": True, # Essencial para o streaming
|
| 52 |
+
"compound_custom": {"tools": {"enabled_tools": ["web_search", "code_interpreter", "visit_website"]}}
|
| 53 |
+
}
|
| 54 |
|
| 55 |
+
# Usamos um AsyncClient do httpx para fazer a requisição
|
| 56 |
+
async with httpx.AsyncClient(timeout=60) as client:
|
| 57 |
+
# client.stream nos dá um objeto de resposta para iterar
|
| 58 |
+
async with client.stream("POST", API_URL, headers=headers, json=payload) as response:
|
| 59 |
+
# Verificamos se a requisição foi bem-sucedida
|
| 60 |
+
response.raise_for_status()
|
| 61 |
+
|
| 62 |
+
# Iteramos sobre as linhas da resposta (formato SSE)
|
| 63 |
+
async for line in response.aiter_lines():
|
| 64 |
+
if line.startswith("data: "):
|
| 65 |
+
# Removemos o prefixo "data: "
|
| 66 |
+
json_data = line.removeprefix("data: ").strip()
|
| 67 |
+
|
| 68 |
+
# O stream termina com um sinal "[DONE]"
|
| 69 |
+
if json_data == "[DONE]":
|
| 70 |
+
break
|
| 71 |
+
|
| 72 |
+
# Convertemos o texto JSON em um dicionário Python
|
| 73 |
+
chunk = json.loads(json_data)
|
| 74 |
|
| 75 |
+
# Extraímos o token de texto, se existir
|
| 76 |
+
if chunk["choices"] and chunk["choices"][0]["delta"].get("content"):
|
| 77 |
+
token = chunk["choices"][0]["delta"]["content"]
|
| 78 |
+
await msg.stream_token(token)
|
| 79 |
+
full_response += token
|
| 80 |
|
| 81 |
except Exception as e:
|
| 82 |
+
print(f"--- ERRO INESPERADO CAPTURADO ---")
|
| 83 |
traceback.print_exc()
|
| 84 |
+
await msg.update(content=f"Desculpe, ocorreu um erro: {e}")
|
| 85 |
return
|
| 86 |
|
| 87 |
+
# Finaliza a mensagem e atualiza o histórico
|
| 88 |
+
if full_response.strip():
|
|
|
|
|
|
|
| 89 |
await msg.update()
|
| 90 |
message_history.append({"role": "assistant", "content": full_response})
|
| 91 |
cl.user_session.set("message_history", message_history)
|
| 92 |
else:
|
| 93 |
+
# Se não houve resposta, informa o usuário e remove a mensagem vazia
|
| 94 |
+
await msg.update(content="O modelo não gerou uma resposta desta vez.")
|