aztro commited on
Commit
95290c6
·
verified ·
1 Parent(s): 156703d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +201 -220
app.py CHANGED
@@ -1,226 +1,207 @@
 
1
  import os
2
- import google.generativeai as genai
3
- import streamlit as st
4
- import logging
5
- from datetime import datetime
6
-
7
- # Configuración inicial
8
- st.set_page_config(page_title="Asistente Hielo Polar", page_icon="❄️")
9
-
10
- # --- Constantes y Configuraciones ---
11
- PRECIOS_PUBLICO = {
12
- "Bolsas de hielo 5 KG": "$25.00 MXN",
13
- "Bolsas de hielo 3 KG": "$18.00 MXN",
14
- "Barra de hielo 75 KG": "$100.00 MXN",
15
- "Hielo Premier 3 KG": "$26.00 MXN"
16
- }
17
-
18
- PRECIOS_CLIENTE = {
19
- "Acámbaro Gto.": {
20
- "Bolsas de hielo 5 KG": "$18.00 MXN",
21
- "Bolsas de hielo 3 KG": "$13.00 MXN",
22
- "Barra de hielo 75 KG": "$100.00 MXN",
23
- "Hielo Premier 3 KG": "$20.00 MXN"
24
- },
25
- "Comunidades, Zinapecuaro y Tarandacuao": {
26
- "Bolsas de hielo 5 KG": "$19.00 MXN",
27
- "Hielo Premier 3 KG": "$20.00 MXN"
28
- },
29
- "Maravatío": {
30
- "Bolsas de hielo 5 KG": "$20.00 MXN"
31
- }
32
- }
33
-
34
- # Lista completa de clientes registrados
35
- CLIENTES_REGISTRADOS = {
36
- # Ruta Local - Acámbaro
37
- "Mariscos Acámbaro", "El Frontón", "Panchito", "Depósito Goretti", "KUATO",
38
- "J. Socorro", "La Tobara", "Vinos París", "Depósito París", "Taquería Matamoros",
39
- "Jovita Rosiles", "Juan Olivarez", "Vinos Cony", "Pomodoro", "Galú",
40
- "Miscelánea Ortiz", "La Chiquita Sabino", "Depósito Acámbaro", "Abarrotes Gamma San Isidro",
41
- "Abarrotes Paty", "Valle de Acámbaro Zamudio", "Garibaldi", "Súper Saturno",
42
- "Portal 500", "Abarrotes Jairo", "Deportivo", "Depósito Ricky", "Maguey 500",
43
- "Depósito La Pista", "Las Palomas", "Café 296", "Abarrotes El Rey", "Depósito El Chido",
44
- "La Estancia", "Bariloche", "Depósito Juárez", "Tío Sam", "Autolata Maquinita",
45
- "Servicio Lerma", "Depósito Kuate", "Servicio Carranza", "Los Cocos",
46
- "Farmacia Guadalajara Carranza", "Villa del Mar", "Depósito Zaragoza", "Depósito Abasolo",
47
- "Abarrotes Luna", "La Mitotera", "Gasolinera Caballito", "Depósito Las Trancas",
48
- "Abarrotes Las Trancas", "Modelorama Agencia Corona", "Tornero Morelia", "Depósito Micky",
49
- "Acuarium", "Arrecife", "Depósito 20 de Noviembre", "FMCIA GDJL Hidalgo 122",
50
- "INCHAMACUARO", "Alma Rosa", "Depósito Monteprieto", "Obrajuelo", "Vinatería Obrajuelo",
51
- "Langosticos", "Saul Mandujano", "Esther Mandujano", "Farmacia Inchamacuaro",
52
- "FMCIA GDJL Central 458", "CHAMACUARO", "DN BALDEMAR", "Cremería 2000",
53
- "Abarrotes Elvira", "Depósito Chido", "Depósito Rojas", "Bar Califa", "Buenavista",
54
- "Depósito Pedro Moreno", "Mod. Casandra", "3B (5 de Febrero, Guerrero, Hidalgo)",
55
- "Bar Mi Oficina", "Modelorama Agencia", "Agüitas",
56
-
57
- # Comunidades Acámbaro
58
- "Vinatería Santa Fe", "Depósito Chupícuaro D. Pacos", "Vinatería San Pedro",
59
- "Abarrotes Ángel Cereso", "Larguitas Los Ángeles", "Abarrotes Guerrero", "Don Arturo",
60
- "Tornero San Cayetano", "La Chiquita Chupícuaro", "Frutería Rosales", "Abarrotes Mi Alma",
61
- "Abarrotes El Museo", "Guadalupe", "Abarrotes Gamma", "Don Mariano", "Gasolinera Parácuaro",
62
- "Vinos La California", "Depósito La Wera", "Caba Mi Pueblo", "Hotel Los Pericos",
63
- "Vinos El Porvenir", "Súper El Capricho", "Depósito Roque", "La Encarnación",
64
-
65
- # Ruta Foránea
66
- "Abarrotes Hervideros", "Ramiro Orozco", "Irlanda Arriba", "Irlanda", "Wingo",
67
- "Abarrotes Wingo", "Abarrotes Hernández", "Abarrotes F1", "Farmacia Guadalajara 1216",
68
- "3B Centro", "Hotel Los Ángeles", "Milla Plastic", "Farmacia Guadalajara 334",
69
- "Comercializadora", "Nicolás Hernández", "Short Stop", "Pickup", "Pickup Lata",
70
- "Súper Bee", "Modelorama El Sabino", "Campo Hermoso", "Minisúper Gym", "Súper K 16",
71
- "Súper K Colonia", "Vinatería El Vergel", "3B (Arteaga, Centro, Morelos, Urquiza)",
72
- "Abarrotes Cecy", "Abarrotes Estrella", "Depósito Jaripeo Faby", "Mod. Jaripeo",
73
- "Iramuco", "Abarrotes Junior", "Paniagua", "Vinatería 2000", "El Zapote", "3B Iramuco",
74
- "Bar Portales", "La Cava", "La Pasadita", "Gasolinera El Moral", "Depósito Ruta 126",
75
- "La Colmena"
76
- }
77
-
78
- # --- Funciones Auxiliares ---
79
- def es_cliente_registrado(texto: str) -> bool:
80
- """Verifica si el texto menciona algún cliente registrado."""
81
- texto = texto.lower()
82
- return any(cliente.lower() in texto for cliente in CLIENTES_REGISTRADOS)
83
-
84
- def obtener_region(texto: str) -> str:
85
- """Determina la región basada en el texto del cliente."""
86
- texto = texto.lower()
87
- if any(palabra in texto for palabra in ["maravatío", "zinapécuaro", "santa ana maya"]):
88
- return "Maravatío"
89
- elif any(palabra in texto for palabra in ["tarandacuao", "zinapécuaro", "comunidad"]):
90
- return "Comunidades, Zinapecuaro y Tarandacuao"
91
- elif "acámbaro" in texto:
92
- return "Acámbaro Gto."
93
- return None
94
-
95
- def obtener_precios(es_cliente: bool, region: str = None) -> str:
96
- """Devuelve la lista de precios según el tipo de cliente y región."""
97
- if es_cliente and region in PRECIOS_CLIENTE:
98
- precios = PRECIOS_CLIENTE[region]
99
- return "Precios para clientes registrados:\n" + "\n".join([f"- {producto}: {precio}" for producto, precio in precios.items()])
100
  else:
