feat: AI AnP support working.
This commit is contained in:
parent
36413778e7
commit
20e877eac2
@ -1,17 +1,17 @@
|
||||
[
|
||||
["Qué es AnP", "/MD/PseudoLoRAs/AnP.md", [], false],
|
||||
["AnP - Gestores", "/MD/AnP.Managers.md", [], false],
|
||||
["AnP - Gestores - Configuraciones", "/MD/AnP.Settings.md", [], false],
|
||||
["AnP - Gestores - I18N", "/MD/AnP.i18n.md", [], false],
|
||||
["AnP - Gestores - Tipos de impresión", "/MD/AnP.PrintTypes.md", [], false],
|
||||
["AnP - Gestores - Terminal/Consola", "/MD/AnP.Terminal.md", [], false],
|
||||
["AnP - Gestores - Modelos", "/MD/AnP.Models.md", [], false],
|
||||
["AnP - Gestores - Controladores de IA", "/MD/AnP.Controllers.md", [], false],
|
||||
["AnP - Gestores - Índices", "/MD/AnP.Indexes.md", [], false],
|
||||
["AnP - Gestores - Rutas", "/MD/AnP.Routes.md", [], false],
|
||||
["AnP - Web Sockets - WebSocketServerDriver", "/MD/AnP.WebSocketServerDriver.md", [], false],
|
||||
["AnP - Intérpretes de IA - OllamaDriver", "/MD/AnP.OllamaDriver.md", [], false],
|
||||
["AnP - Servidores HTTP - HTTPDriver", "/MD/AnP.HTTPDriver.md", [], false],
|
||||
["AnP - Modelos - IA", "/MD/AnP.AIModel.md", [], false],
|
||||
["AnP - Controladores - IA", "/MD/AnP.AIController.md", [], false]
|
||||
["Gestión de gestores de AnP", "/MD/AnP.Managers.md", [], false],
|
||||
["Gestión de configuración de AnP", "/MD/AnP.Settings.md", [], false],
|
||||
["Gestión de I18N/Idiomas/Textos de AnP", "/MD/AnP.i18n.md", [], false],
|
||||
["Gestión de tipos de mensajes de consola/terminal de AnP", "/MD/AnP.PrintTypes.md", [], false],
|
||||
["Gestión de comandos de Terminal/Consola de AnP", "/MD/AnP.Terminal.md", [], false],
|
||||
["Gestión de modelos genéricos de AnP", "/MD/AnP.Models.md", [], false],
|
||||
["Gestión de controladores de AnP", "/MD/AnP.Controllers.md", [], false],
|
||||
["Gestión de archivos índice de AnP", "/MD/AnP.Indexes.md", [], false],
|
||||
["Gestión de rutas de AnP", "/MD/AnP.Routes.md", [], false],
|
||||
["Driver de Web Socket Servidor `WebSocketServerDriver` de AnP", "/MD/AnP.WebSocketServerDriver.md", [], false],
|
||||
["Intérprete de IA `OllamaDriver` de AnP", "/MD/AnP.OllamaDriver.md", [], false],
|
||||
["Driver de Servidor HTTP `HTTPDriver` de AnP", "/MD/AnP.HTTPDriver.md", [], false],
|
||||
["Modelo de respuesta para IA de AnP", "/MD/AnP.AIResponseModel.md", [], false],
|
||||
["Controlador de IA de AnP", "/MD/AnP.AIController.md", [], false]
|
||||
]
|
||||
@ -50,9 +50,9 @@
|
||||
"Debes responder ÚNICAMENTE con un array JSON de booleanos que tenga exactamente {items} elementos.\n",
|
||||
"Cada posición del array de salida debe corresponder textualmente a la posición del título en la lista original:\n\n",
|
||||
"- true: Si el título cumple el criterio.\n",
|
||||
"- false: Si el título NO cumple el criterio.\n",
|
||||
"No añadas explicaciones, solo el JSON final.\n\n",
|
||||
"Si ningún título cumple el criterio, responde con un array de booleanos con todos sus valores en false.\n",
|
||||
"- false: Si el título NO cumple el criterio.\n\n",
|
||||
"No añadas explicaciones, solo el JSON final.\n",
|
||||
"Si ningún título cumple el criterio, responde con un array de booleanos con todos sus valores en false.\n\n",
|
||||
"Lista de títulos a evaluar: \n{list}"
|
||||
],
|
||||
"ai_controller_response_system" : "Usa las siguientes guías para responder y dar soporte.{loras}",
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
## Gestión de configuración
|
||||
|
||||
Para gestionar las configuraciones de AnP hay que mandarle dichos parámetros por diccionarios, ya sea JSON como un diccionario a nivel de código. Se pueden apilar en Arrays.
|
||||
|
||||
Los parámetros de configuración son los siguientes:
|
||||
@ -1,5 +1,3 @@
|
||||
## ¿Qué es AnP?
|
||||
|
||||
AnP, de Attach & Play en inglés, es un Framework basado en Gestores y su consumo sobre un sistema de Controladores.
|
||||
|
||||
Está desarrollado en Python para el servidor; y JavaScript para el entorno cliente Web.
|
||||
@ -181,17 +181,36 @@ export const AIChatComponent = (function(){
|
||||
event.key == "Enter" && !event.shiftKey && send(item, event);
|
||||
};
|
||||
|
||||
this.write_response = (id, fragment, ok, done) => {
|
||||
// console.log([id, fragment]);
|
||||
const set_status = (conversation, message, status) => {
|
||||
console.log([conversation, message, status]);
|
||||
|
||||
const box = document.querySelector(".aichat .messages>[data-type=bot][data-id='" + id + "']"),
|
||||
status = (
|
||||
!ok ? "error" :
|
||||
done ? "done" :
|
||||
"loading"),
|
||||
status_text = anp.i18n.get(status),
|
||||
const box = document.querySelector(".aichat [data-conversation='" + conversation + "']>[data-type=bot][data-id='" + message + "']"),
|
||||
status_box = box.querySelector("[data-name=status]"),
|
||||
status_i18n_box = status_box.querySelector("[data-i18n]"),
|
||||
status_text = anp.i18n.get(status);
|
||||
|
||||
|
||||
box.setAttribute("data-status", status);
|
||||
|
||||
status_box.setAttribute("data-i18n", status);
|
||||
status_box.setAttribute("title", status_text);
|
||||
status_box.querySelector("[data-icon]").setAttribute("data-icon", status);
|
||||
status_i18n_box.setAttribute("data-i18n", status_text);
|
||||
status_i18n_box.innerHTML = status_text;
|
||||
|
||||
};
|
||||
|
||||
this.write_response = (conversation, message, fragment, ok, done) => {
|
||||
// console.log([id, fragment]);
|
||||
|
||||
const box = document.querySelector(".aichat .messages>[data-type=bot][data-id='" + message + "']"),
|
||||
// status = (
|
||||
// !ok ? "error" :
|
||||
// done ? "done" :
|
||||
// "loading"),
|
||||
// status_text = anp.i18n.get(status),
|
||||
// status_box = box.querySelector("[data-name=status]"),
|
||||
// status_i18n_box = status_box.querySelector("[data-i18n]"),
|
||||
date = Date.now(),
|
||||
tokens_box = box.querySelector("[data-name=response_tokens] .value"),
|
||||
[html, raw_html, md] = format(box.querySelector(".md-content").textContent += fragment);
|
||||
@ -203,13 +222,18 @@ export const AIChatComponent = (function(){
|
||||
|
||||
box.setAttribute("data-ok", ok);
|
||||
box.setAttribute("data-done", done);
|
||||
box.setAttribute("data-status", status);
|
||||
// box.setAttribute("data-status", status);
|
||||
|
||||
status_box.setAttribute("data-i18n", status);
|
||||
status_box.setAttribute("title", status_text);
|
||||
status_box.querySelector("[data-icon]").setAttribute("data-icon", status);
|
||||
status_i18n_box.setAttribute("data-i18n", status_text);
|
||||
status_i18n_box.innerHTML = status_text;
|
||||
// status_box.setAttribute("data-i18n", status);
|
||||
// status_box.setAttribute("title", status_text);
|
||||
// status_box.querySelector("[data-icon]").setAttribute("data-icon", status);
|
||||
// status_i18n_box.setAttribute("data-i18n", status_text);
|
||||
// status_i18n_box.innerHTML = status_text;
|
||||
|
||||
set_status(conversation, message, (
|
||||
!ok ? "error" :
|
||||
done ? "done" :
|
||||
"loading"));
|
||||
|
||||
box.querySelector("[data-name=date_to]").querySelector(".value").innerHTML = date;
|
||||
box.querySelector("[data-name=time]").querySelector(".value").innerHTML = date - Number(box.querySelector("[data-name=date_from] .value").innerText);
|
||||
@ -217,6 +241,10 @@ export const AIChatComponent = (function(){
|
||||
|
||||
};
|
||||
|
||||
this.change_status = (conversation, message, status) => {
|
||||
set_status(conversation, message, status);
|
||||
};
|
||||
|
||||
constructor();
|
||||
};
|
||||
|
||||
|
||||
@ -32,20 +32,34 @@ export const AIController = (function(){
|
||||
*/
|
||||
const constructor = () => {};
|
||||
|
||||
this.test = (...parameters) => {
|
||||
console.log(parameters);
|
||||
/**
|
||||
* @param {!Object.<string, any|null>} data
|
||||
* @param {!number} code
|
||||
* @return {void}
|
||||
* @access private
|
||||
*/
|
||||
this.message = (data, code) => {
|
||||
anp.components.aichat.write_response(
|
||||
data.data.conversation,
|
||||
data.data.message,
|
||||
data.data.response,
|
||||
data.data.ok,
|
||||
data.data.done
|
||||
);
|
||||
};
|
||||
|
||||
this.message = (data, code) => {
|
||||
|
||||
anp.components.aichat.write_response(data.data.data_id, data.data.response, data.data.ok, data.data.done);
|
||||
|
||||
// const box = document.querySelector(".aichat .messages [data-type=bot][data-id=" + data.data.data_id + "]");
|
||||
|
||||
// box.querySelector(".content").innerHTML += data.data.response;
|
||||
// box.setAttribute("data-done", data.data.done);
|
||||
// box.setAttribute("data-ok", data.data.ok);
|
||||
|
||||
/**
|
||||
* @param {!Object.<string, any|null>} data
|
||||
* @param {!number} code
|
||||
* @return {void}
|
||||
* @access private
|
||||
*/
|
||||
this.status = (data, code) => {
|
||||
anp.components.aichat.change_status(
|
||||
data.data.conversation,
|
||||
data.data.message,
|
||||
data.data.status
|
||||
);
|
||||
};
|
||||
|
||||
constructor();
|
||||
|
||||
@ -1277,6 +1277,9 @@
|
||||
content: "\f164";
|
||||
font-family: "FA6FR";
|
||||
}
|
||||
.anp [data-icon=analyzing]::before {
|
||||
content: "\e522";
|
||||
}
|
||||
.anp [data-icon=think]::before {
|
||||
content: "\f731";
|
||||
font-family: "FA6FB";
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -25,6 +25,7 @@
|
||||
[data-icon=raw_html]::before{content : unicode("f121");}
|
||||
[data-icon=md]::before{content : unicode("f1c9");}
|
||||
[data-icon=done]::before{content : unicode("f164"); font-family : $FA6FR;}
|
||||
[data-icon=analyzing]::before{content : unicode("e522");}
|
||||
[data-icon=think]::before{content : unicode("f731"); font-family : $FA6FB;}
|
||||
[data-icon=loading]::before{content : unicode("f110");}
|
||||
[data-icon=waiting]::before{content : unicode("f252");}
|
||||
@ -37,4 +38,5 @@
|
||||
[data-icon=time]::before{content : unicode("f017"); font-family : $FA6FR;}
|
||||
[data-icon=length]::before{content : unicode("f546");}
|
||||
[data-icon=response_tokens]::before{content : unicode("f4ad"); font-family : $FA6FR;}
|
||||
|
||||
}
|
||||
@ -1,65 +1,41 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Self, Any, Callable
|
||||
from typing import Self, Callable
|
||||
from Abstracts.ModelAbstract import ModelAbstract
|
||||
from Abstracts.ControllerAbstract import ControllerAbstract
|
||||
from Models.RequestModel import RequestModel
|
||||
from Models.PseudoLoRAModel import PseudoLoRAModel
|
||||
from Models.AIResponseModel import AIResponseModel
|
||||
from Utils.Common import Common
|
||||
|
||||
class AIController(ControllerAbstract, ModelAbstract):
|
||||
|
||||
# def __message_execution(self:Self, end:Callable[[], None], request:RequestModel) -> None:
|
||||
|
||||
# session:str|None = request.session.get("anp_ai_session")
|
||||
# message_id:str|None = request.get("message_id")
|
||||
# client_id:str|None = request.get("client_id")
|
||||
|
||||
# session, _ = self.anp.ai_interpreters.request(
|
||||
# "anp_responses",
|
||||
# session,
|
||||
# request.get("conversation"),
|
||||
# request.get("message"),
|
||||
# [],
|
||||
# lambda id, response: self.anp.web_socket_servers.send("anp", "ai", "message", {
|
||||
# "id" : id,
|
||||
# "conversation" : response.conversation,
|
||||
# "response" : response.response,
|
||||
# "ok" : response.ok,
|
||||
# "done" : response.done,
|
||||
# "data_id" : message_id
|
||||
# }, client_id)
|
||||
# )
|
||||
|
||||
# if session is not None:
|
||||
# request.session.set("anp_ai_session", session)
|
||||
|
||||
# end()
|
||||
|
||||
def __analyse_loras(self:Self, data:dict[str, Any], request:RequestModel, loras:list[str]) -> list[tuple[str, str]]:
|
||||
def __analyse_loras(self:Self,
|
||||
iterations:dict[str, int],
|
||||
conversation:str,
|
||||
message:str,
|
||||
request:RequestModel,
|
||||
loras:list[str]
|
||||
) -> list[tuple[str, str]]:
|
||||
|
||||
session:str|None = request.session.get("anp_loras_session")
|
||||
results:list[tuple[str, str]] = []
|
||||
results:AIResponseModel
|
||||
|
||||
print(self.anp.i18n.get("ai_controller_loras_system", {
|
||||
"items" : len(loras),
|
||||
"list" : "".join("\n" + str(i) + ". " + title for i, title in enumerate(loras))
|
||||
}))
|
||||
session, results = self.anp.ai_interpreters.request(
|
||||
"anp_titles",
|
||||
session,
|
||||
conversation,
|
||||
message,
|
||||
self.anp.i18n.get("ai_controller_loras_system", {
|
||||
"items" : len(loras),
|
||||
"list" : "".join("\n" + str(i) + ". " + title for i, title in enumerate(loras))
|
||||
})
|
||||
)
|
||||
results = Common.json_decode(results.response)
|
||||
iterations["i"] += 1
|
||||
|
||||
# session, results = self.anp.ai_interpreters.request(
|
||||
# "anp_loras",
|
||||
# session,
|
||||
# data["conversation"],
|
||||
# data["message"],
|
||||
# self.anp.i18n.get("ai_controller_loras_system", {
|
||||
# "items" : len(loras),
|
||||
# "list" : "".join("\n" + str(i) + ". " + title for i, title in enumerate(loras))
|
||||
# })
|
||||
# )
|
||||
data["i"] += 1
|
||||
|
||||
# if session is not None or data["i"] == 1:
|
||||
# request.session.set("anp_loras_session", session)
|
||||
if session is not None or iterations["i"] == 1:
|
||||
request.session.set("anp_loras_session", session)
|
||||
|
||||
return results
|
||||
|
||||
@ -71,66 +47,40 @@ class AIController(ControllerAbstract, ModelAbstract):
|
||||
conversation:str = request.get("conversation")
|
||||
message:str = request.get("message")
|
||||
loras:list[tuple[str, str]]
|
||||
loras_data:dict[str, Any] = {
|
||||
iterations:dict[str, int] = {"i" : 0}
|
||||
|
||||
self.anp.web_socket_servers.send("anp", "ai", "status", {
|
||||
"message" : message_id,
|
||||
"conversation" : conversation,
|
||||
"message" : message,
|
||||
"i" : 0
|
||||
}
|
||||
"status" : "analyzing"
|
||||
}, client_id)
|
||||
|
||||
loras = self.anp.pseudoloras.get(lambda loras:self.__analyse_loras(loras_data, request, loras))
|
||||
loras = self.anp.pseudoloras.get(lambda loras:self.__analyse_loras(iterations, conversation, message, request, loras))
|
||||
|
||||
print([title for title, _ in loras])
|
||||
session, _ = self.anp.ai_interpreters.request(
|
||||
"anp_responses",
|
||||
session,
|
||||
conversation,
|
||||
message,
|
||||
self.anp.i18n.get("ai_controller_response_system", {
|
||||
"loras" : "".join("\n\n# " + title + "\n\n" + markdown for title, markdown in loras if markdown is not None)
|
||||
}) if len(loras) else [],
|
||||
lambda id, response: self.anp.web_socket_servers.send("anp", "ai", "message", {
|
||||
"id" : id,
|
||||
"conversation" : response.conversation,
|
||||
"response" : response.response,
|
||||
"ok" : response.ok,
|
||||
"done" : response.done,
|
||||
"message" : message_id,
|
||||
"conversation" : conversation,
|
||||
}, client_id)
|
||||
)
|
||||
|
||||
# session, _ = self.anp.ai_interpreters.request(
|
||||
# "anp_responses",
|
||||
# session,
|
||||
# conversation,
|
||||
# message,
|
||||
# ("Usa las siguientes guías para responder y dar soporte.\n\n" + "".join(
|
||||
# "# " + title + "\n\n" + text + "\n\n" for title, text in loras
|
||||
# ) if len(loras) else []),
|
||||
# lambda id, response: self.anp.web_socket_servers.send("anp", "ai", "message", {
|
||||
# "id" : id,
|
||||
# "conversation" : response.conversation,
|
||||
# "response" : response.response,
|
||||
# "ok" : response.ok,
|
||||
# "done" : response.done,
|
||||
# "data_id" : message_id
|
||||
# }, client_id)
|
||||
# )
|
||||
|
||||
# if session is not None:
|
||||
# request.session.set("anp_ai_session", session)
|
||||
if session is not None:
|
||||
request.session.set("anp_ai_session", session)
|
||||
|
||||
end()
|
||||
|
||||
# def __message_by_themes_execution(self:Self, end:Callable[[], None], request:RequestModel) -> None:
|
||||
|
||||
# session:str|None = request.session.get("anp_ai_session")
|
||||
# message_id:str|None = request.get("message_id")
|
||||
# client_id:str|None = request.get("client_id")
|
||||
|
||||
# session, _ = self.anp.ai_interpreters.request(
|
||||
# "anp_responses",
|
||||
# session,
|
||||
# request.get("conversation"),
|
||||
# request.get("message"),
|
||||
# [],
|
||||
# lambda id, response: self.anp.web_socket_servers.send("anp", "ai", "message", {
|
||||
# "id" : id,
|
||||
# "conversation" : response.conversation,
|
||||
# "response" : response.response,
|
||||
# "ok" : response.ok,
|
||||
# "done" : response.done,
|
||||
# "data_id" : message_id
|
||||
# }, client_id)
|
||||
# )
|
||||
|
||||
# if session is not None:
|
||||
# request.session.set("anp_ai_session", session)
|
||||
|
||||
# end()
|
||||
|
||||
def message(self:Self, request:RequestModel) -> None:
|
||||
self.anp.queues.add("anp", self.__message_execution, request)
|
||||
request.set_response({
|
||||
|
||||
@ -91,7 +91,7 @@ class PseudoLoRAsManager:
|
||||
lora.clean_cache()
|
||||
|
||||
def get(self:Self,
|
||||
callback:Callable[[list[PseudoLoRAModel]], bool],
|
||||
callback:Callable[[list[PseudoLoRAModel]], list[bool]],
|
||||
loras:Optional[list[PseudoLoRAModel]] = None
|
||||
) -> list[tuple[str, str]]:
|
||||
|
||||
@ -102,7 +102,7 @@ class PseudoLoRAsManager:
|
||||
if loras is None:
|
||||
loras = self.__loras.copy()
|
||||
|
||||
loras_is:list[bool] = [(i, callback([lora.title])) for i, lora in enumerate(loras)]
|
||||
loras_is:list[bool] = callback([lora.title for lora in loras])
|
||||
|
||||
new_loras:list[PseudoLoRAModel] = []
|
||||
|
||||
|
||||
@ -45,9 +45,7 @@ class Check:
|
||||
return isinstance(item, REPattern)
|
||||
|
||||
@staticmethod
|
||||
def is_json_data(item:Any|None, full:bool = False) -> bool:
|
||||
if Check.is_dictionary(item) or Check.is_array(item):
|
||||
return True
|
||||
def is_json_string(item:Any|None, full:bool = False) -> bool:
|
||||
if Check.is_string(item) and len(item = item.strip()) >= 2 and item[0] + item[-1] in ("{}", "[]"):
|
||||
if not full:
|
||||
return True
|
||||
@ -57,3 +55,15 @@ class Check:
|
||||
except Exception as _:
|
||||
pass
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def is_json(item:Any|None) -> bool:
|
||||
return Check.is_dictionary(item) or Check.is_array(item)
|
||||
|
||||
@staticmethod
|
||||
def is_json_data(item:Any|None, full:bool = False) -> bool:
|
||||
if Check.is_json(item):
|
||||
return True
|
||||
if Check.is_string(item):
|
||||
return Check.is_json_string(item, full)
|
||||
return False
|
||||
@ -286,7 +286,7 @@ class Common:
|
||||
try:
|
||||
return json_encode(data)
|
||||
except Exception as exception:
|
||||
pass
|
||||
print(exception)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
@ -322,10 +322,15 @@ class Common:
|
||||
|
||||
@classmethod
|
||||
def data_encode(cls:type[Self], data:Any|None) -> str|None:
|
||||
if Check.is_json_data(data):
|
||||
data = cls.json_encode(data)
|
||||
elif not Check.is_string(data):
|
||||
data = str(data)
|
||||
if data is None:
|
||||
return None
|
||||
if not Check.is_json_string(data, True):
|
||||
if Check.is_json(data):
|
||||
data = cls.json_encode(data)
|
||||
elif not Check.is_string(data):
|
||||
data = str(data)
|
||||
if data is None:
|
||||
return None
|
||||
return cls.base64_encode(data.encode("utf-8"))
|
||||
|
||||
@classmethod
|
||||
|
||||
Loading…
Reference in New Issue
Block a user