File size: 3,601 Bytes
7e493b0
324a12a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f3200bb
7e493b0
 
f3200bb
7e493b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324a12a
7e493b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324a12a
7e493b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e39c34b
324a12a
e39c34b
 
 
 
 
 
7e493b0
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import os
import sys

# === Compatibilidade Hugging Face Hub (HfFolder foi depreciado nas versoes novas do huggingface_hub) ===
try:
    import huggingface_hub
    if not hasattr(huggingface_hub, "HfFolder"):
        class _HfFolderShim:
            @staticmethod
            def get_token():
                import os
                try:
                    from huggingface_hub import get_token
                    return get_token()
                except Exception:
                    return os.getenv("HF_TOKEN") or os.getenv("HUGGING_FACE_HUB_TOKEN")
            @staticmethod
            def save_token(token):
                pass
            @staticmethod
            def delete_token():
                pass
        huggingface_hub.HfFolder = _HfFolderShim
except Exception as _shim_err:
    print(f"[boot] HfFolder shim error (non-fatal): {_shim_err}", flush=True)

import gradio as gr
import uvicorn

try:
    import spaces

    print(f"[boot] spaces real: {getattr(spaces, '__file__', '?')}", flush=True)
except ImportError:  # fora do ZeroGPU (dev local)
    print("[boot] AVISO: pacote 'spaces' ausente, fallback local (ZeroGPU desligado)", flush=True)

    class _SpacesFallback:
        @staticmethod
        def GPU(task=None, **kwargs):
            if task is None:
                return lambda fn: fn
            return task

    spaces = _SpacesFallback()

from ai_engine import AIEngine
from config import Config
from main import app as api_app

PORT = int(os.getenv("PORT") or os.getenv("GRADIO_SERVER_PORT") or 7860)

_engine = AIEngine()


def _demo_reply(pergunta: str) -> str:
    pergunta = (pergunta or "").strip()
    if not pergunta:
        return "Escreve uma pergunta sobre a pastelaria Negra Plena."
    return _engine.generate_reply("demo", pergunta, "Visitante")


@spaces.GPU(duration=120)
def _zerogpu_status() -> str:
    return "ZeroGPU activo neste Space."


api_app.router.routes = [r for r in api_app.router.routes if getattr(r, "path", None) != "/"]

with gr.Blocks(title=f"{Config.ASSISTANT_NAME} - {Config.COMPANY_NAME}") as demo:
    gr.Markdown(
        f"# {Config.ASSISTANT_NAME} - cérebro da {Config.COMPANY_NAME}\n"
        "API de atendimento usada pelo bot WhatsApp.  \n"
        "`POST /api/escutar` · `GET /health` · `GET /docs`"
    )
    entrada = gr.Textbox(label="Pergunta de teste", placeholder="Qual é o preço do bolo no pote?")
    btn = gr.Button("Enviar", variant="primary")
    saida = gr.Markdown()
    btn.click(_demo_reply, inputs=entrada, outputs=saida)
    entrada.submit(_demo_reply, inputs=entrada, outputs=saida)
    gr.Button("Estado ZeroGPU").click(_zerogpu_status, inputs=None, outputs=saida)

# SSR desligado: o proxy Node do Gradio fica com a 7860 e o uvicorn precisa dela.
app = gr.mount_gradio_app(api_app, demo, path="/", ssr_mode=False)

# ZeroGPU: o demo TEM de ser lançado para o scan de startup detectar o @spaces.GPU.
try:
    demo.launch(prevent_thread_lock=True, server_name="127.0.0.1", server_port=8000)
    demo.close()
    print("[boot] demo lançado e fechado para o scan ZeroGPU", flush=True)
except Exception as exc:
    print(f"[boot] lançamento interno do demo falhou: {exc!r}", flush=True)

# Pré-aquecimento do Llama local: baixa os pesos UMA vez (depois usa o cache
# do disco) para a primeira resposta não pagar o download.
try:
    from local_llm import _ensure_loaded as _warm_llama
    _warm_llama()
except Exception as exc:
    print(f"[boot] warmup Llama ignorado: {exc!r}", flush=True)

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=PORT, log_level="info")