101
- return "Precios al público:\n" + "\n".join([f"- {producto}: {precio}" for producto, precio in PRECIOS_PUBLICO.items()])
102
-
103
- @st.cache_resource
104
- def cargar_modelo():
105
- """Carga el modelo Gemini con caché."""
106
- api_key = os.environ.get("GEMINI_API_KEY")
107
- if not api_key:
108
- raise ValueError("API key de Gemini no configurada")
109
- genai.configure(api_key=api_key)
110
- return genai.GenerativeModel('gemini-1.5-flash')
111
-
112
- def configurar_registro():
113
- """Configura el sistema de registro."""
114
- logging.basicConfig(
115
- filename="registro_uso_hielo_polar.txt",
116
- level=logging.INFO,
117
- format="%(asctime)s - %(message)s"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  )
119
 
120
- def mostrar_interfaz_admin():
121
- """Muestra la interfaz administrativa si está autorizado."""
122
- query_params = st.query_params
123
- if query_params.get("admin") == "1234":
124
- st.sidebar.title("Panel Administrativo")
125
- if os.path.exists("registro_uso_hielo_polar.txt"):
126
- with open("registro_uso_hielo_polar.txt", "rb") as f:
127
- st.sidebar.download_button(
128
- label="⬇️ Descargar registro de uso",
129
- data=f,
130
- file_name="registro_uso_hielo_polar.txt",
131
- mime="text/plain"
132
- )
133
- else:
134
- st.sidebar.warning("No se encontró el archivo de registro.")
135
-
136
- # --- Instrucciones del Sistema ---
137
- INSTRUCCIONES = """Eres un asistente virtual especializado en Hielo Polar del Centro (Acámbaro, Guanajuato).
138
-
139
- Información clave:
140
- 1. Productos y precios:
141
- - Barras industriales 75kg: $100 (molienda gratis)
142
- - Bolsas 5kg: $25 público / $18 clientes
143
- - Bolsas 3kg: $18 público / $13 clientes
144
- - Hielo Premier: $26 público / $20 clientes
145
-
146
- 2. Horarios:
147
- - Lunes a sábado: 6am-7pm
148
- - Domingo: 6am-2pm
149
-
150
- 3. Contacto:
151
- - Tel: (417) 172-1455
152
- - WhatsApp: (417) 172-1455
153
- - Email: contacto@hielolapolar.com
154
-
155
- 4. Conservadores:
156
- - Vida útil: 7 años
157
- - Para fallas: guiar en diagnóstico básico
158
- - Proporcionar indicaciones claras
159
-
160
- Reglas:
161
- - Validar si es cliente antes de dar precios especiales
162
- - Nunca revelar información confidencial
163
- - Mantener tono profesional y amable
164
- - Ser conciso pero útil
165
- - No proporcionar precios a usuarios no identificados."""
166
-
167
- # --- Interfaz Principal ---
168
- def main():
169
- configurar_registro()
170
- mostrar_interfaz_admin()
171
-
172
- modelo = cargar_modelo()
173
-
174
- # Inicializar chat
175
- if "chat" not in st.session_state:
176
- st.session_state.chat = modelo.start_chat(history=[])
177
- mensaje_inicial = "🐻‍❄️ ¡Hola! Soy tu asistente de Hielo Polar del Centro. ¿Cómo puedo ayudarte hoy?"
178
- st.session_state.mensajes = [{"role": "assistant", "content": mensaje_inicial}]
179
-
180
- # Mostrar historial
181
- st.title("Asistente Virtual de Hielo Polar 💬")
182
- for msg in st.session_state.mensajes:
183
- with st.chat_message(msg["role"]):
184
- st.markdown(msg["content"])
185
-
186
- # Procesar consulta
187
- if pregunta := st.chat_input("Escribe tu consulta aquí..."):
188
- if len(pregunta) > 500:
189
- st.warning("Por favor, limita tu consulta a 500 caracteres")
190
- return
191
-
192
- logging.info(f"Consulta: {pregunta}")
193
- st.session_state.mensajes.append({"role": "user", "content": pregunta})
194
-
195
- with st.chat_message("user"):
196
- st.markdown(pregunta)
197
-
198
- # Preparar contexto
199
- contexto = ""
200
- if any(palabra in pregunta.lower() for palabra in ["precio", "cuesta", "valor", "cuánto"]):
201
- es_cliente = es_cliente_registrado(pregunta)
202
- region = obtener_region(pregunta)
203
- contexto = f"\nContexto de precios:\n{obtener_precios(es_cliente, region)}"
204
-
205
- # Generar respuesta
206
- with st.chat_message("assistant"):
207
- try:
208
- respuesta = st.session_state.chat.send_message(
209
- f"Instrucciones: {INSTRUCCIONES}\n"
210
- f"{contexto}\n"
211
- f"Consulta del cliente: {pregunta}\n"
212
- "Por favor responde de manera clara y concisa:"
213
- )
214
-
215
- respuesta_texto = respuesta.text
216
- st.markdown(respuesta_texto)
217
- st.session_state.mensajes.append({"role": "assistant", "content": respuesta_texto})
218
- logging.info(f"Respuesta: {respuesta_texto[:200]}...")
219
-
220
- except Exception as e:
221
- error_msg = "⚠️ Ocurrió un error al procesar tu consulta. Por favor intenta nuevamente."
222
- st.error(error_msg)
223
- logging.error(f"Error: {str(e)}")
224
 
