MGLDZM commited on
Commit
a1888d0
·
1 Parent(s): 3c51054

Dev end stable...

Browse files
logs/function.output.log DELETED
@@ -1,18 +0,0 @@
1
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': 'assistant', 'tool_calls': None}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
2
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 0, 'id': 'call_1lF6wX8Fl9qIDabi0eN1agXL', 'function': {'arguments': '', 'name': 'buscar_google'}, 'type': 'function'}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
3
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 0, 'id': None, 'function': {'arguments': '{"bu', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
4
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 0, 'id': None, 'function': {'arguments': 'squed', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
5
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 0, 'id': None, 'function': {'arguments': 'a": "n', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
6
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 0, 'id': None, 'function': {'arguments': 'otic', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
7
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 0, 'id': None, 'function': {'arguments': 'ias d', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
8
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 0, 'id': None, 'function': {'arguments': 'e hoy"', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
9
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 0, 'id': None, 'function': {'arguments': '}', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
10
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 1, 'id': 'call_Hqn7hcl7lEcD87e22JTyHqVf', 'function': {'arguments': '', 'name': 'buscar_google'}, 'type': 'function'}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
11
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 1, 'id': None, 'function': {'arguments': '{"bu', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
12
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 1, 'id': None, 'function': {'arguments': 'squed', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
13
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 1, 'id': None, 'function': {'arguments': 'a": "ú', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
14
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 1, 'id': None, 'function': {'arguments': 'ltim', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
15
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 1, 'id': None, 'function': {'arguments': 'as no', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
16
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 1, 'id': None, 'function': {'arguments': 'ticias', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
17
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': [{'index': 1, 'id': None, 'function': {'arguments': '"}', 'name': None}, 'type': None}]}, 'finish_reason': None, 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
18
- {'id': 'chatcmpl-8YgAMqR5wAbKdaFDxrtFsM0CVOaWd', 'choices': [{'delta': {'content': None, 'function_call': None, 'role': None, 'tool_calls': None}, 'finish_reason': 'tool_calls', 'index': 0, 'logprobs': None}], 'created': 1703275930, 'model': 'gpt-3.5-turbo-1106', 'object': 'chat.completion.chunk', 'system_fingerprint': 'fp_772e8125bb'}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
main.py CHANGED
@@ -17,7 +17,7 @@ app.mount("/static", StaticFiles(directory="static"), name="static")
17
  templates = Jinja2Templates(directory="templates")
18
 
19
  fecha_unix = str(int(time.time()))
20
- log_module.log_write("master", "iniciado", "-")
21
  ##########################################################
22
 
23
 
@@ -141,12 +141,11 @@ async def get_token(response: Response, user: User_find_from_data):
141
  async def chat_async(session: Session_find_from_data):
142
  chat = model.Chat(messages = session.data["messages"])
143
  if(len(chat.messages) < 1 or chat.messages[-1].content==""):
144
- log_module.logger.warning(session.gid, "Mensaje RQ", "error, mensajes vacios")
145
  raise HTTPException(
146
  status_code=status.HTTP_418_IM_A_TEAPOT,
147
  detail= "Nope"
148
  )
149
-
150
  return StreamingResponse(llm.streamer(chat, session), media_type="application/json")
151
 
152
 
@@ -171,7 +170,7 @@ async def on_hold(request: Request, user: User = Depends(User.find_from_cookie))
171
  form = await request.form()
172
  if message := form["message"].strip():
173
  user.update_description(message)
174
-
175
  return templates.TemplateResponse(
176
  "no_access.html", {
177
  "request": request,
 
17
  templates = Jinja2Templates(directory="templates")
18
 
19
  fecha_unix = str(int(time.time()))
20
+ log_module.logger("system").info("iniciado")
21
  ##########################################################
22
 
23
 
 
141
  async def chat_async(session: Session_find_from_data):
142
  chat = model.Chat(messages = session.data["messages"])
143
  if(len(chat.messages) < 1 or chat.messages[-1].content==""):
144
+ log_module.logger(session.gid).warning("Empty message")
145
  raise HTTPException(
146
  status_code=status.HTTP_418_IM_A_TEAPOT,
147
  detail= "Nope"
148
  )
 
149
  return StreamingResponse(llm.streamer(chat, session), media_type="application/json")
150
 
151
 
 
170
  form = await request.form()
171
  if message := form["message"].strip():
172
  user.update_description(message)
173
+
174
  return templates.TemplateResponse(
175
  "no_access.html", {
176
  "request": request,
modules/chat_functions/buscar_google.py CHANGED
@@ -20,15 +20,13 @@ info = {
20
  "type": "function",
21
  "function":{
22
  "name": "buscar_google",
23
- "description": "Un API de Búsqueda de Google. Útil cuando necesitas responder preguntas sobre\
24
- eventos actuales, personas o noticias. Utiliza esta herramienta especialmente cuando busques\
25
- información sobre eventos o personas. El resultado será un JSON { \n\
26
  \"conseguidos\": [\n\
27
  { \n\
28
- \"titulo\": este contendrá el titulo del enlace , \n\
29
- \"link\": este contendrá el enlace a la pagina donde está la información, puedes usar este enlace en \
30
- la herramienta leer_pagina_web si está disponible para obtener más información, \n\
31
- \"resumen\": este contendrá un resumen del contenido de la pagina \n\
32
  },\n\
33
  ...\n\
34
  ] \n\
@@ -38,18 +36,18 @@ info = {
38
  "properties": {
39
  "busqueda": {
40
  "type": "string",
41
- "description": "El termino a buscar en google para obtener información. e.g. Alejandro Magno",
42
- },
43
  },
44
  "required": ["busqueda"],
45
  }}
46
  }
47
 
48
- def ejecutar(busqueda):
 
49
  try:
50
- print(busqueda)
51
  service = build("customsearch", "v1", developerKey=api_key)
52
- results = service.cse().list(q=busqueda, cx=cse_id).execute()
53
  retorno = {}
54
  retorno["conseguidos"] = []
55
  for result in results["items"]:
@@ -59,10 +57,10 @@ def ejecutar(busqueda):
59
  "link": result["link"],
60
  "resumen": result["snippet"]
61
  })
62
- print(retorno)
63
  return json.dumps(retorno)
64
  except Exception as e:
65
- log_module.logger.error(repr(e))
66
  return json.dumps({"status": "api failed"})
67
 
68
 
 
20
  "type": "function",
21
  "function":{
22
  "name": "buscar_google",
23
+ "description": "API de Búsqueda en Google. Usa esta herramienta cuando debas obtener información sobre eventos actuales, personas o noticias. Utiliza esta herramienta ¡SOLO CUANDO SEA NECESARIO! y si tu margen de seguridad sobre la información es menor al 50%. Interpreta la información de manera objetiva para responder un resultado facil de leer. Evita usarlo esta herramienta a con frecuencia.\n\
24
+ El resultado de la ejecución será un JSON { \n\
 
25
  \"conseguidos\": [\n\
26
  { \n\
27
+ \"titulo\": este contendrá el titulo del enlace\n\
28
+ \"link\": link al la pagina donde se encuentra la información \n\
29
+ \"resumen\": este contendrá un resumen del contenido de la pagina, usa esta información para extrapolar una respuesta una respuesta util para el usuario \n\
 
30
  },\n\
31
  ...\n\
32
  ] \n\
 
36
  "properties": {
37
  "busqueda": {
38
  "type": "string",
39
+ "description": "El termino a buscar en google para obtener información. e.g. Conquistas de Alejandro Magno en Asia",
40
+ }
41
  },
42
  "required": ["busqueda"],
43
  }}
44
  }
45
 
46
+ def ejecutar(params, gid):
47
+ busqueda = params["busqueda"]
48
  try:
 
49
  service = build("customsearch", "v1", developerKey=api_key)
50
+ results = service.cse().list(q=busqueda, cx=cse_id, gl="ve").execute()
51
  retorno = {}
52
  retorno["conseguidos"] = []
53
  for result in results["items"]:
 
57
  "link": result["link"],
58
  "resumen": result["snippet"]
59
  })
60
+ log_module.logger(gid).info(f"Searh google {params}")
61
  return json.dumps(retorno)
62
  except Exception as e:
63
+ log_module.logger(gid).error(f"Searh google failed: {repr(e)}")
64
  return json.dumps({"status": "api failed"})
65
 
66
 
modules/llm.py CHANGED
@@ -40,13 +40,14 @@ def ejecutar(chat: "model.Chat", session: "model.Session"):
40
 
41
  return generated
42
  except Exception as error:
43
- log_module.logger.error(repr(error) + " - " + session.gid)
44
  raise HTTPException( **error_map.error_table.get(type(error), error_map.error_table["undefined"]))
45
 
46
  async def streamer(chat: "model.Chat", session: "model.Session", sub_exec:bool = False):
47
  response_async = ejecutar(chat, session)
 
 
48
 
49
- yield json.dumps({"comando": "status", "status":{"mensaje":"Cargando", "modo": "reemplazar"}})
50
  message = None
51
  role = None
52
 
@@ -59,46 +60,22 @@ async def streamer(chat: "model.Chat", session: "model.Session", sub_exec:bool =
59
  chat.append(message)
60
  else:
61
  message = chat.new_func(role, response_async, chunk)
62
- message.exec()
 
 
63
 
64
  chat.append(message)
65
 
66
  async for r_async in streamer(chat, session, True):
67
  yield r_async
68
 
69
- if sub_exec:
70
- return
71
- # st = time.time()
72
- # st_times = 0
73
- # if time.time() - st > 3:
74
- # if st_times > 2:
75
- # yield json.dumps({"comando": "status", "status":{"mensaje":"Cargando", "modo": "reemplazar"}})
76
- # st_times = 0
77
- # else:
78
- # yield json.dumps({"comando": "status", "status":{"mensaje":".", "modo": "enlinea"}})
79
- # st_times += 1
80
- # st = time.time()
81
-
82
- yield json.dumps({"comando": "status", "status":{"mensaje":"Cargando", "modo": "reemplazar"}})
83
-
84
-
85
-
86
- # if functions_exec:
87
- # for i in functions_exec:
88
- # i.exec()
89
- # chat.messages.append(i)
90
-
91
-
92
- # async for out in streamer(chat, session):
93
- # yield out
94
-
95
-
96
- #session.update_usage(message)
97
-
98
 
99
- yield json.dumps({"comando":"challenge", "challenge": session.challenge} )
100
- yield json.dumps({"comando":"token", "token": session.create_cookie_token() } )
101
- yield json.dumps({"comando":"mensaje", "mensaje": chat.messages[-1].model_dump()} )
 
102
 
103
 
104
 
 
40
 
41
  return generated
42
  except Exception as error:
43
+ log_module.logger(session.gid).error(repr(error) + " - " + session.gid)
44
  raise HTTPException( **error_map.error_table.get(type(error), error_map.error_table["undefined"]))
45
 
46
  async def streamer(chat: "model.Chat", session: "model.Session", sub_exec:bool = False):
47
  response_async = ejecutar(chat, session)
48
+ if not sub_exec:
49
+ yield json.dumps({"comando": "status", "status":{"mensaje":"Cargando", "modo": "reemplazar"}})
50
 
 
51
  message = None
52
  role = None
53
 
 
60
  chat.append(message)
61
  else:
62
  message = chat.new_func(role, response_async, chunk)
63
+ if not sub_exec:
64
+ yield json.dumps({"comando": "status", "status":{"mensaje":"Buscando en google o algo así", "modo": "reemplazar"}})
65
+ message.exec(session.gid)
66
 
67
  chat.append(message)
68
 
69
  async for r_async in streamer(chat, session, True):
70
  yield r_async
71
 
72
+ if not sub_exec:
73
+ session.update_usage(chat.tokens)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
+ log_module.logger(session.gid).info(f"Chat used, tokens: {chat.tokens}")
76
+ yield json.dumps({"comando":"challenge", "challenge": session.challenge} )
77
+ yield json.dumps({"comando":"token", "token": session.create_cookie_token() } )
78
+ yield json.dumps({"comando":"mensaje", "mensaje": chat.messages[-1].model_dump()} )
79
 
80
 
81
 
modules/log_module.py CHANGED
@@ -12,7 +12,7 @@ stream_handler = logging.StreamHandler()
12
  stream_handler.setLevel(logging.DEBUG)
13
 
14
  # Define el formato de los mensajes de log
15
- formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(user)s - %(action)s - %(message)s')
16
 
17
  file_handler.setFormatter(formatter)
18
  stream_handler.setFormatter(formatter)
@@ -21,9 +21,5 @@ stream_handler.setFormatter(formatter)
21
  _logger.addHandler(file_handler)
22
  _logger.addHandler(stream_handler)
23
 
24
-
25
- logger = logging.LoggerAdapter(_logger, extra={'user': "system", 'action': ""})
26
-
27
- def log_write(user, action, data):
28
- logger_l = logging.LoggerAdapter(_logger, extra={'user': user, 'action': action})
29
- logger_l.info(data)
 
12
  stream_handler.setLevel(logging.DEBUG)
13
 
14
  # Define el formato de los mensajes de log
15
+ formatter = logging.Formatter('%(asctime)s [%(filename)s:%(lineno)d @ %(funcName)s] - %(levelname)s - %(user)s - %(message)s')
16
 
17
  file_handler.setFormatter(formatter)
18
  stream_handler.setFormatter(formatter)
 
21
  _logger.addHandler(file_handler)
22
  _logger.addHandler(stream_handler)
23
 
24
+ def logger(user:str = "", action:str = ""):
25
+ return logging.LoggerAdapter(_logger, extra={'user': user})
 
 
 
 
modules/model.py CHANGED
@@ -56,10 +56,14 @@ class Configs(BaseModel):
56
  class Message(BaseModel):
57
  role: str
58
  content: str = ""
59
- _tokens: int = 0
60
  _thread = None
61
  _running:bool = False
62
 
 
 
 
 
63
  def consume_stream(self, stream):
64
  self._running = True
65
  for chunk in stream:
@@ -82,7 +86,6 @@ class ToolCallsInput(BaseModel):
82
  id: str
83
  function: ToolCallsInputFunction
84
  type: str = "function"
85
- _tokens: int = 0
86
 
87
  class ToolCallsOutput(BaseModel):
88
  role: str
@@ -112,7 +115,8 @@ class MessageTool(BaseModel):
112
 
113
  while True:
114
  choice = chunk.choices[0]
115
-
 
116
  if choice.finish_reason:
117
  break
118
 
@@ -131,21 +135,23 @@ class MessageTool(BaseModel):
131
  )))
132
  elif tool_call.function.arguments:
133
  self.tool_calls[-1].function.arguments += tool_call.function.arguments
134
- self.tool_calls[-1]._tokens += 1
135
 
136
  chunk = next(stream)
137
  if not chunk:
 
138
  break
139
 
140
- def exec(self):
141
  for func in self.tool_calls:
142
  self._outputs.append(ToolCallsOutput(
143
  role="tool",
144
  tool_call_id=func.id,
145
  name=func.function.name ,
146
- content=chat_functions.function_callbacks[func.function.name](func.function.arguments)
147
  ))
148
 
 
149
  class Chat(BaseModel):
150
  messages: List[Message|MessageTool|ToolCallsOutput]
151
  tokens: int = 3
@@ -206,15 +212,15 @@ class Session(BaseModel):
206
  cookie_data:dict = security.token_from_cookie(request)
207
 
208
  if "gid" not in cookie_data or "guid" not in cookie_data:
209
- log_module.logger.error("Cookie without session needed data")
210
  security.raise_401("gid or guid not in cookie")
211
 
212
  if not (public_key := cookie_data.get("public_key", None)): # FIX Vuln Code
213
  if request.scope["path"] != "/getToken":
214
- log_module.logger.error(f"User without public key saved | {json.dumps(cookie_data)}")
215
  security.raise_401("the user must have a public key saved in token")
216
  else:
217
- log_module.logger.info(f"API public key set for user {cookie_data['gid']}")
218
  public_key = data["public_key"]
219
  else:
220
  cls.check_challenge(data["fingerprint"], cookie_data["challenge"])
@@ -230,13 +236,15 @@ class Session(BaseModel):
230
 
231
 
232
  if session.hashed != cookie_data["fprint"]:
233
- log_module.logger.error(f"Fingerprint didnt match | {json.dumps(cookie_data)}")
234
  security.raise_401("Fingerprint didnt match")
235
 
236
 
237
  session.add_challenge()
238
 
239
  return session
 
 
240
  def create_cookie_token(self:Self):
241
  return security.create_jwt_token({
242
  "gid":self.gid,
@@ -293,7 +301,7 @@ class User(BaseModel):
293
 
294
  user._session = Session(gid=user.gid, fprint=loginData["fp"], public_key=loginData["pk"])
295
 
296
- log_module.logger.info(f"User {'logged' if found else'created'}: {user.gid} | fp: {user._session.fprint}")
297
  return user
298
 
299
  @classmethod
@@ -301,13 +309,13 @@ class User(BaseModel):
301
  cookie_data:dict = security.token_from_cookie(request)
302
 
303
  if "gid" not in cookie_data or "guid" not in cookie_data:
304
- log_module.logger.error("Cookie without needed data")
305
  security.raise_307("gid or guid not in cookie")
306
 
307
  found:dict = DB.user.find_one({"gid":cookie_data["gid"]})
308
 
309
  if not found:
310
- log_module.logger.error("User not found on DB")
311
  security.raise_307("User not found on DB")
312
 
313
  user: Self = cls(**found)
@@ -321,12 +329,12 @@ class User(BaseModel):
321
 
322
  @classmethod
323
  def find_from_data(cls:Self, request: Request, data:dict) -> Self:
324
- session = Session.find_from_data(request, data)
325
 
326
  found:dict = DB.user.find_one({"gid":session.gid})
327
 
328
  if not found:
329
- log_module.logger.error("User not found on DB")
330
  security.raise_307("User not found on DB")
331
 
332
  user: Self = cls(**found)
@@ -335,7 +343,7 @@ class User(BaseModel):
335
  return user
336
 
337
  def update_description(self: Self, message: str) -> None:
338
- log_module.logger.info(f"Description Updated: {self.gid}")
339
  DB.user.update_one(
340
  {"gid":self.gid},
341
  {"$set": { "description": message}}
@@ -346,14 +354,13 @@ class User(BaseModel):
346
  return security.can_use(self.role, activity)
347
 
348
  def update_user(self: Self, message: Message = None) -> None:
349
- log_module.logger.info(f"User Updated: {self.gid}")
350
  DB.user.update_one({"gid": self.gid}, {"$set": self.model_dump()})
351
 
352
  @staticmethod
353
- def update_usage(gid:str, message:Message):
354
- count_tokens:int = message._tokens #message._tokensOutput+message._tokens
355
  inc_field = datetime.now().strftime("tokens.%y.%m.%d")
356
- DB.user.update_one({"gid": gid}, {"$inc":{inc_field: count_tokens}})
357
 
358
  def create_cookie(self:Self):
359
  return security.create_jwt_token({
 
56
  class Message(BaseModel):
57
  role: str
58
  content: str = ""
59
+ _tokens: int = 1
60
  _thread = None
61
  _running:bool = False
62
 
63
+ def __init__(self, *args, **kwargs):
64
+ super(Message, self).__init__(*args, **kwargs)
65
+ self._tokens = count_tokens_on_message([self.content])
66
+
67
  def consume_stream(self, stream):
68
  self._running = True
69
  for chunk in stream:
 
86
  id: str
87
  function: ToolCallsInputFunction
88
  type: str = "function"
 
89
 
90
  class ToolCallsOutput(BaseModel):
91
  role: str
 
115
 
116
  while True:
117
  choice = chunk.choices[0]
118
+ self._tokens += 1
119
+
120
  if choice.finish_reason:
121
  break
122
 
 
135
  )))
136
  elif tool_call.function.arguments:
137
  self.tool_calls[-1].function.arguments += tool_call.function.arguments
138
+
139
 
140
  chunk = next(stream)
141
  if not chunk:
142
+ self._tokens += sum
143
  break
144
 
145
+ def exec(self, gid):
146
  for func in self.tool_calls:
147
  self._outputs.append(ToolCallsOutput(
148
  role="tool",
149
  tool_call_id=func.id,
150
  name=func.function.name ,
151
+ content=chat_functions.function_callbacks[func.function.name](json.loads(func.function.arguments), gid)
152
  ))
153
 
154
+
155
  class Chat(BaseModel):
156
  messages: List[Message|MessageTool|ToolCallsOutput]
157
  tokens: int = 3
 
212
  cookie_data:dict = security.token_from_cookie(request)
213
 
214
  if "gid" not in cookie_data or "guid" not in cookie_data:
215
+ log_module.logger().error("Cookie without session needed data")
216
  security.raise_401("gid or guid not in cookie")
217
 
218
  if not (public_key := cookie_data.get("public_key", None)): # FIX Vuln Code
219
  if request.scope["path"] != "/getToken":
220
+ log_module.logger(cookie_data["gid"]).error(f"User without public key saved | {json.dumps(cookie_data)}")
221
  security.raise_401("the user must have a public key saved in token")
222
  else:
223
+ log_module.logger(cookie_data['gid']).info("API public key set for user")
224
  public_key = data["public_key"]
225
  else:
226
  cls.check_challenge(data["fingerprint"], cookie_data["challenge"])
 
236
 
237
 
238
  if session.hashed != cookie_data["fprint"]:
239
+ log_module.logger(session.gid).error(f"Fingerprint didnt match | {json.dumps(cookie_data)}")
240
  security.raise_401("Fingerprint didnt match")
241
 
242
 
243
  session.add_challenge()
244
 
245
  return session
246
+
247
+
248
  def create_cookie_token(self:Self):
249
  return security.create_jwt_token({
250
  "gid":self.gid,
 
301
 
302
  user._session = Session(gid=user.gid, fprint=loginData["fp"], public_key=loginData["pk"])
303
 
304
+ log_module.logger(user.gid).info(f"User {'logged' if found else'created'} | fp: {user._session.fprint}")
305
  return user
306
 
307
  @classmethod
 
309
  cookie_data:dict = security.token_from_cookie(request)
310
 
311
  if "gid" not in cookie_data or "guid" not in cookie_data:
312
+ log_module.logger().error("Cookie without needed data")
313
  security.raise_307("gid or guid not in cookie")
314
 
315
  found:dict = DB.user.find_one({"gid":cookie_data["gid"]})
316
 
317
  if not found:
318
+ log_module.logger(cookie_data["gid"]).error("User not found on DB")
319
  security.raise_307("User not found on DB")
320
 
321
  user: Self = cls(**found)
 
329
 
330
  @classmethod
331
  def find_from_data(cls:Self, request: Request, data:dict) -> Self:
332
+ session:Session = Session.find_from_data(request, data)
333
 
334
  found:dict = DB.user.find_one({"gid":session.gid})
335
 
336
  if not found:
337
+ log_module.logger(session.gid).error("User not found on DB")
338
  security.raise_307("User not found on DB")
339
 
340
  user: Self = cls(**found)
 
343
  return user
344
 
345
  def update_description(self: Self, message: str) -> None:
346
+ log_module.logger(self.gid).info("Description Updated")
347
  DB.user.update_one(
348
  {"gid":self.gid},
349
  {"$set": { "description": message}}
 
354
  return security.can_use(self.role, activity)
355
 
356
  def update_user(self: Self, message: Message = None) -> None:
357
+ log_module.logger(self.gid).info("User Updated")
358
  DB.user.update_one({"gid": self.gid}, {"$set": self.model_dump()})
359
 
360
  @staticmethod
361
+ def update_usage(gid:str, tokens:int):
 
362
  inc_field = datetime.now().strftime("tokens.%y.%m.%d")
363
+ DB.user.update_one({"gid": gid}, {"$inc":{inc_field: tokens}})
364
 
365
  def create_cookie(self:Self):
366
  return security.create_jwt_token({
modules/security.py CHANGED
@@ -27,7 +27,7 @@ def validate_jwt_token(token: str, usage: str = "api"):
27
  payload = jwt.decode(token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM])
28
  return payload
29
  except Exception as e:
30
- log_module.logger.error(repr(e) + " - Invalid token: " + str(token))
31
  if usage == "view":
32
  return raise_307("Failed validating jwt token")
33
  return raise_401("Failed validating jwt token")
 
27
  payload = jwt.decode(token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM])
28
  return payload
29
  except Exception as e:
30
+ log_module.logger().error(repr(e) + " - Invalid token: " + str(token))
31
  if usage == "view":
32
  return raise_307("Failed validating jwt token")
33
  return raise_401("Failed validating jwt token")
modules/settings.py CHANGED
@@ -7,10 +7,10 @@ from Crypto.Random import get_random_bytes
7
  def environ_get(variable, required=False):
8
  if variable not in os.environ:
9
  if not required:
10
- log_module.logger.warning(f"Variable not set {variable}")
11
  return None
12
  else:
13
- log_module.logger.error(f"Required variable not set {variable}")
14
 
15
  return os.environ[variable]
16
 
 
7
  def environ_get(variable, required=False):
8
  if variable not in os.environ:
9
  if not required:
10
+ log_module.logger("system").warning(f"Variable not set {variable}")
11
  return None
12
  else:
13
+ log_module.logger("system").error(f"Required variable not set {variable}")
14
 
15
  return os.environ[variable]
16
 
static/js/windowHandler.js CHANGED
@@ -127,6 +127,9 @@ class WindowHandler{
127
  respuestaStatus(mensaje, modo=false){
128
  let temp = $("<div></div>")
129
  temp.text(mensaje)
 
 
 
130
  switch(modo){
131
  case "enlinea":
132
  this.active.find("div p div:last-child").text(this.active.find("div p div:last-child").text() + mensaje);
@@ -223,6 +226,7 @@ class WindowHandler{
223
  resultado += "'>"+temp+"</code></pre>";
224
  }else{
225
  resultado += $("<div></div>").text(actual).html().replace(/`([^`]+?)`/gm, "<b>$1</b>").replace(/\n/g, "<br>");
 
226
  }
227
  codigo = !codigo;
228
  }
 
127
  respuestaStatus(mensaje, modo=false){
128
  let temp = $("<div></div>")
129
  temp.text(mensaje)
130
+ if(!this.active.find(".loader").hasClass("firststage")){
131
+ this.active.find(".loader").addClass("firststage")
132
+ }
133
  switch(modo){
134
  case "enlinea":
135
  this.active.find("div p div:last-child").text(this.active.find("div p div:last-child").text() + mensaje);
 
226
  resultado += "'>"+temp+"</code></pre>";
227
  }else{
228
  resultado += $("<div></div>").text(actual).html().replace(/`([^`]+?)`/gm, "<b>$1</b>").replace(/\n/g, "<br>");
229
+ resultado = resultado.replace(/\[(.+?)\]\((.+?)\)/gm, "<a href='$2'>[$1]</a>")
230
  }
231
  codigo = !codigo;
232
  }