File size: 4,776 Bytes
2731234
 
ff801d4
 
2731234
dd5ab79
87fd43c
adc63f0
dd5ab79
 
 
adc63f0
 
 
ff801d4
d9fe66d
ff801d4
726dd3c
ff801d4
dd5ab79
2731234
ff801d4
726dd3c
ff801d4
d9fe66d
ff801d4
 
 
 
 
cc4027d
ff801d4
 
adc63f0
ff801d4
 
 
2731234
adc63f0
ff801d4
 
 
adc63f0
2731234
adc63f0
dd5ab79
adc63f0
 
 
dd5ab79
c376a15
 
726dd3c
c376a15
2731234
adc63f0
 
 
 
 
 
 
726dd3c
adc63f0
ff801d4
adc63f0
 
 
 
ff801d4
dd5ab79
726dd3c
87fd43c
adc63f0
 
 
726dd3c
adc63f0
 
 
 
 
 
 
726dd3c
adc63f0
 
 
 
 
 
dd5ab79
 
 
726dd3c
adc63f0
 
 
 
 
 
 
 
726dd3c
adc63f0
 
 
726dd3c
 
 
 
 
 
adc63f0
 
 
 
 
 
 
 
 
 
726dd3c
adc63f0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44a3282
2731234
 
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import os
import gradio as gr
import requests
from huggingface_hub import InferenceClient

"""
For more information on `huggingface_hub` Inference API support, 
please check the docs: 
https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
"""

# ----------------------------------------------------------------
# CONFIGURACIÓN DE SERPER (búsqueda web)
# ----------------------------------------------------------------
SERPER_API_KEY = os.getenv("SERPER_API_KEY")

def do_websearch(query: str) -> str:
    """ Llama a serper.dev para hacer la búsqueda en Google y devuelve texto. """
    if not SERPER_API_KEY:
        return "(SERPER_API_KEY no está configurado)"

    url = "https://google.serper.dev/search"
    headers = {"X-API-KEY": SERPER_API_KEY, "Content-Type": "application/json"}
    payload = {"q": query}

    try:
        resp = requests.post(url, json=payload, headers=headers, timeout=10)
        data = resp.json()
    except Exception as e:
        return f"(Error al llamar a serper.dev: {e})"

    if "organic" not in data:
        return "No se encontraron resultados en serper.dev."

    results = data["organic"]
    if not results:
        return "No hay resultados relevantes."

    text = []
    for i, item in enumerate(results, start=1):
        title = item.get("title", "Sin título")
        link = item.get("link", "Sin enlace")
        text.append(f"{i}. {title}\n   {link}")

    return "\n".join(text)

# ----------------------------------------------------------------
# CONFIGURACIÓN DEL MODELO (AHORA CON TOKEN)
# ----------------------------------------------------------------
hf_api_token = os.getenv("HF_API_TOKEN")
client = InferenceClient(
    model="meta-llama/Llama-3.1-8B-Instruct",
    token=hf_api_token
)

def respond(
    message,
    history: list[tuple[str, str]],
    system_message,
    max_tokens,
    temperature,
    top_p,
    use_search  # <-- Checkbox en 1er lugar en additional_inputs
):
    """
    - system_message: Texto del rol "system"
    - history: lista de (user_msg, assistant_msg)
    - message: Mensaje actual del usuario
    - use_search: booleano que indica si se habilita la búsqueda en serper
    """

    # Si use_search es True, primero el contenido web y luego el input
    if use_search:
        web_info = do_websearch(message)
        message = f"Información de la web:\n{web_info}\n\nPregunta del usuario:\n{message}"

    # Construimos la conversación
    messages = [{"role": "system", "content": system_message}]
    for user_txt, assistant_txt in history:
        if user_txt:
            messages.append({"role": "user", "content": user_txt})
        if assistant_txt:
            messages.append({"role": "assistant", "content": assistant_txt})

    # Añadimos turno nuevo
    messages.append({"role": "user", "content": message})

    # Llamamos a la API con streaming
    response_text = ""
    for chunk in client.chat_completion(
        messages=messages,
        max_tokens=max_tokens,
        temperature=temperature,
        top_p=top_p,
        stream=True
    ):
        token = chunk.choices[0].delta.get("content", "")
        response_text += token
        yield response_text

# ----------------------------------------------------------------
# CONFIGURACIÓN DE LA INTERFAZ
# ----------------------------------------------------------------
# Subimos la casilla de verificación (checkbox) de websearch a la parte superior
demo = gr.ChatInterface(
    fn=respond,
    additional_inputs=[
        # 1) Checkbox de websearch
        gr.Checkbox(
            value=False,
            label="🌐 Búsqueda",
        ),
        # 2) Texto system
        gr.Textbox(
            value=(
                "Eres Juan, un asistente virtual en español. "
                "Debes responder con mucha paciencia y empatía a usuarios que "
                "pueden tener dificultades cognitivas o escribir frases confusas. "
                "Provee explicaciones simples, procura entender la intención del usuario "
                "aunque la frase esté mal escrita, y mantén siempre un tono amable."
            ),
            label="Mensaje del sistema",
        ),
        # 3) Sliders
        gr.Slider(
            minimum=1, 
            maximum=2048, 
            value=512, 
            step=1, 
            label="Máxima cantidad de tokens"
        ),
        gr.Slider(
            minimum=0.1, 
            maximum=4.0, 
            value=0.7, 
            step=0.1, 
            label="Temperatura"
        ),
        gr.Slider(
            minimum=0.1,
            maximum=1.0,
            value=0.95,
            step=0.05,
            label="Top-p (muestreo por núcleo)",
        ),
    ],
)

if __name__ == "__main__":
    demo.launch()