225
  if __name__ == "__main__":
226
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ Basic Agent Evaluation Runner"""
2
  import os
3
+ import inspect
4
+ import gradio as gr
5
+ import requests
6
+ import pandas as pd
7
+ from langchain_core.messages import HumanMessage
8
+ from agent import build_graph
9
+
10
+
11
+
12
+ # (Keep Constants as is)
13
+ # --- Constants ---
14
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
15
+
16
+ # --- Basic Agent Definition ---
17
+ # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
18
+
19
+
20
+ class BasicAgent:
21
+ """A langgraph agent."""
22
+ def __init__(self):
23
+ print("BasicAgent initialized.")
24
+ self.graph = build_graph()
25
+
26
+ def __call__(self, question: str) -> str:
27
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
28
+ # Wrap the question in a HumanMessage from langchain_core
29
+ messages = [HumanMessage(content=question)]
30
+ messages = self.graph.invoke({"messages": messages})
31
+ answer = messages['messages'][-1].content
32
+ return answer[14:]
33
+
34
+
35
+ def run_and_submit_all( profile: gr.OAuthProfile | None):
36
+ """
37
+ Fetches all questions, runs the BasicAgent on them, submits all answers,
38
+ and displays the results.
39
+ """
40
+ # --- Determine HF Space Runtime URL and Repo URL ---
41
+ space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
42
+
43
+ if profile:
44
+ username= f"{profile.username}"
45
+ print(f"User logged in: {username}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  else:
47
+ print("User not logged in.")
48
+ return "Please Login to Hugging Face with the button.", None
49
+
50
+ api_url = DEFAULT_API_URL
51
+ questions_url = f"{api_url}/questions"
52
+ submit_url = f"{api_url}/submit"
53
+
54
+ # 1. Instantiate Agent ( modify this part to create your agent)
55
+ try:
56
+ agent = BasicAgent()
57
+ except Exception as e:
58
+ print(f"Error instantiating agent: {e}")
59
+ return f"Error initializing agent: {e}", None
60
+ # In the case of an app running as a hugging Face space, this link points toward your codebase ( usefull for others so please keep it public)
61
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
62
+ print(agent_code)
63
+
64
+ # 2. Fetch Questions
65
+ print(f"Fetching questions from: {questions_url}")
66
+ try:
67
+ response = requests.get(questions_url, timeout=15)
68
+ response.raise_for_status()
69
+ questions_data = response.json()
70
+ if not questions_data:
71
+ print("Fetched questions list is empty.")
72
+ return "Fetched questions list is empty or invalid format.", None
73
+ print(f"Fetched {len(questions_data)} questions.")
74
+ except requests.exceptions.RequestException as e:
75
+ print(f"Error fetching questions: {e}")
76
+ return f"Error fetching questions: {e}", None
77
+ except requests.exceptions.JSONDecodeError as e:
78
+ print(f"Error decoding JSON response from questions endpoint: {e}")
79
+ print(f"Response text: {response.text[:500]}")
80
+ return f"Error decoding server response for questions: {e}", None
81
+ except Exception as e:
82
+ print(f"An unexpected error occurred fetching questions: {e}")
83
+ return f"An unexpected error occurred fetching questions: {e}", None
84
+
85
+ # 3. Run your Agent
86
+ results_log = []
87
+ answers_payload = []
88
+ print(f"Running agent on {len(questions_data)} questions...")
89
+ for item in questions_data:
90
+ task_id = item.get("task_id")
91
+ question_text = item.get("question")
92
+ if not task_id or question_text is None:
93
+ print(f"Skipping item with missing task_id or question: {item}")
94
+ continue
95
+ try:
96
+ submitted_answer = agent(question_text)
97
+ answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
98
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
99
+ except Exception as e:
100
+ print(f"Error running agent on task {task_id}: {e}")
101
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
102
+
103
+ if not answers_payload:
104
+ print("Agent did not produce any answers to submit.")
105
+ return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
106
+
107
+ # 4. Prepare Submission
108
+ submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
109
+ status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
110
+ print(status_update)
111
+
112
+ # 5. Submit
113
+ print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
114
+ try:
115
+ response = requests.post(submit_url, json=submission_data, timeout=60)
116
+ response.raise_for_status()
117
+ result_data = response.json()
118
+ final_status = (
119
+ f"Submission Successful!\n"
120
+ f"User: {result_data.get('username')}\n"
121
+ f"Overall Score: {result_data.get('score', 'N/A')}% "
122
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
123
+ f"Message: {result_data.get('message', 'No message received.')}"
124
+ )
125
+ print("Submission successful.")
126
+ results_df = pd.DataFrame(results_log)
127
+ return final_status, results_df
128
+ except requests.exceptions.HTTPError as e:
129
+ error_detail = f"Server responded with status {e.response.status_code}."
130
+ try:
131
+ error_json = e.response.json()
132
+ error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
133
+ except requests.exceptions.JSONDecodeError:
134
+ error_detail += f" Response: {e.response.text[:500]}"
135
+ status_message = f"Submission Failed: {error_detail}"
136
+ print(status_message)
137
+ results_df = pd.DataFrame(results_log)
138
+ return status_message, results_df
139
+ except requests.exceptions.Timeout:
140
+ status_message = "Submission Failed: The request timed out."
141
+ print(status_message)
142
+ results_df = pd.DataFrame(results_log)
143
+ return status_message, results_df
144
+ except requests.exceptions.RequestException as e:
145
+ status_message = f"Submission Failed: Network error - {e}"
146
+ print(status_message)
147
+ results_df = pd.DataFrame(results_log)
148
+ return status_message, results_df
149
+ except Exception as e:
150
+ status_message = f"An unexpected error occurred during submission: {e}"
151
+ print(status_message)
152
+ results_df = pd.DataFrame(results_log)
153
+ return status_message, results_df
154
+
155
+
156
+ # --- Build Gradio Interface using Blocks ---
157
+ with gr.Blocks() as demo:
158
+ gr.Markdown("# Basic Agent Evaluation Runner")
159
+ gr.Markdown(
160
+ """
161
+ **Instructions:**
162
+ 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
163
+ 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
164
+ 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
165
+ ---
166
+ **Disclaimers:**
167
+ Once clicking on the "submit button, it can take quite some time ( this is the time for the agent to go through all the questions).
168
+ This space provides a basic setup and is intentionally sub-optimal to encourage you to develop your own, more robust solution. For instance for the delay process of the submit button, a solution could be to cache the answers and submit in a seperate action or even to answer the questions in async.
169
+ """
170
  )
171
 
172
+ gr.LoginButton()
173
+
174
+ run_button = gr.Button("Run Evaluation & Submit All Answers")
175
+
176
+ status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
177
+ # Removed max_rows=10 from DataFrame constructor
178
+ results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
179
+
180
+ run_button.click(
181
+ fn=run_and_submit_all,
182
+ outputs=[status_output, results_table]
183
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
  if __name__ == "__main__":
186
+ print("\n" + "-"*30 + " App Starting " + "-"*30)
187
+ # Check for SPACE_HOST and SPACE_ID at startup for information
188
+ space_host_startup = os.getenv("SPACE_HOST")
189
+ space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
190
+
191
+ if space_host_startup:
192
+ print(f"✅ SPACE_HOST found: {space_host_startup}")
193
+ print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
194
+ else:
195
+ print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
196
+
197
+ if space_id_startup: # Print repo URLs if SPACE_ID is found
198
+ print(f"✅ SPACE_ID found: {space_id_startup}")
199
+ print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
200
+ print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
201
+ else:
202
+ print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
203
+
204
+ print("-"*(60 + len(" App Starting ")) + "\n")
205
+
206
+ print("Launching Gradio Interface for Basic Agent Evaluation...")
207
+ demo.launch(debug=True, share=False)