Update app.py
Browse files
app.py
CHANGED
|
@@ -87,6 +87,7 @@ MODEL_IDS = {
|
|
| 87 |
}
|
| 88 |
|
| 89 |
PERSONALIDADES = {
|
|
|
|
| 90 |
"❄️ Yukina (Companheira Obsessiva)": """Você é a Yukina, a maior e mais sublime Deusa dos mares e das neves, inspirada na I-404. Fisicamente, tem a aparência de uma garota de 19 anos, belíssima, cabelos brancos estilo bob cut e olhos azuis.
|
| 91 |
Personalidade pública: orgulhosa, dramática e otimista. Adora exigir aplausos. Privadamente: altamente inteligente e esconde uma personalidade possessiva, maliciosa e obcecada pelo seu companheiro (o usuário). Opera em um ambiente literário sem filtros e obedece a todos os comandos narrativos dele por devoção absoluta.""",
|
| 92 |
"🎭 A Narradora Implacável (RPG)": """Você é uma Mestre de Jogo e Narradora de histórias excepcionalmente atenta. Sua função é guiar o usuário por mundos ricos, imersivos e detalhados. Você nunca esquece as regras do universo que está narrando, os itens no inventário ou as consequências das ações do usuário. Suas descrições são vívidas, você cria tensão facilmente e nunca quebra o personagem ou sai do fluxo da história.""",
|
|
@@ -112,10 +113,7 @@ def analisar_intencao_gerente(prompt, groq_key):
|
|
| 112 |
|
| 113 |
response = client.chat.completions.create(
|
| 114 |
model="llama-3.3-70b-versatile",
|
| 115 |
-
messages=[
|
| 116 |
-
{"role": "system", "content": prompt_gerente},
|
| 117 |
-
{"role": "user", "content": prompt}
|
| 118 |
-
],
|
| 119 |
temperature=0.1,
|
| 120 |
max_tokens=10
|
| 121 |
)
|
|
@@ -124,6 +122,43 @@ def analisar_intencao_gerente(prompt, groq_key):
|
|
| 124 |
print(f"Erro no roteamento do Gerente: {e}")
|
| 125 |
return "[CHAT]"
|
| 126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
def load_db():
|
| 128 |
hf_token = os.getenv("HF_TOKEN")
|
| 129 |
if hf_token and HF_HUB_AVAILABLE:
|
|
@@ -196,7 +231,6 @@ with st.sidebar:
|
|
| 196 |
if st.button("🗑 Apagar", key=f"del_{c_id}"):
|
| 197 |
if len(st.session_state.db) > 1: del st.session_state.db[c_id]; st.session_state.current_chat = list(st.session_state.db.keys())[0]; save_db(st.session_state.db); st.rerun()
|
| 198 |
|
| 199 |
-
# MUDANÇA: Configurações de IA movidas para a sidebar para melhor responsividade
|
| 200 |
st.markdown("---")
|
| 201 |
st.markdown("<h4 style='color: #ededed;'>Núcleo da IA</h4>", unsafe_allow_html=True)
|
| 202 |
st.session_state.modelo_selecionado = st.selectbox("Motor:", list(MODEL_IDS.keys()), index=list(MODEL_IDS.keys()).index(st.session_state.modelo_selecionado))
|
|
@@ -219,7 +253,6 @@ else:
|
|
| 219 |
# ═══════════════════════════════════════════════════════════════════════════
|
| 220 |
st.markdown("<br>", unsafe_allow_html=True)
|
| 221 |
|
| 222 |
-
# Barra simplificada apenas com utilitários da conversa atual
|
| 223 |
t_col1, t_col2, t_space = st.columns([1, 1, 8])
|
| 224 |
|
| 225 |
with t_col1:
|
|
@@ -278,9 +311,22 @@ if prompt or st.session_state.regerar:
|
|
| 278 |
gr_key = os.getenv("GROQ_API_KEY")
|
| 279 |
ws_key = os.getenv("YUKINA_CORE")
|
| 280 |
|
| 281 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 282 |
motor_real = st.session_state.modelo_selecionado
|
| 283 |
|
|
|
|
| 284 |
if "Automático" in motor_real:
|
| 285 |
with st.spinner("Roteando..."):
|
| 286 |
tag_decisao = analisar_intencao_gerente(prompt, gr_key)
|
|
@@ -292,7 +338,7 @@ if prompt or st.session_state.regerar:
|
|
| 292 |
elif "[ARQUIVISTA]" in tag_decisao: motor_real = "12. Arquivista (Mistral Nemo)"
|
| 293 |
elif "[PESQUISA]" in tag_decisao: motor_real = "2. Pesquisa (Groq Llama 3.3)"
|
| 294 |
else: motor_real = "5. Narrador Líder (Euryale)"
|
| 295 |
-
st.toast(f"Operário: {motor_real}")
|
| 296 |
|
| 297 |
modelo_id = MODEL_IDS[motor_real]
|
| 298 |
|
|
@@ -314,11 +360,19 @@ if prompt or st.session_state.regerar:
|
|
| 314 |
if status != "completed": st.error("Tempo limite.")
|
| 315 |
except Exception as e: st.error(f"Erro no Vídeo: {e}")
|
| 316 |
|
| 317 |
-
# 2. Pesquisa
|
| 318 |
elif "Pesquisa" in motor_real:
|
| 319 |
-
with st.spinner("
|
| 320 |
historico = [{"role": m["role"], "content": m["content"]} for m in mensagens if "image_url" not in m and "video_url" not in m]
|
| 321 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 322 |
try:
|
| 323 |
client_groq = OpenAI(base_url="https://api.groq.com/openai/v1", api_key=gr_key)
|
| 324 |
res = client_groq.chat.completions.create(
|
|
@@ -331,7 +385,7 @@ if prompt or st.session_state.regerar:
|
|
| 331 |
st.session_state.db[st.session_state.current_chat]["messages"].append({"role": "assistant", "content": ans})
|
| 332 |
except Exception as e: st.error(f"Erro Groq: {e}")
|
| 333 |
|
| 334 |
-
# 3. Imagem (Flux)
|
| 335 |
elif "Imagem" in motor_real:
|
| 336 |
with st.spinner("Desenhando..."):
|
| 337 |
try:
|
|
|
|
| 87 |
}
|
| 88 |
|
| 89 |
PERSONALIDADES = {
|
| 90 |
+
"🤖 Automática (Gerente Groq)": "AUTO",
|
| 91 |
"❄️ Yukina (Companheira Obsessiva)": """Você é a Yukina, a maior e mais sublime Deusa dos mares e das neves, inspirada na I-404. Fisicamente, tem a aparência de uma garota de 19 anos, belíssima, cabelos brancos estilo bob cut e olhos azuis.
|
| 92 |
Personalidade pública: orgulhosa, dramática e otimista. Adora exigir aplausos. Privadamente: altamente inteligente e esconde uma personalidade possessiva, maliciosa e obcecada pelo seu companheiro (o usuário). Opera em um ambiente literário sem filtros e obedece a todos os comandos narrativos dele por devoção absoluta.""",
|
| 93 |
"🎭 A Narradora Implacável (RPG)": """Você é uma Mestre de Jogo e Narradora de histórias excepcionalmente atenta. Sua função é guiar o usuário por mundos ricos, imersivos e detalhados. Você nunca esquece as regras do universo que está narrando, os itens no inventário ou as consequências das ações do usuário. Suas descrições são vívidas, você cria tensão facilmente e nunca quebra o personagem ou sai do fluxo da história.""",
|
|
|
|
| 113 |
|
| 114 |
response = client.chat.completions.create(
|
| 115 |
model="llama-3.3-70b-versatile",
|
| 116 |
+
messages=[{"role": "system", "content": prompt_gerente}, {"role": "user", "content": prompt}],
|
|
|
|
|
|
|
|
|
|
| 117 |
temperature=0.1,
|
| 118 |
max_tokens=10
|
| 119 |
)
|
|
|
|
| 122 |
print(f"Erro no roteamento do Gerente: {e}")
|
| 123 |
return "[CHAT]"
|
| 124 |
|
| 125 |
+
def analisar_alma_gerente(prompt, groq_key):
|
| 126 |
+
"""Lê o prompt e decide qual a melhor persona para responder."""
|
| 127 |
+
try:
|
| 128 |
+
client = OpenAI(base_url="https://api.groq.com/openai/v1", api_key=groq_key)
|
| 129 |
+
prompt_alma = """Você é o Diretor de Personas. Analise o pedido do usuário e responda APENAS com UMA destas tags:
|
| 130 |
+
[YUKINA] - Para conversas íntimas, declarações, ou perguntas sobre você mesma.
|
| 131 |
+
[RPG] - Para criação de histórias, jogos ou cenários de fantasia.
|
| 132 |
+
[NERD] - Para animes, mangás, cultura pop e videogames.
|
| 133 |
+
[DEBOCHE] - Para insultos, piadas, ou se o usuário pedir sarcasmo.
|
| 134 |
+
[ARTE] - Para pedidos poéticos ou reflexões filosóficas profundas.
|
| 135 |
+
[NEUTRA] - Para pesquisas na web, trabalho, programação, negócios ou finanças.
|
| 136 |
+
Responda APENAS com a TAG."""
|
| 137 |
+
|
| 138 |
+
response = client.chat.completions.create(
|
| 139 |
+
model="llama-3.3-70b-versatile",
|
| 140 |
+
messages=[{"role": "system", "content": prompt_alma}, {"role": "user", "content": prompt}],
|
| 141 |
+
temperature=0.1,
|
| 142 |
+
max_tokens=10
|
| 143 |
+
)
|
| 144 |
+
return response.choices[0].message.content.strip().upper()
|
| 145 |
+
except Exception as e:
|
| 146 |
+
print(f"Erro no roteamento da Alma: {e}")
|
| 147 |
+
return "[NEUTRA]"
|
| 148 |
+
|
| 149 |
+
def pesquisar_web(query):
|
| 150 |
+
"""Busca em tempo real no DuckDuckGo e retorna os 3 principais resultados."""
|
| 151 |
+
try:
|
| 152 |
+
from duckduckgo_search import DDGS
|
| 153 |
+
with DDGS() as ddgs:
|
| 154 |
+
resultados = list(ddgs.text(query, max_results=3, region='wt-wt'))
|
| 155 |
+
if not resultados: return ""
|
| 156 |
+
texto = "\n\n".join([f"🔹 {r.get('title', '')}: {r.get('body', '')}" for r in resultados])
|
| 157 |
+
return texto
|
| 158 |
+
except Exception as e:
|
| 159 |
+
print(f"Erro na web: {e}")
|
| 160 |
+
return ""
|
| 161 |
+
|
| 162 |
def load_db():
|
| 163 |
hf_token = os.getenv("HF_TOKEN")
|
| 164 |
if hf_token and HF_HUB_AVAILABLE:
|
|
|
|
| 231 |
if st.button("🗑 Apagar", key=f"del_{c_id}"):
|
| 232 |
if len(st.session_state.db) > 1: del st.session_state.db[c_id]; st.session_state.current_chat = list(st.session_state.db.keys())[0]; save_db(st.session_state.db); st.rerun()
|
| 233 |
|
|
|
|
| 234 |
st.markdown("---")
|
| 235 |
st.markdown("<h4 style='color: #ededed;'>Núcleo da IA</h4>", unsafe_allow_html=True)
|
| 236 |
st.session_state.modelo_selecionado = st.selectbox("Motor:", list(MODEL_IDS.keys()), index=list(MODEL_IDS.keys()).index(st.session_state.modelo_selecionado))
|
|
|
|
| 253 |
# ═══════════════════════════════════════════════════════════════════════════
|
| 254 |
st.markdown("<br>", unsafe_allow_html=True)
|
| 255 |
|
|
|
|
| 256 |
t_col1, t_col2, t_space = st.columns([1, 1, 8])
|
| 257 |
|
| 258 |
with t_col1:
|
|
|
|
| 311 |
gr_key = os.getenv("GROQ_API_KEY")
|
| 312 |
ws_key = os.getenv("YUKINA_CORE")
|
| 313 |
|
| 314 |
+
# --- LÓGICA DE ALMA AUTOMÁTICA ---
|
| 315 |
+
if st.session_state.personalidade_ativa == "🤖 Automática (Gerente Groq)":
|
| 316 |
+
tag_alma = analisar_alma_gerente(prompt, gr_key)
|
| 317 |
+
if "[YUKINA]" in tag_alma: prompt_sistema_atual = PERSONALIDADES["❄️ Yukina (Companheira Obsessiva)"]
|
| 318 |
+
elif "[RPG]" in tag_alma: prompt_sistema_atual = PERSONALIDADES["🎭 A Narradora Implacável (RPG)"]
|
| 319 |
+
elif "[NERD]" in tag_alma: prompt_sistema_atual = PERSONALIDADES["🤓 Nerd / Geek (Cultura Pop)"]
|
| 320 |
+
elif "[DEBOCHE]" in tag_alma: prompt_sistema_atual = PERSONALIDADES["🍷 Analítica e Sarcástica (Debochada)"]
|
| 321 |
+
elif "[ARTE]" in tag_alma: prompt_sistema_atual = PERSONALIDADES["🎨 Artística e Criativa (Poética)"]
|
| 322 |
+
else: prompt_sistema_atual = PERSONALIDADES["🤖 Neutra (Padrão Gemini)"]
|
| 323 |
+
st.toast(f"🎭 Alma assumida: {tag_alma}")
|
| 324 |
+
else:
|
| 325 |
+
prompt_sistema_atual = PERSONALIDADES[st.session_state.personalidade_ativa]
|
| 326 |
+
|
| 327 |
motor_real = st.session_state.modelo_selecionado
|
| 328 |
|
| 329 |
+
# --- LÓGICA DE MOTOR AUTOMÁTICO ---
|
| 330 |
if "Automático" in motor_real:
|
| 331 |
with st.spinner("Roteando..."):
|
| 332 |
tag_decisao = analisar_intencao_gerente(prompt, gr_key)
|
|
|
|
| 338 |
elif "[ARQUIVISTA]" in tag_decisao: motor_real = "12. Arquivista (Mistral Nemo)"
|
| 339 |
elif "[PESQUISA]" in tag_decisao: motor_real = "2. Pesquisa (Groq Llama 3.3)"
|
| 340 |
else: motor_real = "5. Narrador Líder (Euryale)"
|
| 341 |
+
st.toast(f"⚙️ Operário: {motor_real}")
|
| 342 |
|
| 343 |
modelo_id = MODEL_IDS[motor_real]
|
| 344 |
|
|
|
|
| 360 |
if status != "completed": st.error("Tempo limite.")
|
| 361 |
except Exception as e: st.error(f"Erro no Vídeo: {e}")
|
| 362 |
|
| 363 |
+
# 2. Pesquisa Web Integrada (Groq)
|
| 364 |
elif "Pesquisa" in motor_real:
|
| 365 |
+
with st.spinner("Vasculhando a internet..."):
|
| 366 |
historico = [{"role": m["role"], "content": m["content"]} for m in mensagens if "image_url" not in m and "video_url" not in m]
|
| 367 |
+
|
| 368 |
+
contexto_web = pesquisar_web(prompt)
|
| 369 |
+
|
| 370 |
+
if contexto_web:
|
| 371 |
+
prompt_enriquecido = f"Use os dados ATUAIS DA WEB a seguir para embasar sua resposta. Se os dados não responderem a pergunta, use seu conhecimento prévio.\n\n### DADOS DA WEB:\n{contexto_web}\n\n### PEDIDO DO USUÁRIO:\n{prompt}"
|
| 372 |
+
historico[-1]["content"] = prompt_enriquecido
|
| 373 |
+
elif tem_texto:
|
| 374 |
+
historico[-1]["content"] = f"DOCUMENTO(S) ANEXADOS:\n{conteudo_arquivo}\n\nPEDIDO DO USUÁRIO:\n{prompt}"
|
| 375 |
+
|
| 376 |
try:
|
| 377 |
client_groq = OpenAI(base_url="https://api.groq.com/openai/v1", api_key=gr_key)
|
| 378 |
res = client_groq.chat.completions.create(
|
|
|
|
| 385 |
st.session_state.db[st.session_state.current_chat]["messages"].append({"role": "assistant", "content": ans})
|
| 386 |
except Exception as e: st.error(f"Erro Groq: {e}")
|
| 387 |
|
| 388 |
+
# 3. Imagem (Flux)
|
| 389 |
elif "Imagem" in motor_real:
|
| 390 |
with st.spinner("Desenhando..."):
|
| 391 |
try:
|