#wip: PseudoLoRAs building...
This commit is contained in:
parent
b4a1d09e3d
commit
36413778e7
@ -1,4 +1,17 @@
|
||||
[
|
||||
["Qué es AnP", "/MD/PseudoLoRAs/AnP.md", [], false],
|
||||
["Gestión de configuración", "/MD/AnP.Settings.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]
|
||||
]
|
||||
@ -41,7 +41,22 @@
|
||||
"AnP_TitlesManager_end" : null,
|
||||
|
||||
"AnP_AIModel_start" : null,
|
||||
"AnP_AIModel_end" : null
|
||||
"AnP_AIModel_end" : null,
|
||||
|
||||
"AnP_AIController_start" : null,
|
||||
"ai_controller_loras_system" : [
|
||||
"Actúa como un clasificador estricto. Se te proporcionará una lista de títulos y un Prompt.\n",
|
||||
"Debes evaluar cada título uno por uno en base al Prompt del usuario.\n",
|
||||
"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",
|
||||
"Lista de títulos a evaluar: \n{list}"
|
||||
],
|
||||
"ai_controller_response_system" : "Usa las siguientes guías para responder y dar soporte.{loras}",
|
||||
"AnP_AIController_end" : null
|
||||
|
||||
}
|
||||
}
|
||||
@ -95,7 +95,6 @@ export const WebSocketsClientsAbstract = (function(){
|
||||
switch(data.controller + "." + data.action){
|
||||
case "web_socket_client.set_id":
|
||||
self.id = data.data;
|
||||
console.log(self.id);
|
||||
break;
|
||||
default:
|
||||
anp.controllers.execute(data.controller, data.action, data, data.code);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
import {
|
||||
Fieldset, Section, Form, Div, Nav, UL, LI, Span, Pre
|
||||
Fieldset, Section, Form, Div, Nav, UL, LI, Span, Pre, Article
|
||||
} from "../Utils/HTMLDSL.ecma.js";
|
||||
import {MarkDown} from "../Utils/MarkDown.ecma.js";
|
||||
import {Common} from "../Utils/Common.ecma.js";
|
||||
@ -46,7 +46,13 @@ export const AIChatComponent = (function(){
|
||||
|
||||
return Fieldset({class : "aichat"}, [
|
||||
anp.components.i18n(name, "legend"),
|
||||
Section({class : "messages"}),
|
||||
Section({class : "conversations"}, [
|
||||
Article({
|
||||
class : "messages",
|
||||
data_conversation : anp.unique_keys.get(),
|
||||
data_selected : true
|
||||
})
|
||||
]),
|
||||
Form({
|
||||
method : "post",
|
||||
action : "#",
|
||||
@ -144,7 +150,8 @@ export const AIChatComponent = (function(){
|
||||
const send = (item, event) => {
|
||||
|
||||
const text_box = item.querySelector("[name=message]"),
|
||||
text = text_box.value.trim();
|
||||
text = text_box.value.trim(),
|
||||
conversation = document.querySelector(".aichat [data-conversation][data-selected=true]").getAttribute("data-conversation");
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
@ -153,7 +160,7 @@ export const AIChatComponent = (function(){
|
||||
const data_id = anp.unique_keys.get();
|
||||
|
||||
Common.HTML(
|
||||
".aichat .messages",
|
||||
".aichat [data-conversation=" + conversation + "]",
|
||||
build_message(data_id, "user", text, "done"),
|
||||
build_message(data_id, "bot")
|
||||
);
|
||||
@ -161,7 +168,8 @@ export const AIChatComponent = (function(){
|
||||
|
||||
anp.web_sockets_clients.send("anp", "ai", "message", {
|
||||
message_id : data_id,
|
||||
message : text
|
||||
message : text,
|
||||
conversation : conversation
|
||||
});
|
||||
|
||||
};
|
||||
@ -174,7 +182,7 @@ export const AIChatComponent = (function(){
|
||||
};
|
||||
|
||||
this.write_response = (id, fragment, ok, done) => {
|
||||
console.log([id, fragment]);
|
||||
// console.log([id, fragment]);
|
||||
|
||||
const box = document.querySelector(".aichat .messages>[data-type=bot][data-id='" + id + "']"),
|
||||
status = (
|
||||
|
||||
@ -161,7 +161,7 @@ export const WebSocketsClientsDriver = (function(){
|
||||
controller : controller,
|
||||
action : action,
|
||||
data : data,
|
||||
id : self.id
|
||||
id : _super.id
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
import {Check} from "../Utils/Check.ecma.js";
|
||||
import {Check} from "../Utils/Checks.ecma.js";
|
||||
import {Common} from "../Utils/Common.ecma.js";
|
||||
|
||||
/**
|
||||
|
||||
@ -213,6 +213,17 @@ export const UniqueKeysManager = (function(){
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!(string|Array.<string>)} new_keys
|
||||
* @returns {void}
|
||||
* @access public
|
||||
*/
|
||||
this.set = new_keys => {
|
||||
Common.get_keys(new_keys).forEach(key => {
|
||||
keys.includes(key) || keys.push(key);
|
||||
});
|
||||
};
|
||||
|
||||
constructor();
|
||||
|
||||
};
|
||||
|
||||
@ -32,6 +32,7 @@ class AIInterpretersAbstract(ABC):
|
||||
self.sessions_i:int = 0
|
||||
self.think:bool = self.anp.settings.get(("ai_interpreter_think", "ai_think", "think"), inputs, False)
|
||||
self.allow_contexts:bool = self.anp.settings.get(("ai_interpreter_allow_contexts", "ai_allow_contexts", "allow_contexts"), inputs, True)
|
||||
self.temperature:float = self.anp.settings.get(("ai_interpreter_temperature", "ai_temperature", "temperature"), inputs, 0.7)
|
||||
|
||||
def start(self:Self) -> None:
|
||||
pass
|
||||
@ -39,18 +40,26 @@ class AIInterpretersAbstract(ABC):
|
||||
def close(self:Self) -> None:
|
||||
self.sessions = {}
|
||||
|
||||
def get_session(self:Self, id:int|None = None) -> tuple[int, list[int]]:
|
||||
def get_session(self:Self, id:int|None = None, conversation:str|None = None) -> tuple[int, list[int]]:
|
||||
|
||||
if id is None or id not in self.sessions:
|
||||
id = self.sessions_i
|
||||
self.sessions_i += 1
|
||||
self.sessions[id] = []
|
||||
self.sessions[id] = {}
|
||||
|
||||
return id, self.sessions[id]
|
||||
return id, self.sessions[id][conversation] if conversation in self.sessions[id] else []
|
||||
|
||||
def save_context(self:Self, id:int, context:list[int]) -> None:
|
||||
def save_context(self:Self, id:int, conversation:str, context:list[int]) -> None:
|
||||
if self.allow_contexts and id in self.sessions:
|
||||
self.sessions[id] = context
|
||||
if conversation not in self.sessions[id]:
|
||||
self.sessions[id][conversation] = context
|
||||
self.sessions[id][conversation] = context
|
||||
|
||||
def close_conversation(self:Self, id:int, conversation:str) -> bool:
|
||||
if id in self.sessions and conversation in self.sessions[id]:
|
||||
del self.sessions[id][conversation]
|
||||
return True
|
||||
return False
|
||||
|
||||
def close_session(self:Self, id:int) -> bool:
|
||||
if id in self.sessions:
|
||||
@ -62,29 +71,34 @@ class AIInterpretersAbstract(ABC):
|
||||
return self.sessions[id] if id in self.sessions else []
|
||||
|
||||
def get_orders(self:Self, orders:Optional[str|list[str]] = None) -> str:
|
||||
return (
|
||||
orders if Check.is_string(orders) else
|
||||
"\n".join(orders) if Check.is_array(orders) else
|
||||
"")
|
||||
|
||||
results:str = ""
|
||||
i:int = 0
|
||||
# results:str = ""
|
||||
# i:int = 0
|
||||
|
||||
for block in (self.orders, orders):
|
||||
if block:
|
||||
if Check.is_array(block):
|
||||
# for block in (self.orders, orders):
|
||||
# if block:
|
||||
# if Check.is_array(block):
|
||||
|
||||
block_string:str = "".join(str(i + 1 + j) + ". " + str(order) + "\n" for j, order in enumerate(block))
|
||||
# block_string:str = "".join(str(i + 1 + j) + ". " + str(order) + "\n" for j, order in enumerate(block))
|
||||
|
||||
i += len(block)
|
||||
results += ("\n\n" if results else "") + block_string.strip()
|
||||
# i += len(block)
|
||||
# results += ("\n\n" if results else "") + block_string.strip()
|
||||
|
||||
else:
|
||||
results += ("\n\n" if results else "") + str(block).strip()
|
||||
# else:
|
||||
# results += ("\n\n" if results else "") + str(block).strip()
|
||||
|
||||
return results
|
||||
# return results
|
||||
|
||||
@abstractmethod
|
||||
def request(self:Self,
|
||||
session:int|None,
|
||||
conversation:str|None,
|
||||
message:str,
|
||||
orders:list[str] = [],
|
||||
orders:str|list[str] = [],
|
||||
callback:Optional[Callable[[int, AIResponseModel], None]] = None,
|
||||
context:list[int] = []
|
||||
custom_context:list[int] = []
|
||||
) -> tuple[int|None, AIResponseModel]:pass
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any, Self, Optional, Sequence
|
||||
from re import Match as REMath
|
||||
from Interfaces.Application.AnPInterface import AnPInterface
|
||||
from Utils.Common import Common
|
||||
|
||||
@ -20,6 +21,7 @@ class HTTPServersAbstract(ABC):
|
||||
"port": self.port,
|
||||
"host": self.host
|
||||
}
|
||||
self._session_timeout:int = anp.settings.get(("sessions_timeout", "timeout"), inputs, 3600)
|
||||
self.key:str = key
|
||||
|
||||
self.update()
|
||||
@ -51,3 +53,41 @@ class HTTPServersAbstract(ABC):
|
||||
self.__update_print_data()
|
||||
|
||||
self.update()
|
||||
|
||||
def load_cookies(self:Self, cookies:str|None) -> dict[str, Any|None]:
|
||||
if not cookies:
|
||||
return {}
|
||||
|
||||
cookie:str
|
||||
results:dict[str, Any|None] = {}
|
||||
|
||||
for cookie in cookies.split(";"):
|
||||
if "=" in cookie:
|
||||
|
||||
key:str
|
||||
value:str
|
||||
|
||||
key, value = cookie.split("=", 1)
|
||||
results[key.strip()] = value.strip()
|
||||
|
||||
return results
|
||||
|
||||
@staticmethod
|
||||
def get_variables_from(source:str|None) -> dict[str, Any|None]:
|
||||
if not source:
|
||||
return {}
|
||||
|
||||
json:dict[str, Any|None] = Common.data_decode(source)
|
||||
|
||||
if json is not None:
|
||||
return Common.get_dictionary(json)
|
||||
|
||||
json = {}
|
||||
|
||||
def callback(matches:REMath) -> str:
|
||||
json[matches.group(1)] = matches.group(2)
|
||||
return matches.group(0)
|
||||
|
||||
Common.replace(self.HTTP_VARIABLE, source, callback)
|
||||
|
||||
return json
|
||||
@ -14,6 +14,7 @@ class WebSocketServersAbstract(ABC):
|
||||
self.key:str = key
|
||||
self.host:str = self.anp.settings.get(("web_socket_server_host", "host"), inputs, "")
|
||||
self.port:int = self.anp.settings.get(("web_socket_server_port", "port"), inputs, 18765)
|
||||
self.__sessions:dict[str, str] = {}
|
||||
self.on_new_client:Event = Event()
|
||||
self.on_message:Event = Event()
|
||||
self.on_close:Event = Event()
|
||||
@ -40,3 +41,14 @@ class WebSocketServersAbstract(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def send(self:Self, controller:str, action:str, data:Any|None, ids:Optional[str|Sequence[str]] = None, code:int = 200) -> None:pass
|
||||
|
||||
def set_session(self:Self, id:str, session:str) -> None:
|
||||
if id not in self.__sessions:
|
||||
self.__sessions[id] = session
|
||||
|
||||
def get_session(self:Self, id:str) -> str|None:
|
||||
return self.__sessions.get(id)
|
||||
|
||||
def remove_session(self:Self, id:str) -> None:
|
||||
if id in self.__sessions:
|
||||
del self.__sessions[id]
|
||||
@ -5,6 +5,7 @@ from typing import Self, Any, Optional, Sequence
|
||||
import datetime
|
||||
from re import Match as REMatch
|
||||
from traceback import extract_tb as extract_traceback, format_stack as trace_format_stack
|
||||
from time import time as timestamp, sleep
|
||||
from Managers.I18NManager import I18NManager
|
||||
from Managers.SettingsManager import SettingsManager
|
||||
from Managers.PrintTypesManager import PrintTypesManager
|
||||
@ -171,3 +172,10 @@ class AnP:
|
||||
data["end"] = Common.string_variables(self.__exception_format, data)
|
||||
|
||||
message and self.print("exception", message, data, i + 2)
|
||||
|
||||
def wait(self:Self, time:str|float) -> None:
|
||||
|
||||
date:float = timestamp()
|
||||
|
||||
while self.__working and timestamp() - date < float(time):
|
||||
sleep(.1)
|
||||
@ -9,54 +9,128 @@ from Models.PseudoLoRAModel import PseudoLoRAModel
|
||||
|
||||
class AIController(ControllerAbstract, ModelAbstract):
|
||||
|
||||
def __test_execution(self:Self, end:Callable[[], None], request:RequestModel) -> None:
|
||||
self.anp.ai_interpreters.request(
|
||||
"anp_responses",
|
||||
None,
|
||||
request.get("message", "Hola, Gemma. ¿Me puedes ayudar a instalar una impresora Canon?"),
|
||||
# lambda id, response: print((id, response.response, request.get("client_id"))),
|
||||
lambda id, response: self.anp.web_socket_servers.send("anp", "ai", "test", {
|
||||
"id" : id,
|
||||
"response" : response.response
|
||||
}, request.get("client_id")),
|
||||
# [
|
||||
# "# Títulos\n" + "".join(
|
||||
# "\n - " + title for title in [
|
||||
# "Información, gestión e instalación de Cividas",
|
||||
# "Información, gestión e instalación de Impresoras/Fotocopiadoras/Multifuncionales Canon"
|
||||
# ]
|
||||
# ),
|
||||
# ]
|
||||
)
|
||||
end()
|
||||
# def __message_execution(self:Self, end:Callable[[], None], request:RequestModel) -> None:
|
||||
|
||||
def test(self:Self, request:RequestModel) -> None:
|
||||
self.anp.queues.add("anp", self.__test_execution, request)
|
||||
request.set_response({
|
||||
"ok" : True,
|
||||
"code" : 200,
|
||||
"message" : "ok"
|
||||
})
|
||||
# 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]]:
|
||||
|
||||
session:str|None = request.session.get("anp_loras_session")
|
||||
results:list[tuple[str, str]] = []
|
||||
|
||||
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_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)
|
||||
|
||||
return results
|
||||
|
||||
def __message_execution(self:Self, end:Callable[[], None], request:RequestModel) -> None:
|
||||
|
||||
session:str|None = 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")
|
||||
conversation:str = request.get("conversation")
|
||||
message:str = request.get("message")
|
||||
loras:list[tuple[str, str]]
|
||||
loras_data:dict[str, Any] = {
|
||||
"conversation" : conversation,
|
||||
"message" : message,
|
||||
"i" : 0
|
||||
}
|
||||
|
||||
session, _ = self.anp.ai_interpreters.request(
|
||||
"anp_responses",
|
||||
session,
|
||||
request.get("message"),
|
||||
lambda id, response: self.anp.web_socket_servers.send("anp", "ai", "message", {
|
||||
"id" : id,
|
||||
"response" : response.response,
|
||||
"ok" : response.ok,
|
||||
"done" : response.done,
|
||||
"data_id" : request.get("message_id")
|
||||
}, request.get("client_id"))
|
||||
)
|
||||
loras = self.anp.pseudoloras.get(lambda loras:self.__analyse_loras(loras_data, request, loras))
|
||||
|
||||
print([title for title, _ in loras])
|
||||
|
||||
# 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)
|
||||
|
||||
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({
|
||||
|
||||
@ -7,6 +7,7 @@ from Abstracts.ModelAbstract import ModelAbstract
|
||||
from Models.RequestModel import RequestModel
|
||||
from threading import Thread
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
from http.cookies import SimpleCookie
|
||||
from Abstracts.HTTPServersAbstract import HTTPServersAbstract
|
||||
|
||||
class HTTPDriver(HTTPServersAbstract, ModelAbstract):
|
||||
@ -16,19 +17,50 @@ class HTTPDriver(HTTPServersAbstract, ModelAbstract):
|
||||
def __process(self:Self, method:str) -> None:
|
||||
|
||||
anp:AnPInterface = self.server.anp
|
||||
server:HTTPServersAbstract = self.server.itself
|
||||
request:RequestModel = RequestModel()
|
||||
session_id:str|None = None
|
||||
cookies:SimpleCookie|None = None
|
||||
|
||||
request.method = method
|
||||
request.path = self.path
|
||||
request.path = self.path.split("?")[0]
|
||||
request.headers = dict(self.headers)
|
||||
request.client_host = self.client_address[0]
|
||||
request.client_port = self.client_address[1]
|
||||
|
||||
request.get_variables = server.get_variables_from(self.path[self.path.find("?") + 1:] if "?" in self.path else None)
|
||||
request.post_variables = server.get_variables_from(self.rfile.read(int(self.headers.get("Content-Length", 0))))
|
||||
request.cookies = server.load_cookies(self.headers.get("Cookie"))
|
||||
|
||||
session_id = request.get("session")
|
||||
request.session = anp.sessions._get_instance(session_id)
|
||||
|
||||
if session_id is None or request.session is None:
|
||||
|
||||
cookies = SimpleCookie()
|
||||
|
||||
session_id = anp.sessions.create()
|
||||
cookies["session"] = session_id
|
||||
cookies["session"]["path"] = "/"
|
||||
cookies["session"]["max-age"] = server._session_timeout
|
||||
# cookies["session"]["HttpOnly"] = True
|
||||
# cookies["session"]["Secure"] = True
|
||||
|
||||
request.session = anp.sessions._get_instance(session_id)
|
||||
|
||||
anp.routes.go([self.server.key], method, self.path, request)
|
||||
|
||||
self.send_response(request.response_code)
|
||||
self.send_header("Content-Type", request.response_mime)
|
||||
self.send_header("Content-Length", str(len(request.response)))
|
||||
|
||||
if cookies is not None:
|
||||
|
||||
morsel:str
|
||||
|
||||
for morsel in cookies.values():
|
||||
self.send_header("Set-Cookie", morsel.OutputString())
|
||||
|
||||
self.end_headers()
|
||||
|
||||
self.wfile.write(
|
||||
@ -113,5 +145,6 @@ class HTTPDriver(HTTPServersAbstract, ModelAbstract):
|
||||
def __run_service(self:Self) -> None:
|
||||
self.__server = HTTPServer((self.host, self.port), self.HTTPRequestHandler)
|
||||
self.__server.anp = self.anp
|
||||
self.__server.itself = self
|
||||
self.__server.key = self.key
|
||||
self.__server.serve_forever()
|
||||
@ -22,24 +22,24 @@ class OllamaDriver(AIInterpretersAbstract, ModelAbstract):
|
||||
|
||||
def request(self:Self,
|
||||
session:int|None,
|
||||
conversation:str|None,
|
||||
message:str,
|
||||
callback:Optional[Callable[[int, AIResponseModel], None]] = None,
|
||||
orders:str|list[str] = [],
|
||||
custom_context:Optional[list[int]] = None
|
||||
callback:Optional[Callable[[int, AIResponseModel], None]] = None,
|
||||
custom_context:Optional[list[int]] = None,
|
||||
save_session:bool = True
|
||||
) -> tuple[int|None, AIResponseModel]:
|
||||
|
||||
response:Response
|
||||
context:list[int]
|
||||
options:dict[str, Any] = {}
|
||||
results:AIResponseModel = AIResponseModel()
|
||||
options:dict[str, Any] = {key : value for key, value in {
|
||||
"num_predict" : self.maximum_response_tokens,
|
||||
"num_ctx" : self.maximum_tokens_per_session,
|
||||
"temperature" : self.temperature
|
||||
}.items() if value is not None}
|
||||
results:AIResponseModel = AIResponseModel(conversation)
|
||||
|
||||
if self.maximum_response_tokens is not None:
|
||||
options["num_predict"] = self.maximum_response_tokens
|
||||
|
||||
if self.maximum_tokens_per_session is not None:
|
||||
options["num_ctx"] = self.maximum_tokens_per_session
|
||||
|
||||
session, context = custom_context or self.get_session(session)
|
||||
session, context = custom_context or self.get_session(session, conversation)
|
||||
orders = self.get_orders(orders)
|
||||
|
||||
if custom_context:
|
||||
@ -75,7 +75,7 @@ class OllamaDriver(AIInterpretersAbstract, ModelAbstract):
|
||||
if chunk:
|
||||
results.update(Common.json_decode(chunk))
|
||||
if results.done:
|
||||
self.save_context(session, results.context)
|
||||
save_session and self.save_context(session, conversation, results.context)
|
||||
break
|
||||
|
||||
Common.execute(callback, session, results)
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
from threading import Thread
|
||||
from typing import Any, Self, Sequence, Optional
|
||||
from http.cookies import SimpleCookie
|
||||
from Abstracts.WebSocketServersAbstract import WebSocketServersAbstract
|
||||
from Abstracts.ModelAbstract import ModelAbstract
|
||||
from websockets.sync.server import serve as server_serve
|
||||
@ -60,10 +61,14 @@ class WebSocketServerDriver(WebSocketServersAbstract, ModelAbstract):
|
||||
def __handler(self:Self, client:WebSocketClient) -> None:
|
||||
|
||||
id:str = self.anp.unique_keys.get()
|
||||
cookies:SimpleCookie = SimpleCookie()
|
||||
|
||||
self.__clients[id] = client
|
||||
self.on_new_client.execute(id)
|
||||
|
||||
cookies.load(client.request.headers.get("Cookie", ''))
|
||||
self.set_session(id, cookies.get("session").value)
|
||||
|
||||
self.anp.print("info", "web_socket_server_client_connected", {
|
||||
"id": id,
|
||||
"port": self.port,
|
||||
@ -92,6 +97,7 @@ class WebSocketServerDriver(WebSocketServersAbstract, ModelAbstract):
|
||||
self.__clients[id].close()
|
||||
except Exception as _:
|
||||
pass
|
||||
self.remove_session(id)
|
||||
del self.__clients[id]
|
||||
self.anp.unique_keys.remove(id)
|
||||
self.on_close.execute(id)
|
||||
@ -106,6 +112,8 @@ class WebSocketServerDriver(WebSocketServersAbstract, ModelAbstract):
|
||||
success:bool = True
|
||||
id:str
|
||||
|
||||
# print([ids, list(self.__clients.keys())])
|
||||
|
||||
for id in (
|
||||
list(self.__clients.keys()) if ids is None else
|
||||
ids if Check.is_array(ids) else
|
||||
@ -113,6 +121,7 @@ class WebSocketServerDriver(WebSocketServersAbstract, ModelAbstract):
|
||||
if id in self.__clients:
|
||||
try:
|
||||
self.__clients[id].send(self.format_data(controller, action, data, id, code))
|
||||
# print(["WS", controller, action, data, ids, code, list(self.__clients.keys())])
|
||||
except Exception as exception:
|
||||
self.anp.exception(exception, "web_socket_server_client_send_exception", {
|
||||
"id": id,
|
||||
|
||||
@ -67,3 +67,6 @@ class AnPInterface(ABC):
|
||||
inputs:Optional[dict[str, Any|None]|Sequence[Any|None]] = None,
|
||||
i:int = 0
|
||||
) -> None:pass
|
||||
|
||||
@abstractmethod
|
||||
def wait(self:Self, time:str|float) -> None:pass
|
||||
@ -27,8 +27,9 @@ class AIInterpretersManagerInterface(ABC):
|
||||
key:str,
|
||||
session:int|None,
|
||||
message:str,
|
||||
callback:Callable[[int, AIResponseModel], None],
|
||||
orders:list[str] = []
|
||||
orders:list[str] = [],
|
||||
callback:Optional[Callable[[int, AIResponseModel], None]] = None,
|
||||
custom_context:list[int] = []
|
||||
) -> int|None:pass
|
||||
|
||||
@abstractmethod
|
||||
|
||||
@ -3,8 +3,9 @@
|
||||
|
||||
from typing import Self, Optional, Any
|
||||
from abc import ABC, abstractmethod
|
||||
from Models.SessionModel import SessionModel
|
||||
|
||||
class SessionsManagerInterfaces(ABC):
|
||||
class SessionsManagerInterface(ABC):
|
||||
|
||||
@abstractmethod
|
||||
def update(self:Self) -> None:pass
|
||||
@ -12,6 +13,12 @@ class SessionsManagerInterfaces(ABC):
|
||||
@abstractmethod
|
||||
def reset(self:Self) -> None:pass
|
||||
|
||||
@abstractmethod
|
||||
def create(self:Self) -> SessionModel:pass
|
||||
|
||||
@abstractmethod
|
||||
def _get_instance(self:Self, id:str) -> SessionModel|None:pass
|
||||
|
||||
@abstractmethod
|
||||
def get(self:Self, id:str, key:str, default:Optional[Any] = None) -> Any|None:pass
|
||||
|
||||
|
||||
@ -75,13 +75,14 @@ class AIInterpretersManager:
|
||||
key:str,
|
||||
session:int|None,
|
||||
message:str,
|
||||
callback:Callable[[int, AIResponseModel], None],
|
||||
orders:list[str] = []
|
||||
orders:str|list[str] = [],
|
||||
callback:Optional[Callable[[int, AIResponseModel], None]] = None,
|
||||
custom_context:list[int] = []
|
||||
) -> tuple[int|None, AIResponseModel|None]:
|
||||
|
||||
response:AIResponseModel|None = None
|
||||
|
||||
if key in self.__interpreters:
|
||||
session, response = self.__interpreters[key].request(session, message, callback, orders)
|
||||
session, response = self.__interpreters[key].request(session, message, orders, callback, custom_context)
|
||||
|
||||
return session, response
|
||||
@ -15,6 +15,7 @@ class PseudoLoRAsManager:
|
||||
self.__maximum_cache:int = (1 << 20) * 100
|
||||
self.__memory_cached:int = 0
|
||||
self.__cache:dict[int, PseudoLoRAModel] = {}
|
||||
self.__cache_i:int = 0
|
||||
self.__loras:list[PseudoLoRAModel] = []
|
||||
|
||||
self.update()
|
||||
@ -89,58 +90,62 @@ class PseudoLoRAsManager:
|
||||
for lora in self.__loras:
|
||||
lora.clean_cache()
|
||||
|
||||
def get(self:Self, callback:Callable[[list[PseudoLoRAModel]], bool], keys:list[str] = []) -> list[tuple[str, str]]:
|
||||
def get(self:Self,
|
||||
callback:Callable[[list[PseudoLoRAModel]], bool],
|
||||
loras:Optional[list[PseudoLoRAModel]] = None
|
||||
) -> list[tuple[str, str]]:
|
||||
|
||||
next:list[PseudoLoRAModel] = []
|
||||
results:list[tuple[str, str]] = []
|
||||
i:int
|
||||
ok:bool
|
||||
has_keys:bool = len(keys) > 0
|
||||
|
||||
for i, ok in enumerate(callback(
|
||||
lora.title for lora in self.__loras if not has_keys or any(
|
||||
key in lora.keys for key in keys
|
||||
)
|
||||
)):
|
||||
if loras is None:
|
||||
loras = self.__loras.copy()
|
||||
|
||||
loras_is:list[bool] = [(i, callback([lora.title])) for i, lora in enumerate(loras)]
|
||||
|
||||
new_loras:list[PseudoLoRAModel] = []
|
||||
|
||||
for i, ok in enumerate(loras_is):
|
||||
if not ok:
|
||||
continue
|
||||
|
||||
lora:PseudoLoRAModel = self.__loras[i]
|
||||
lora:PseudoLoRAModel = loras[i]
|
||||
|
||||
if lora.path is not None:
|
||||
results.append((lora.title, Common.load_file(lora.path, "r")))
|
||||
|
||||
data:str|None
|
||||
# data:str|None
|
||||
|
||||
if lora.cacheable:
|
||||
if not lora.cache:
|
||||
# if lora.cacheable:
|
||||
# if not lora.cache:
|
||||
|
||||
lora.cache = Common.load_file(lora.path, "r")
|
||||
lora.memory = len(lora.cache)
|
||||
self.__memory_cached += lora.memory
|
||||
# lora.cache = Common.load_file(lora.path, "r")
|
||||
# lora.memory = len(lora.cache)
|
||||
# self.__memory_cached += lora.memory
|
||||
|
||||
if self.__cache[lora.i]:
|
||||
del self.__cache[lora.i]
|
||||
lora.i += 1
|
||||
if lora.i in self.__cache:
|
||||
self.__cache[lora.i].append(lora)
|
||||
else:
|
||||
self.__cache[lora.i] = [lora]
|
||||
# if self.__cache[lora.i]:
|
||||
# del self.__cache[lora.i]
|
||||
|
||||
if self.__memory_cached > self.__maximum_cache:
|
||||
# lora.i = self.__cache_i
|
||||
# self.__cache_i += 1
|
||||
# self.__cache[lora.i] = lora
|
||||
|
||||
i:int = min(self.__cache.keys())
|
||||
# if self.__memory_cached > self.__maximum_cache:
|
||||
|
||||
for lora in self.__cache[i]:
|
||||
lora.clean_cache()
|
||||
del self.__cache[i]
|
||||
# i:int = min(self.__cache.keys())
|
||||
|
||||
if (data := lora.cache or Common.load_file(lora.path, "r")):
|
||||
results.append((lora.title, lora.path))
|
||||
# for lora in self.__cache[i]:
|
||||
# lora.clean_cache()
|
||||
# del self.__cache[i]
|
||||
|
||||
# if (data := lora.cache or Common.load_file(lora.path, "r")):
|
||||
# results.append((lora.title, lora.path))
|
||||
|
||||
else:
|
||||
next.extend(lora.nested)
|
||||
new_loras.extend(lora.nested)
|
||||
|
||||
if len(next):
|
||||
results.extend(callback(next))
|
||||
if len(new_loras):
|
||||
results.extend(self.get(callback, new_loras))
|
||||
|
||||
return results
|
||||
@ -35,6 +35,9 @@ class RoutesManager:
|
||||
|
||||
route:RouteModel
|
||||
|
||||
if request.session is None:
|
||||
request.session = self.anp.sessions._get_instance(request.get("session")) or None
|
||||
|
||||
for route in self.__routes:
|
||||
if route.match(key, method, path, request):
|
||||
if not request.response:
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
from typing import Self, Optional, Any
|
||||
from threading import Thread
|
||||
from time import sleep, time as timestamp
|
||||
from time import time as timestamp
|
||||
from Interfaces.Application.AnPInterface import AnPInterface
|
||||
from Models.SessionModel import SessionModel
|
||||
|
||||
@ -39,21 +39,36 @@ class SessionsManager:
|
||||
if time - session.get("date_last", time) > self.__timeout:
|
||||
self.remove(id)
|
||||
|
||||
sleep(self.__clean_waiter)
|
||||
self.anp.wait(self.__clean_waiter)
|
||||
|
||||
def create(self:Self) -> SessionModel:
|
||||
|
||||
id:str = self.anp.unique_keys.get()
|
||||
|
||||
self.__sessions[id] = SessionModel(id)
|
||||
|
||||
return id
|
||||
|
||||
def _get_instance(self:Self, id:str) -> SessionModel|None:
|
||||
|
||||
if id in self.__sessions and not self.__sessions[id].removed:
|
||||
return self.__sessions[id]
|
||||
return None
|
||||
|
||||
def get(self:Self, id:str, key:str, default:Optional[Any] = None) -> Any|None:
|
||||
if id in self.__sessions:
|
||||
if id in self.__sessions and not self.__sessions[id].removed:
|
||||
return self.__sessions[id].get(key, default)
|
||||
return default
|
||||
|
||||
def set(self:Self, id:str, key:str, value:Any|None) -> bool:
|
||||
if id in self.__sessions:
|
||||
if id in self.__sessions and not self.__sessions[id].removed:
|
||||
self.__sessions[id].set(key, value)
|
||||
return True
|
||||
return False
|
||||
|
||||
def remove(self:Self, id:str) -> bool:
|
||||
if id in self.__sessions:
|
||||
self.__sessions[id].remove()
|
||||
del self.__sessions[id]
|
||||
return True
|
||||
return False
|
||||
@ -105,7 +105,7 @@ class WebSocketServersManager:
|
||||
except Exception as exception:
|
||||
self.anp.exception(exception, "web_socket_server_send_exception", {"name": name})
|
||||
|
||||
def __receive(self:Self, web_socket:WebSocketServersAbstract, client:int, raw_data:str, name:str) -> None:
|
||||
def __receive(self:Self, web_socket:WebSocketServersAbstract, client:str, raw_data:str, name:str) -> None:
|
||||
|
||||
data:dict[str, Any|None] = Common.data_decode(raw_data)
|
||||
|
||||
@ -119,6 +119,7 @@ class WebSocketServersManager:
|
||||
request.variables["web_socket"] = web_socket
|
||||
request.variables["client_id"] = client
|
||||
request.variables["web_socket_name"] = name
|
||||
request.session = self.anp.sessions._get_instance(web_socket.get_session(client))
|
||||
|
||||
self.anp.controllers.execute(
|
||||
data["controller"],
|
||||
|
||||
@ -6,7 +6,8 @@ from time import time as timestamp
|
||||
|
||||
class AIResponseModel:
|
||||
|
||||
def __init__(self:Self) -> None:
|
||||
def __init__(self:Self, conversation:str) -> None:
|
||||
self.conversation:str = conversation
|
||||
self.start:float = timestamp()
|
||||
self.model:str = ""
|
||||
self.response:str = ""
|
||||
|
||||
@ -9,10 +9,11 @@ from Utils.Common import Common
|
||||
|
||||
class RequestModel:
|
||||
|
||||
def __init__(self:Self) -> None:
|
||||
def __init__(self:Self, session:Optional[SessionModel] = None) -> None:
|
||||
self.post_variables:dict[str, Any|None] = {}
|
||||
self.get_variables:dict[str, Any|None] = {}
|
||||
self.url_variables:dict[str, Any|None] = {}
|
||||
self.cookies:dict[str, Any|None] = {}
|
||||
self.variables:dict[str, Any|None] = {}
|
||||
self.request_headers:dict[str, Any|None] = {}
|
||||
self.method:str|None = None
|
||||
@ -23,15 +24,22 @@ class RequestModel:
|
||||
self.response_headers:dict[str, Any|None] = {}
|
||||
self.callback:Callable[[RequestModel, str|bytes|None], None]|None = None
|
||||
self.data:Any|None = None
|
||||
self.session:SessionModel|None = None
|
||||
self.session:SessionModel|None = session
|
||||
|
||||
def get(self:Self, key:str|Sequence[str], default:Optional[Any] = None) -> Any|None:
|
||||
return self.session.get(key, Common.get_value(key, (
|
||||
self.url_variables, self.get_variables, self.post_variables, self.variables
|
||||
), default))
|
||||
if self.session is not None:
|
||||
|
||||
results:Any|None = self.session.get(key)
|
||||
|
||||
if results is not None:
|
||||
return results
|
||||
return Common.get_value(key, (
|
||||
self.cookies, self.url_variables, self.get_variables, self.post_variables, self.variables
|
||||
), default)
|
||||
|
||||
def set_variables(self:Self, inputs:dict[str, Any|None], on:Optional[str] = None) -> None:
|
||||
(
|
||||
self.cookies if on == "cookies" else
|
||||
self.url_variables if on == "url" else
|
||||
self.get_variables if on == "get" else
|
||||
self.post_variables if on == "post" else
|
||||
|
||||
@ -11,6 +11,7 @@ class SessionModel:
|
||||
self.date_from:float = timestamp()
|
||||
self.date_last:float = timestamp()
|
||||
self.variables:dict[str, Any|None] = {}
|
||||
self.removed:bool = False
|
||||
|
||||
def set(self:Self, key:str, value:Any|None) -> None:
|
||||
self.date_last = timestamp()
|
||||
@ -19,3 +20,6 @@ class SessionModel:
|
||||
def get(self:Self, key:str, default:Any|None = None) -> Any|None:
|
||||
self.date_last = timestamp()
|
||||
return self.variables.get(key, default)
|
||||
|
||||
def remove(self:Self) -> None:
|
||||
self.removed = True
|
||||
@ -14,3 +14,4 @@ class RE:
|
||||
ROUTE_KEY:REPattern = re_compile(r'\\\{([a-z_][a-z0-9_]*)\\\}', RE_IGNORECASE)
|
||||
EXCEPTION:REPattern = re_compile(r'^\s*File "([^"]+)", line ([0-9]+), in ([^\n]+)(.*|[\r\n]*)*$')
|
||||
NEW_LINE:REPattern = re_compile(r'\r\n|[\r\n]')
|
||||
HTTP_VARIABLE:REPattern = re_compile(r'([^=&]+)=([^&]*)')
|
||||
Loading…
Reference in New Issue
Block a user