mirror of
https://github.com/ParisNeo/lollms.git
synced 2024-12-20 05:08:00 +00:00
skills library is now working
This commit is contained in:
parent
33297e81c7
commit
c6fcfa3686
@ -2,6 +2,7 @@ from lollms.main_config import LOLLMSConfig
|
|||||||
from lollms.paths import LollmsPaths
|
from lollms.paths import LollmsPaths
|
||||||
from lollms.personality import PersonalityBuilder, AIPersonality
|
from lollms.personality import PersonalityBuilder, AIPersonality
|
||||||
from lollms.binding import LLMBinding, BindingBuilder, ModelBuilder
|
from lollms.binding import LLMBinding, BindingBuilder, ModelBuilder
|
||||||
|
from lollms.databases.discussions_database import Message
|
||||||
from lollms.extension import LOLLMSExtension, ExtensionBuilder
|
from lollms.extension import LOLLMSExtension, ExtensionBuilder
|
||||||
from lollms.config import InstallOption
|
from lollms.config import InstallOption
|
||||||
from lollms.helpers import ASCIIColors, trace_exception
|
from lollms.helpers import ASCIIColors, trace_exception
|
||||||
@ -128,8 +129,72 @@ class LollmsApplication(LoLLMsCom):
|
|||||||
self.mount_personalities()
|
self.mount_personalities()
|
||||||
self.mount_extensions()
|
self.mount_extensions()
|
||||||
|
|
||||||
def add_discussion_tto_skills_library(self, client:Client):
|
def add_discussion_to_skills_library(self, client: Client):
|
||||||
pass
|
messages = client.discussion.get_messages()
|
||||||
|
db = client.discussion.skills_db
|
||||||
|
|
||||||
|
# Extract relevant information from messages
|
||||||
|
content = self._extract_content(messages)
|
||||||
|
|
||||||
|
# Generate title
|
||||||
|
title_prompt = f"Generate a concise title for the following content without any additional explanations or context:\n\n{content}\n\nTitle:"
|
||||||
|
title = self._generate_text(title_prompt)
|
||||||
|
|
||||||
|
# Determine category
|
||||||
|
category_prompt = f"Determine the most appropriate category for the following title and content, and provide only the category name:\n\nTitle: {title}\nContent: {content}\n\nCategory:"
|
||||||
|
category = self._generate_text(category_prompt)
|
||||||
|
|
||||||
|
# Add entry to skills library
|
||||||
|
db.add_entry(1, category, title, content)
|
||||||
|
return category, title, content
|
||||||
|
|
||||||
|
def _extract_content(self, messages:List[Message]):
|
||||||
|
ranked_messages = sorted(messages, key=lambda m: m.rank, reverse=True)
|
||||||
|
|
||||||
|
max_chunk_size = int(self.config.ctx_size * 0.75)
|
||||||
|
|
||||||
|
chunks = []
|
||||||
|
current_chunk = ""
|
||||||
|
current_chunk_tokens = 0
|
||||||
|
|
||||||
|
for message in ranked_messages:
|
||||||
|
rank = message.rank
|
||||||
|
sender = message.sender
|
||||||
|
text = message.content
|
||||||
|
message_content = f"Rank {rank} - {sender}: {text}\n"
|
||||||
|
|
||||||
|
message_tokens = self.model.get_nb_tokens(message_content)
|
||||||
|
|
||||||
|
if current_chunk_tokens + message_tokens <= max_chunk_size:
|
||||||
|
current_chunk += message_content
|
||||||
|
current_chunk_tokens += message_tokens
|
||||||
|
else:
|
||||||
|
chunks.append(current_chunk)
|
||||||
|
current_chunk = message_content
|
||||||
|
current_chunk_tokens = message_tokens
|
||||||
|
|
||||||
|
if current_chunk:
|
||||||
|
chunks.append(current_chunk)
|
||||||
|
|
||||||
|
summarized_chunks = []
|
||||||
|
for chunk in chunks:
|
||||||
|
prompt = f"Summarize the following discussion chunk, keeping only important information that can be used as skills. Use bullet points:\n\n{chunk}"
|
||||||
|
max_tokens = self.config.ctx_size - self.model.get_nb_tokens(prompt)
|
||||||
|
|
||||||
|
summarized_chunk = self.model.generate(prompt, max_tokens)
|
||||||
|
summarized_chunks.append(summarized_chunk.strip())
|
||||||
|
|
||||||
|
summarized_content = "\n".join(summarized_chunks)
|
||||||
|
return summarized_content
|
||||||
|
|
||||||
|
|
||||||
|
def _generate_text(self, prompt):
|
||||||
|
max_tokens = self.config.ctx_size - self.model.get_nb_tokens(prompt)
|
||||||
|
generated_text = self.model.generate(prompt, max_tokens)
|
||||||
|
return generated_text.strip()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_uploads_path(self, client_id):
|
def get_uploads_path(self, client_id):
|
||||||
return self.lollms_paths.personal_uploads_path
|
return self.lollms_paths.personal_uploads_path
|
||||||
|
@ -111,6 +111,11 @@ class LLMBinding:
|
|||||||
models_folder.mkdir(parents=True, exist_ok=True)
|
models_folder.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_nb_tokens(self, prompt):
|
||||||
|
"""
|
||||||
|
Counts the number of tokens in a prtompt
|
||||||
|
"""
|
||||||
|
return len(self.tokenize(prompt))
|
||||||
|
|
||||||
def searchModelFolder(self, model_name:str):
|
def searchModelFolder(self, model_name:str):
|
||||||
for mn in self.models_folders:
|
for mn in self.models_folders:
|
||||||
|
@ -4,6 +4,7 @@ from pathlib import Path
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from lollms.helpers import ASCIIColors
|
from lollms.helpers import ASCIIColors
|
||||||
from lollms.paths import LollmsPaths
|
from lollms.paths import LollmsPaths
|
||||||
|
from lollms.databases.skills_database import SkillsLibrary
|
||||||
import json
|
import json
|
||||||
|
|
||||||
__author__ = "parisneo"
|
__author__ = "parisneo"
|
||||||
@ -598,8 +599,8 @@ class Discussion:
|
|||||||
self.discussion_skills_folder.mkdir(exist_ok=True)
|
self.discussion_skills_folder.mkdir(exist_ok=True)
|
||||||
self.discussion_rag_folder.mkdir(exist_ok=True)
|
self.discussion_rag_folder.mkdir(exist_ok=True)
|
||||||
self.messages = self.get_messages()
|
self.messages = self.get_messages()
|
||||||
self.skills_db = self.discussion_skills_folder/"skills_db.db"
|
self.skills_db_path = self.discussion_skills_folder/"skills_db.db"
|
||||||
|
self.skills_db = SkillsLibrary(self.skills_db_path)
|
||||||
if len(self.messages)>0:
|
if len(self.messages)>0:
|
||||||
self.current_message = self.messages[-1]
|
self.current_message = self.messages[-1]
|
||||||
|
|
||||||
|
@ -1,19 +1,15 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
class SkillsLibrary:
|
class SkillsLibrary:
|
||||||
def __init__(self, db_path):
|
|
||||||
self.conn = sqlite3.connect(db_path)
|
|
||||||
self.cursor = self.conn.cursor()
|
|
||||||
self._create_table()
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, db_path):
|
def __init__(self, db_path):
|
||||||
self.conn = sqlite3.connect(db_path)
|
self.db_path =db_path
|
||||||
self.cursor = self.conn.cursor()
|
|
||||||
self._initialize_db()
|
self._initialize_db()
|
||||||
|
|
||||||
def _initialize_db(self):
|
def _initialize_db(self):
|
||||||
self.cursor.execute("""
|
conn = sqlite3.connect(self.db_path)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS skills_library (
|
CREATE TABLE IF NOT EXISTS skills_library (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
version INTEGER,
|
version INTEGER,
|
||||||
@ -22,29 +18,39 @@ class SkillsLibrary:
|
|||||||
content TEXT
|
content TEXT
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
self.cursor.execute("""
|
cursor.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS db_info (
|
CREATE TABLE IF NOT EXISTS db_info (
|
||||||
version INTEGER
|
version INTEGER
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
self.cursor.execute("SELECT version FROM db_info")
|
cursor.execute("SELECT version FROM db_info")
|
||||||
version = self.cursor.fetchone()
|
version = cursor.fetchone()
|
||||||
if version is None:
|
if version is None:
|
||||||
self.cursor.execute("INSERT INTO db_info (version) VALUES (1)")
|
cursor.execute("INSERT INTO db_info (version) VALUES (1)")
|
||||||
self.conn.commit()
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
else:
|
else:
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
self._migrate_db(version[0])
|
self._migrate_db(version[0])
|
||||||
|
|
||||||
def _migrate_db(self, version):
|
def _migrate_db(self, version):
|
||||||
|
conn = sqlite3.connect(self.db_path)
|
||||||
|
cursor = conn.cursor()
|
||||||
# Perform migrations based on the current version
|
# Perform migrations based on the current version
|
||||||
# For example, if the current version is 1 and the latest version is 2:
|
# For example, if the current version is 1 and the latest version is 2:
|
||||||
if version < 2:
|
if version < 2:
|
||||||
self.cursor.execute("ALTER TABLE skills_library ADD COLUMN new_column TEXT")
|
cursor.execute("ALTER TABLE skills_library ADD COLUMN new_column TEXT")
|
||||||
self.cursor.execute("UPDATE db_info SET version = 2")
|
cursor.execute("UPDATE db_info SET version = 2")
|
||||||
self.conn.commit()
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
def _create_table(self):
|
def _create_table(self):
|
||||||
self.cursor.execute("""
|
conn = sqlite3.connect(self.db_path)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS skills_library (
|
CREATE TABLE IF NOT EXISTS skills_library (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
version INTEGER,
|
version INTEGER,
|
||||||
@ -53,29 +59,49 @@ class SkillsLibrary:
|
|||||||
content TEXT
|
content TEXT
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
self.conn.commit()
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
def add_entry(self, version, category, title, content):
|
def add_entry(self, version, category, title, content):
|
||||||
self.cursor.execute("""
|
conn = sqlite3.connect(self.db_path)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("""
|
||||||
INSERT INTO skills_library (version, category, title, content)
|
INSERT INTO skills_library (version, category, title, content)
|
||||||
VALUES (?, ?, ?, ?)
|
VALUES (?, ?, ?, ?)
|
||||||
""", (version, category, title, content))
|
""", (version, category, title, content))
|
||||||
self.conn.commit()
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
def list_entries(self):
|
def list_entries(self):
|
||||||
self.cursor.execute("SELECT * FROM skills_library")
|
conn = sqlite3.connect(self.db_path)
|
||||||
return self.cursor.fetchall()
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SELECT * FROM skills_library")
|
||||||
|
res = cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return res
|
||||||
|
|
||||||
def query_entry(self, text):
|
def query_entry(self, text):
|
||||||
self.cursor.execute("""
|
conn = sqlite3.connect(self.db_path)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("""
|
||||||
SELECT * FROM skills_library
|
SELECT * FROM skills_library
|
||||||
WHERE category LIKE ? OR title LIKE ? OR content LIKE ?
|
WHERE category LIKE ? OR title LIKE ? OR content LIKE ?
|
||||||
""", (f'%{text}%', f'%{text}%', f'%{text}%'))
|
""", (f'%{text}%', f'%{text}%', f'%{text}%'))
|
||||||
return self.cursor.fetchall()
|
res= cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return res
|
||||||
|
|
||||||
def remove_entry(self, id):
|
def remove_entry(self, id):
|
||||||
self.cursor.execute("DELETE FROM skills_library WHERE id = ?", (id,))
|
conn = sqlite3.connect(self.db_path)
|
||||||
self.conn.commit()
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("DELETE FROM skills_library WHERE id = ?", (id,))
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
def export_entries(self, file_path):
|
def export_entries(self, file_path):
|
||||||
with open(file_path, 'w') as f:
|
with open(file_path, 'w') as f:
|
||||||
|
@ -30,5 +30,14 @@ class DiscussionInfos(BaseModel):
|
|||||||
|
|
||||||
@router.post("/add_discussion_to_skills_library")
|
@router.post("/add_discussion_to_skills_library")
|
||||||
def add_discussion_to_skills_library(discussionInfos:DiscussionInfos):
|
def add_discussion_to_skills_library(discussionInfos:DiscussionInfos):
|
||||||
client = lollmsElfServer.session.get_client(discussionInfos.client_id)
|
lollmsElfServer.ShowBlockingMessage("Learning...")
|
||||||
lollmsElfServer.add_discussion_tto_skills_library(client)
|
try:
|
||||||
|
client = lollmsElfServer.session.get_client(discussionInfos.client_id)
|
||||||
|
category, title, content = lollmsElfServer.add_discussion_to_skills_library(client)
|
||||||
|
lollmsElfServer.InfoMessage(f"Discussion skill added to skills library:\ntitle:{title}\ncategory:{category}")
|
||||||
|
except Exception as ex:
|
||||||
|
trace_exception(ex)
|
||||||
|
ASCIIColors.error(ex)
|
||||||
|
lollmsElfServer.InfoMessage(f"Failed to learn from this discussion because of the follwoing error:\n{ex}")
|
||||||
|
return {"status":False,"error":f"{ex}"}
|
||||||
|
return {"status":True}
|
||||||
|
Loading…
Reference in New Issue
Block a user