Skip to content

Commit 56159ce

Browse files
daeltix IA
1 parent d713e0d commit 56159ce

File tree

6 files changed

+2043
-0
lines changed

6 files changed

+2043
-0
lines changed

Diff for: __pycache__/tokens.cpython-310.pyc

101 Bytes
Binary file not shown.

Diff for: back_end.py

+228
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
'''
2+
Deltix back_end
3+
'''
4+
5+
from flask import Flask, request, jsonify
6+
from supabase import create_client
7+
from openai import OpenAI, AssistantEventHandler
8+
import os
9+
import json
10+
import random
11+
from datetime import datetime
12+
13+
app = Flask(__name__)
14+
15+
supabase_url = os.getenv('SUPABASE_URL')
16+
supabase_key = os.getenv('SUPABASE_KEY')
17+
openrouter_key = os.getenv('OPENROUTER_API_KEY')
18+
19+
if not supabase_url or not supabase_key:
20+
raise ValueError("Supabase URL and Key must be set in environment variables")
21+
22+
if not openrouter_key:
23+
raise ValueError("OpenRouter API Key must be set in environment variables")
24+
25+
supabase = create_client(supabase_url, supabase_key)
26+
27+
WEATHER_KEYWORDS = ['clima', 'temperatura', 'pronostico', 'tiempo', 'lluvia', 'viento', 'llover', 'soleado', 'ventoso', 'humedad', 'tormenta', 'nublado', 'calor', 'frio']
28+
ALMACEN_KEYWORDS = ['almacen', 'almacén', 'almacenera', 'almaceneras']
29+
JILGUERO_KEYWORDS = ['jilguero', 'carapachay', 'angostura']
30+
INTERISLENA_KEYWORDS = ['interisleña', 'interislena', 'sarmiento', 'san antonio', 'capitan', 'capitán']
31+
LINEASDELTA_KEYWORDS = ['lineasdelta', 'caraguatá', 'caraguata', 'canal arias', 'paraná miní', 'parana mini', 'lineas delta']
32+
33+
client = OpenAI(
34+
base_url="https://openrouter.ai/api/v1",
35+
api_key=openrouter_key,
36+
)
37+
38+
def load_weather_data():
39+
try:
40+
weather_file_path = "rag/weather_data.json"
41+
with open(weather_file_path, 'r') as file:
42+
weather_data = json.load(file)
43+
return weather_data
44+
except Exception as e:
45+
print(f"Error loading weather data: {e}")
46+
return None
47+
48+
def format_weather_for_context(weather_data):
49+
if not weather_data:
50+
return ""
51+
try:
52+
current = weather_data.get('current_weather', {})
53+
location = current.get('name', 'Desconocido')
54+
country = current.get('sys', {}).get('country', '')
55+
temp = current.get('main', {}).get('temp', 'N/A')
56+
feels_like = current.get('main', {}).get('feels_like', 'N/A')
57+
description = current.get('weather', [{}])[0].get('description', 'N/A')
58+
humidity = current.get('main', {}).get('humidity', 'N/A')
59+
wind_speed = current.get('wind', {}).get('speed', 'N/A')
60+
timestamp_str = weather_data.get('timestamp', 'Desconocido')
61+
forecast_items = weather_data.get('forecast', {}).get('list', [])[:8]
62+
forecast_text = ""
63+
for item in forecast_items:
64+
dt_txt = item.get('dt_txt', '')
65+
temp_forecast = item.get('main', {}).get('temp', 'N/A')
66+
desc_forecast = item.get('weather', [{}])[0].get('description', 'N/A')
67+
forecast_text += f"- {dt_txt}: {temp_forecast}°C, {desc_forecast}\n"
68+
context = f"""
69+
Información del clima para {location}, {country} (actualizado el {timestamp_str}):
70+
Condiciones actuales: {temp}°C (sensación térmica de {feels_like}°C), {description}
71+
Humedad: {humidity}%, Velocidad del viento: {wind_speed} m/s
72+
73+
Pronóstico para las próximas 24 horas:
74+
{forecast_text}
75+
"""
76+
return context
77+
except Exception as e:
78+
print(f"Error formatting weather data: {e}")
79+
return "La información del clima está disponible pero no se pudo formatear correctamente."
80+
81+
def contains_weather_keywords(user_input):
82+
lower_input = user_input.lower()
83+
return any(keyword in lower_input for keyword in WEATHER_KEYWORDS)
84+
85+
def contains_almacen_keywords(user_input):
86+
lower_input = user_input.lower()
87+
return any(keyword in lower_input for keyword in ALMACEN_KEYWORDS)
88+
89+
def contains_jilguero_keywords(user_input):
90+
lower_input = user_input.lower()
91+
return any(keyword in lower_input for keyword in JILGUERO_KEYWORDS)
92+
93+
def contains_interislena_keywords(user_input):
94+
lower_input = user_input.lower()
95+
return any(keyword in lower_input for keyword in INTERISLENA_KEYWORDS)
96+
97+
def contains_lineasdelta_keywords(user_input):
98+
lower_input = user_input.lower()
99+
return any(keyword in lower_input for keyword in LINEASDELTA_KEYWORDS)
100+
101+
def load_almacen_data():
102+
try:
103+
almacen_file_path = os.path.join(os.getcwd(), "rag", "almaceneras.txt")
104+
if os.path.exists(almacen_file_path):
105+
with open(almacen_file_path, 'r', encoding='utf-8') as file:
106+
return file.read()
107+
else:
108+
print(f"Almacen data file not found at: {almacen_file_path}")
109+
return ""
110+
except Exception as e:
111+
print(f"Error loading almacen data: {e}")
112+
return ""
113+
114+
def load_transportation_data(company_name):
115+
try:
116+
file_path = os.path.join(os.getcwd(), "rag", f"{company_name}.txt")
117+
if os.path.exists(file_path):
118+
with open(file_path, 'r', encoding='utf-8') as file:
119+
return file.read()
120+
else:
121+
print(f"Transportation data file not found at: {file_path}")
122+
return ""
123+
except Exception as e:
124+
print(f"Error loading transportation data: {e}")
125+
return ""
126+
127+
def make_api_call(user_input, project_id, documents, retries=3, delay=2):
128+
try:
129+
context = []
130+
if any(keyword in user_input.lower() for keyword in ['seguridad', 'policia', 'emergencia', 'telefono']):
131+
with open("rag/policia.txt", "r") as file:
132+
context.append(file.read())
133+
if contains_weather_keywords(user_input):
134+
weather_data = load_weather_data()
135+
if weather_data:
136+
weather_context = format_weather_for_context(weather_data)
137+
context.append(weather_context)
138+
if contains_almacen_keywords(user_input):
139+
almacen_context = load_almacen_data()
140+
if almacen_context:
141+
context.append(f"Información sobre almacenes de la isla:\n{almacen_context}")
142+
if contains_jilguero_keywords(user_input):
143+
jilguero_context = load_transportation_data("jilguero")
144+
if jilguero_context:
145+
context.append(f"Información sobre la lancha colectiva Jilguero:\n{jilguero_context}")
146+
if contains_interislena_keywords(user_input):
147+
interislena_context = load_transportation_data("interislena")
148+
if interislena_context:
149+
context.append(f"Información sobre la lancha colectiva Interisleña:\n{interislena_context}")
150+
if contains_lineasdelta_keywords(user_input):
151+
lineasdelta_context = load_transportation_data("lineasdelta")
152+
if lineasdelta_context:
153+
context.append(f"Información sobre la lancha colectiva LineasDelta:\n{lineasdelta_context}")
154+
previous_messages = supabase.from_("chat_history").select("*").eq("project_id", project_id).execute().data
155+
previous_messages_content = "\n".join([msg["content"] for msg in previous_messages if msg["role"] == "user"][-5:])
156+
context_text = "\n\n".join(context)
157+
for attempt in range(retries):
158+
completion = client.chat.completions.create(
159+
extra_headers={
160+
"HTTP-Referer": "<YOUR_SITE_URL>",
161+
"X-Title": "<YOUR_SITE_NAME>",
162+
},
163+
extra_body={},
164+
model="deepseek/deepseek-chat:free",
165+
messages=[
166+
{
167+
"role": "system",
168+
"content": "Vos sos Deltix, el bot del humedal. Eres argentino y amable. Ingresando algunas de estas palabras el usuario puede obtener información útil: mareas: obtener el pronóstico de mareas, windguru: pronóstico meteorológico de windgurú, Colectivas: horarios de lanchas colectivas, memes: ver los memes más divertidos de la isla, clima/pronostico: información meteorológica actualizada, almaceneras: información sobre almacenes de la isla. Si hay información de contexto, intenta responder con esa información o guia al usuario para que ingrese las palabras clave"
169+
},
170+
{
171+
"role": "user",
172+
"content": f"{user_input}\n\nMensajes anteriores:\n{previous_messages_content}\n\nContexto:\n{context_text}"
173+
}
174+
]
175+
)
176+
response_content = completion.choices[0].message.content
177+
if response_content.strip():
178+
return response_content
179+
time.sleep(delay)
180+
raise ValueError("Received empty response from OpenRouter API after multiple attempts")
181+
except Exception as e:
182+
raise e
183+
184+
def store_chat_message(project_id, role, content):
185+
supabase.from_("chat_history").insert({"project_id": project_id, "role": role, "content": content}).execute()
186+
187+
def create_project():
188+
response = supabase.from_("projects").insert({"name": "Nueva conversacion"}).execute()
189+
return response.data[0]["id"]
190+
191+
def get_random_meme():
192+
meme_files = [f"memes/{file}" for file in os.listdir("memes") if file.endswith(".png")]
193+
return random.choice(meme_files) if meme_files else None
194+
195+
def colectivas():
196+
msg = "Elegí la empresa de lancha colectiva:\n- **Jilguero**: va por el Carapachay-Angostura\n- **Interisleña**: Sarmiento, San Antonio y muchos más\n- **LineasDelta**: Caraguatá, Canal Arias, Paraná Miní"
197+
st.session_state.chat_messages.append({"role": "assistant", "content": msg})
198+
st.chat_message("assistant", avatar="bot_icon.png").write(msg)
199+
store_chat_message(project_id, "assistant", msg)
200+
st.session_state.colectivas_step = "select_company"
201+
202+
def handle_colectivas_input(user_input):
203+
# Implement the logic to handle user input for colectivas
204+
pass
205+
206+
@app.route('/api/chat', methods=['POST'])
207+
def chat():
208+
data = request.json
209+
user_input = data.get('user_input')
210+
project_id = data.get('project_id')
211+
documents = data.get('documents', [])
212+
response_content = make_api_call(user_input, project_id, documents)
213+
store_chat_message(project_id, "user", user_input)
214+
store_chat_message(project_id, "assistant", response_content)
215+
return jsonify({"response": response_content})
216+
217+
@app.route('/api/create_project', methods=['POST'])
218+
def create_new_project():
219+
project_id = create_project()
220+
return jsonify({"project_id": project_id})
221+
222+
@app.route('/api/get_random_meme', methods=['GET'])
223+
def random_meme():
224+
meme_file = get_random_meme()
225+
return jsonify({"meme_file": meme_file})
226+
227+
if __name__ == '__main__':
228+
app.run(debug=True)

0 commit comments

Comments
 (0)