mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2024-12-19 20:37:51 +00:00
Moved to new discussion system
This commit is contained in:
parent
6a0bf65953
commit
dbbb277029
@ -25,6 +25,6 @@ CMD ["/bin/bash", "-c", " \
|
|||||||
python app.py \
|
python app.py \
|
||||||
--host 0.0.0.0 \
|
--host 0.0.0.0 \
|
||||||
--port 9600 \
|
--port 9600 \
|
||||||
--db_path /data/Documents/databases/database.db \
|
--discussion_db_name /data/Documents/databases/database.db \
|
||||||
--config /configs/config.yaml \
|
--config /configs/config.yaml \
|
||||||
"]
|
"]
|
||||||
|
29
api/db.py
29
api/db.py
@ -3,6 +3,7 @@ import sqlite3
|
|||||||
from pathlib import Path
|
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
|
||||||
import json
|
import json
|
||||||
|
|
||||||
__author__ = "parisneo"
|
__author__ = "parisneo"
|
||||||
@ -14,14 +15,22 @@ __license__ = "Apache 2.0"
|
|||||||
# =================================== Database ==================================================================
|
# =================================== Database ==================================================================
|
||||||
class DiscussionsDB:
|
class DiscussionsDB:
|
||||||
|
|
||||||
def __init__(self, db_path="database.db"):
|
def __init__(self, lollms_paths:LollmsPaths, discussion_db_name="default"):
|
||||||
self.db_path = Path(db_path)
|
self.lollms_paths = lollms_paths
|
||||||
self.db_path .parent.mkdir(exist_ok=True, parents= True)
|
if Path(discussion_db_name).is_absolute():
|
||||||
|
self.discussion_db_path = Path(discussion_db_name)
|
||||||
|
self.discussion_db_name = Path(discussion_db_name).name
|
||||||
|
else:
|
||||||
|
self.discussion_db_name = discussion_db_name
|
||||||
|
self.discussion_db_path = self.lollms_paths.personal_discussions_path/discussion_db_name
|
||||||
|
|
||||||
|
self.discussion_db_path.mkdir(exist_ok=True, parents= True)
|
||||||
|
self.discussion_db_file_path = self.discussion_db_path/"database.db"
|
||||||
|
|
||||||
|
|
||||||
def create_tables(self):
|
def create_tables(self):
|
||||||
db_version = 10
|
db_version = 10
|
||||||
with sqlite3.connect(self.db_path) as conn:
|
with sqlite3.connect(self.discussion_db_file_path) as conn:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
@ -72,7 +81,7 @@ class DiscussionsDB:
|
|||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
def add_missing_columns(self):
|
def add_missing_columns(self):
|
||||||
with sqlite3.connect(self.db_path) as conn:
|
with sqlite3.connect(self.discussion_db_file_path) as conn:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
table_columns = {
|
table_columns = {
|
||||||
@ -130,7 +139,7 @@ class DiscussionsDB:
|
|||||||
with optional parameters.
|
with optional parameters.
|
||||||
Returns the cursor object for further processing.
|
Returns the cursor object for further processing.
|
||||||
"""
|
"""
|
||||||
with sqlite3.connect(self.db_path) as conn:
|
with sqlite3.connect(self.discussion_db_file_path) as conn:
|
||||||
if params is None:
|
if params is None:
|
||||||
cursor = conn.execute(query)
|
cursor = conn.execute(query)
|
||||||
else:
|
else:
|
||||||
@ -147,7 +156,7 @@ class DiscussionsDB:
|
|||||||
with optional parameters.
|
with optional parameters.
|
||||||
Returns the cursor object for further processing.
|
Returns the cursor object for further processing.
|
||||||
"""
|
"""
|
||||||
with sqlite3.connect(self.db_path) as conn:
|
with sqlite3.connect(self.discussion_db_file_path) as conn:
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
if params is None:
|
if params is None:
|
||||||
cursor.execute(query)
|
cursor.execute(query)
|
||||||
@ -162,7 +171,7 @@ class DiscussionsDB:
|
|||||||
Returns the ID of the newly inserted row.
|
Returns the ID of the newly inserted row.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with sqlite3.connect(self.db_path) as conn:
|
with sqlite3.connect(self.discussion_db_file_path) as conn:
|
||||||
cursor = conn.execute(query, params)
|
cursor = conn.execute(query, params)
|
||||||
rowid = cursor.lastrowid
|
rowid = cursor.lastrowid
|
||||||
conn.commit()
|
conn.commit()
|
||||||
@ -176,7 +185,7 @@ class DiscussionsDB:
|
|||||||
Returns the ID of the newly inserted row.
|
Returns the ID of the newly inserted row.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with sqlite3.connect(self.db_path) as conn:
|
with sqlite3.connect(self.discussion_db_file_path) as conn:
|
||||||
conn.execute(query, params)
|
conn.execute(query, params)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
@ -580,6 +589,8 @@ class Discussion:
|
|||||||
def __init__(self, discussion_id, discussions_db:DiscussionsDB):
|
def __init__(self, discussion_id, discussions_db:DiscussionsDB):
|
||||||
self.discussion_id = discussion_id
|
self.discussion_id = discussion_id
|
||||||
self.discussions_db = discussions_db
|
self.discussions_db = discussions_db
|
||||||
|
self.discussion_folder = self.discussions_db.discussion_db_path/f"{discussion_id}"
|
||||||
|
self.discussion_folder.mkdir(exist_ok=True)
|
||||||
self.messages = self.get_messages()
|
self.messages = self.get_messages()
|
||||||
if len(self.messages)>0:
|
if len(self.messages)>0:
|
||||||
self.current_message = self.messages[-1]
|
self.current_message = self.messages[-1]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# =================== Lord Of Large Language Multimodal Systems Configuration file ===========================
|
# =================== Lord Of Large Language Multimodal Systems Configuration file ===========================
|
||||||
version: 65
|
version: 66
|
||||||
binding_name: null
|
binding_name: null
|
||||||
model_name: null
|
model_name: null
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ user_avatar: default_user.svg
|
|||||||
use_user_informations_in_discussion: false
|
use_user_informations_in_discussion: false
|
||||||
|
|
||||||
# UI parameters
|
# UI parameters
|
||||||
db_path: database.db
|
discussion_db_name: default
|
||||||
|
|
||||||
# Automatic updates
|
# Automatic updates
|
||||||
debug: False
|
debug: False
|
||||||
|
@ -169,7 +169,7 @@ This Flask server provides various endpoints to manage and interact with the cha
|
|||||||
"binding": "llama_cpp",
|
"binding": "llama_cpp",
|
||||||
"config": "local_config.yaml",
|
"config": "local_config.yaml",
|
||||||
"ctx_size": 4096,
|
"ctx_size": 4096,
|
||||||
"db_path": "databases/database.db",
|
"discussion_db_name": "databases/database.db",
|
||||||
"debug": false,
|
"debug": false,
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"language": "en-US",
|
"language": "en-US",
|
||||||
|
@ -54,7 +54,7 @@ def list_discussions():
|
|||||||
async def list_databases():
|
async def list_databases():
|
||||||
"""List all the personal databases in the LoLLMs server."""
|
"""List all the personal databases in the LoLLMs server."""
|
||||||
# Retrieve the list of database names
|
# Retrieve the list of database names
|
||||||
databases = [f.name for f in lollmsElfServer.lollms_paths.personal_databases_path.iterdir() if f.suffix == ".db"]
|
databases = [f.name for f in lollmsElfServer.lollms_paths.personal_discussions_path.iterdir() if f.is_dir() and (f/"database.db").exists()]
|
||||||
# Return the list of database names
|
# Return the list of database names
|
||||||
return databases
|
return databases
|
||||||
|
|
||||||
@ -62,16 +62,13 @@ async def list_databases():
|
|||||||
def select_database(data:DatabaseSelectionParameters):
|
def select_database(data:DatabaseSelectionParameters):
|
||||||
if(".." in data.name):
|
if(".." in data.name):
|
||||||
raise "Detected an attempt of path traversal. Are you kidding me?"
|
raise "Detected an attempt of path traversal. Are you kidding me?"
|
||||||
|
|
||||||
if not data.name.endswith(".db"):
|
|
||||||
data.name += ".db"
|
|
||||||
print(f'Selecting database {data.name}')
|
print(f'Selecting database {data.name}')
|
||||||
# Create database object
|
# Create database object
|
||||||
lollmsElfServer.db = DiscussionsDB((lollmsElfServer.lollms_paths.personal_databases_path/data.name).resolve())
|
lollmsElfServer.db = DiscussionsDB(lollmsElfServer.lollms_paths, data.name)
|
||||||
ASCIIColors.info("Checking discussions database... ",end="")
|
ASCIIColors.info("Checking discussions database... ",end="")
|
||||||
lollmsElfServer.db.create_tables()
|
lollmsElfServer.db.create_tables()
|
||||||
lollmsElfServer.db.add_missing_columns()
|
lollmsElfServer.db.add_missing_columns()
|
||||||
lollmsElfServer.config.db_path = data.name
|
lollmsElfServer.config.discussion_db_name = data.name
|
||||||
ASCIIColors.success("ok")
|
ASCIIColors.success("ok")
|
||||||
|
|
||||||
if lollmsElfServer.config.auto_save:
|
if lollmsElfServer.config.auto_save:
|
||||||
@ -80,11 +77,11 @@ def select_database(data:DatabaseSelectionParameters):
|
|||||||
if lollmsElfServer.config.data_vectorization_activate and lollmsElfServer.config.activate_ltm:
|
if lollmsElfServer.config.data_vectorization_activate and lollmsElfServer.config.activate_ltm:
|
||||||
try:
|
try:
|
||||||
ASCIIColors.yellow("0- Detected discussion vectorization request")
|
ASCIIColors.yellow("0- Detected discussion vectorization request")
|
||||||
folder = lollmsElfServer.lollms_paths.personal_databases_path/"vectorized_dbs"
|
folder = lollmsElfServer.lollms_paths.personal_discussions_path/"vectorized_dbs"
|
||||||
folder.mkdir(parents=True, exist_ok=True)
|
folder.mkdir(parents=True, exist_ok=True)
|
||||||
lollmsElfServer.long_term_memory = TextVectorizer(
|
lollmsElfServer.long_term_memory = TextVectorizer(
|
||||||
vectorization_method=VectorizationMethod.TFIDF_VECTORIZER,#=VectorizationMethod.BM25_VECTORIZER,
|
vectorization_method=VectorizationMethod.TFIDF_VECTORIZER,#=VectorizationMethod.BM25_VECTORIZER,
|
||||||
database_path=folder/lollmsElfServer.config.db_path,
|
database_path=folder/lollmsElfServer.config.discussion_db_name,
|
||||||
data_visualization_method=VisualizationMethod.PCA,#VisualizationMethod.PCA,
|
data_visualization_method=VisualizationMethod.PCA,#VisualizationMethod.PCA,
|
||||||
save_db=True
|
save_db=True
|
||||||
)
|
)
|
||||||
@ -212,12 +209,12 @@ async def export_multiple_discussions(discussion_export: DiscussionExport):
|
|||||||
return {"status":False,"error":str(ex)}
|
return {"status":False,"error":str(ex)}
|
||||||
|
|
||||||
|
|
||||||
class Discussion(BaseModel):
|
class DiscussionInfo(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
content: str
|
content: str
|
||||||
|
|
||||||
class DiscussionImport(BaseModel):
|
class DiscussionImport(BaseModel):
|
||||||
jArray: List[Discussion]
|
jArray: List[DiscussionInfo]
|
||||||
|
|
||||||
@router.post("/import_multiple_discussions")
|
@router.post("/import_multiple_discussions")
|
||||||
async def import_multiple_discussions(discussion_import: DiscussionImport):
|
async def import_multiple_discussions(discussion_import: DiscussionImport):
|
||||||
|
@ -7,7 +7,7 @@ description:
|
|||||||
application. These routes allow users to manipulate the message elements.
|
application. These routes allow users to manipulate the message elements.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from fastapi import APIRouter, Body
|
from fastapi import APIRouter, Body, Request
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
from lollms_webui import LOLLMSWebUI
|
from lollms_webui import LOLLMSWebUI
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
@ -21,6 +21,8 @@ from safe_store.text_vectorizer import TextVectorizer, VectorizationMethod, Visu
|
|||||||
import tqdm
|
import tqdm
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
from pydantic import BaseModel, ValidationError
|
from pydantic import BaseModel, ValidationError
|
||||||
|
import json
|
||||||
|
|
||||||
# ----------------------- Defining router and main class ------------------------------
|
# ----------------------- Defining router and main class ------------------------------
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
@ -28,16 +30,16 @@ lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
|||||||
|
|
||||||
class EditMessageParameters(BaseModel):
|
class EditMessageParameters(BaseModel):
|
||||||
client_id: str = Field(..., min_length=1)
|
client_id: str = Field(..., min_length=1)
|
||||||
id: int = Field(..., gt=0)
|
id: int = Field(...)
|
||||||
message: str = Field(..., min_length=1)
|
message: str = Field(...)
|
||||||
metadata: dict = Field(default={})
|
metadata: list = Field(default=[])
|
||||||
|
|
||||||
@router.post("/edit_message")
|
@router.post("/edit_message")
|
||||||
async def edit_message(edit_params: EditMessageParameters):
|
async def edit_message(edit_params: EditMessageParameters):
|
||||||
client_id = edit_params.client_id
|
client_id = edit_params.client_id
|
||||||
message_id = edit_params.id
|
message_id = edit_params.id
|
||||||
new_message = edit_params.message
|
new_message = edit_params.message
|
||||||
metadata = edit_params.metadata
|
metadata = json.dumps(edit_params.metadata,indent=4)
|
||||||
try:
|
try:
|
||||||
lollmsElfServer.connections[client_id]["current_discussion"].edit_message(message_id, new_message, new_metadata=metadata)
|
lollmsElfServer.connections[client_id]["current_discussion"].edit_message(message_id, new_message, new_metadata=metadata)
|
||||||
return {"status": True}
|
return {"status": True}
|
||||||
@ -49,7 +51,7 @@ async def edit_message(edit_params: EditMessageParameters):
|
|||||||
|
|
||||||
class MessageRankParameters(BaseModel):
|
class MessageRankParameters(BaseModel):
|
||||||
client_id: str = Field(..., min_length=1)
|
client_id: str = Field(..., min_length=1)
|
||||||
id: int = Field(..., gt=0)
|
id: int = Field(...)
|
||||||
|
|
||||||
@router.post("/message_rank_up")
|
@router.post("/message_rank_up")
|
||||||
async def message_rank_up(rank_params: MessageRankParameters):
|
async def message_rank_up(rank_params: MessageRankParameters):
|
||||||
@ -76,7 +78,7 @@ def message_rank_down(rank_params: MessageRankParameters):
|
|||||||
|
|
||||||
class MessageDeleteParameters(BaseModel):
|
class MessageDeleteParameters(BaseModel):
|
||||||
client_id: str = Field(..., min_length=1)
|
client_id: str = Field(..., min_length=1)
|
||||||
id: int = Field(..., gt=0)
|
id: int = Field(...)
|
||||||
|
|
||||||
@router.post("/delete_message")
|
@router.post("/delete_message")
|
||||||
async def delete_message(delete_params: MessageDeleteParameters):
|
async def delete_message(delete_params: MessageDeleteParameters):
|
||||||
|
@ -36,7 +36,7 @@ def get_presets():
|
|||||||
preset = yaml.safe_load(file)
|
preset = yaml.safe_load(file)
|
||||||
if preset is not None:
|
if preset is not None:
|
||||||
presets.append(preset)
|
presets.append(preset)
|
||||||
presets_folder = lollmsElfServer.lollms_paths.personal_databases_path/"lollms_playground_presets"
|
presets_folder = lollmsElfServer.lollms_paths.personal_discussions_path/"lollms_playground_presets"
|
||||||
presets_folder.mkdir(exist_ok=True, parents=True)
|
presets_folder.mkdir(exist_ok=True, parents=True)
|
||||||
for filename in presets_folder.glob('*.yaml'):
|
for filename in presets_folder.glob('*.yaml'):
|
||||||
with open(filename, 'r', encoding='utf-8') as file:
|
with open(filename, 'r', encoding='utf-8') as file:
|
||||||
@ -58,7 +58,7 @@ async def add_preset(preset_data: PresetData):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
|
||||||
presets_folder = lollmsElfServer.lollms_paths.personal_databases_path/"lollms_playground_presets"
|
presets_folder = lollmsElfServer.lollms_paths.personal_discussions_path/"lollms_playground_presets"
|
||||||
if not presets_folder.exists():
|
if not presets_folder.exists():
|
||||||
presets_folder.mkdir(exist_ok=True, parents=True)
|
presets_folder.mkdir(exist_ok=True, parents=True)
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ async def del_preset(preset_data: PresetData):
|
|||||||
if ".." in preset_data.name or "/" in preset_data.name:
|
if ".." in preset_data.name or "/" in preset_data.name:
|
||||||
raise HTTPException(status_code=400, detail="Invalid preset name")
|
raise HTTPException(status_code=400, detail="Invalid preset name")
|
||||||
|
|
||||||
presets_file = lollmsElfServer.lollms_paths.personal_databases_path/"lollms_playground_presets"/preset_data.name
|
presets_file = lollmsElfServer.lollms_paths.personal_discussions_path/"lollms_playground_presets"/preset_data.name
|
||||||
try:
|
try:
|
||||||
presets_file.unlink()
|
presets_file.unlink()
|
||||||
return {"status":True}
|
return {"status":True}
|
||||||
@ -99,8 +99,12 @@ async def del_preset(preset_data: PresetData):
|
|||||||
return {"status":False}
|
return {"status":False}
|
||||||
|
|
||||||
|
|
||||||
|
class PresetDataWithValue(BaseModel):
|
||||||
|
name: str = Field(..., min_length=1)
|
||||||
|
preset: str
|
||||||
|
|
||||||
@router.post("/save_presets")
|
@router.post("/save_presets")
|
||||||
async def save_presets(preset_data: PresetData):
|
async def save_presets(preset_data: PresetDataWithValue):
|
||||||
"""
|
"""
|
||||||
Saves a preset to a file.
|
Saves a preset to a file.
|
||||||
|
|
||||||
@ -111,7 +115,7 @@ async def save_presets(preset_data: PresetData):
|
|||||||
if preset_data.preset is None:
|
if preset_data.preset is None:
|
||||||
raise HTTPException(status_code=400, detail="Preset data is missing in the request")
|
raise HTTPException(status_code=400, detail="Preset data is missing in the request")
|
||||||
|
|
||||||
presets_file = lollmsElfServer.lollms_paths.personal_databases_path/"presets.json"
|
presets_file = lollmsElfServer.lollms_paths.personal_discussions_path/"presets.json"
|
||||||
# Save the JSON data to a file.
|
# Save the JSON data to a file.
|
||||||
with open(presets_file, "w") as f:
|
with open(presets_file, "w") as f:
|
||||||
json.dump(preset_data.preset, f, indent=4)
|
json.dump(preset_data.preset, f, indent=4)
|
||||||
|
@ -63,10 +63,10 @@ async def restart_program():
|
|||||||
async def update_software():
|
async def update_software():
|
||||||
"""Update the software."""
|
"""Update the software."""
|
||||||
if lollmsElfServer.config.headless_server_mode:
|
if lollmsElfServer.config.headless_server_mode:
|
||||||
return {"status":False,"error":"Restarting app is blocked when in headless mode for obvious security reasons!"}
|
return {"status":False,"error":"Updating app is blocked when in headless mode for obvious security reasons!"}
|
||||||
|
|
||||||
if lollmsElfServer.config.host=="0.0.0.0":
|
if lollmsElfServer.config.host=="0.0.0.0":
|
||||||
return {"status":False,"error":"Restarting app is blocked when the server is exposed outside for very obvious reasons!"}
|
return {"status":False,"error":"Updating app is blocked when the server is exposed outside for very obvious reasons!"}
|
||||||
|
|
||||||
# Display an informative message
|
# Display an informative message
|
||||||
ASCIIColors.info("")
|
ASCIIColors.info("")
|
||||||
@ -93,10 +93,10 @@ async def update_software():
|
|||||||
def check_update():
|
def check_update():
|
||||||
"""Checks if an update is available"""
|
"""Checks if an update is available"""
|
||||||
if lollmsElfServer.config.headless_server_mode:
|
if lollmsElfServer.config.headless_server_mode:
|
||||||
return {"status":False,"error":"Restarting app is blocked when in headless mode for obvious security reasons!"}
|
return {"status":False,"error":"Checking updates is blocked when in headless mode for obvious security reasons!"}
|
||||||
|
|
||||||
if lollmsElfServer.config.host=="0.0.0.0":
|
if lollmsElfServer.config.host=="0.0.0.0":
|
||||||
return {"status":False,"error":"Restarting app is blocked when the server is exposed outside for very obvious reasons!"}
|
return {"status":False,"error":"Checking updates is blocked when the server is exposed outside for very obvious reasons!"}
|
||||||
|
|
||||||
if lollmsElfServer.config.auto_update:
|
if lollmsElfServer.config.auto_update:
|
||||||
res = lollmsElfServer.check_update_()
|
res = lollmsElfServer.check_update_()
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit d6532fbaf6e41911d1c951f4682ef4f329621996
|
Subproject commit da2d2d9a6357891f06f39712593c999fdb270f4a
|
@ -19,7 +19,7 @@ from lollms.paths import LollmsPaths
|
|||||||
from lollms.helpers import ASCIIColors, trace_exception
|
from lollms.helpers import ASCIIColors, trace_exception
|
||||||
from lollms.com import NotificationType, NotificationDisplayType, LoLLMsCom
|
from lollms.com import NotificationType, NotificationDisplayType, LoLLMsCom
|
||||||
from lollms.app import LollmsApplication
|
from lollms.app import LollmsApplication
|
||||||
from lollms.utilities import File64BitsManager, PromptReshaper, PackageManager, find_first_available_file_index, run_async, is_asyncio_loop_running
|
from lollms.utilities import File64BitsManager, PromptReshaper, PackageManager, find_first_available_file_index, run_async, is_asyncio_loop_running, yes_or_no_input
|
||||||
from lollms.generation import RECPTION_MANAGER, ROLE_CHANGE_DECISION, ROLE_CHANGE_OURTPUT
|
from lollms.generation import RECPTION_MANAGER, ROLE_CHANGE_DECISION, ROLE_CHANGE_OURTPUT
|
||||||
|
|
||||||
import git
|
import git
|
||||||
@ -127,8 +127,6 @@ class LOLLMSWebUI(LOLLMSElfServer):
|
|||||||
lollms_paths,
|
lollms_paths,
|
||||||
load_binding=load_binding,
|
load_binding=load_binding,
|
||||||
load_model=load_model,
|
load_model=load_model,
|
||||||
load_sd_service=load_sd_service,
|
|
||||||
load_voice_service=load_voice_service,
|
|
||||||
try_select_binding=try_select_binding,
|
try_select_binding=try_select_binding,
|
||||||
try_select_model=try_select_model,
|
try_select_model=try_select_model,
|
||||||
callback=callback,
|
callback=callback,
|
||||||
@ -155,13 +153,40 @@ class LOLLMSWebUI(LOLLMSElfServer):
|
|||||||
self._current_ai_message_id = 0
|
self._current_ai_message_id = 0
|
||||||
self._message_id = 0
|
self._message_id = 0
|
||||||
|
|
||||||
self.db_path = config["db_path"]
|
|
||||||
if Path(self.db_path).is_absolute():
|
|
||||||
# Create database object
|
# migrate old databases to new ones:
|
||||||
self.db = DiscussionsDB(self.db_path)
|
databases_path = self.lollms_paths.personal_path/"databases"
|
||||||
else:
|
if databases_path.exists() and len([f for f in databases_path.iterdir() if f.suffix==".db"])>0:
|
||||||
# Create database object
|
if yes_or_no_input("Old databases have been spotted on your system. Do you want me to migrate them to the new format?"):
|
||||||
self.db = DiscussionsDB(self.lollms_paths.personal_databases_path/self.db_path)
|
databases_found = False
|
||||||
|
for database_path in databases_path.iterdir():
|
||||||
|
if database_path.suffix==".db":
|
||||||
|
ASCIIColors.red(f"Found old discussion database format : {database_path}")
|
||||||
|
ASCIIColors.red(f"Migrating to new format... ",end="")
|
||||||
|
new_db_path = self.lollms_paths.personal_discussions_path/database_path.stem
|
||||||
|
new_db_path.mkdir(exist_ok=True, parents=True)
|
||||||
|
try:
|
||||||
|
shutil.copy(database_path,new_db_path/"database.db")
|
||||||
|
ASCIIColors.green("ok")
|
||||||
|
databases_found = True
|
||||||
|
except Exception as ex:
|
||||||
|
ASCIIColors.warning(ex)
|
||||||
|
if databases_found:
|
||||||
|
ASCIIColors.green(f"Databases are migrated from {databases_path} to the new {self.lollms_paths.personal_discussions_path} path")
|
||||||
|
if yes_or_no_input("Databases are migrated to the new format. Do you want me to delete the previous version?"):
|
||||||
|
for database_path in databases_path.iterdir():
|
||||||
|
if database_path.suffix==".db":
|
||||||
|
ASCIIColors.red(f"Deleting {database_path}")
|
||||||
|
database_path.unlink()
|
||||||
|
if config["discussion_db_name"].endswith(".db"):
|
||||||
|
config["discussion_db_name"]=config["discussion_db_name"].replace(".db","")
|
||||||
|
config.save_config()
|
||||||
|
|
||||||
|
self.discussion_db_name = config["discussion_db_name"]
|
||||||
|
|
||||||
|
# Create database object
|
||||||
|
self.db = DiscussionsDB(self.lollms_paths, self.discussion_db_name)
|
||||||
|
|
||||||
# If the database is empty, populate it with tables
|
# If the database is empty, populate it with tables
|
||||||
ASCIIColors.info("Checking discussions database... ",end="")
|
ASCIIColors.info("Checking discussions database... ",end="")
|
||||||
@ -173,7 +198,7 @@ class LOLLMSWebUI(LOLLMSElfServer):
|
|||||||
if self.config.data_vectorization_activate and self.config.activate_ltm:
|
if self.config.data_vectorization_activate and self.config.activate_ltm:
|
||||||
try:
|
try:
|
||||||
ASCIIColors.yellow("Loading long term memory")
|
ASCIIColors.yellow("Loading long term memory")
|
||||||
folder = self.lollms_paths.personal_databases_path/"vectorized_dbs"
|
folder = self.lollms_paths.personal_discussions_path/"vectorized_dbs"
|
||||||
folder.mkdir(parents=True, exist_ok=True)
|
folder.mkdir(parents=True, exist_ok=True)
|
||||||
self.build_long_term_skills_memory()
|
self.build_long_term_skills_memory()
|
||||||
ASCIIColors.yellow("Ready")
|
ASCIIColors.yellow("Ready")
|
||||||
@ -236,7 +261,13 @@ class LOLLMSWebUI(LOLLMSElfServer):
|
|||||||
ASCIIColors.blue(f"Your personal data is stored here :",end="")
|
ASCIIColors.blue(f"Your personal data is stored here :",end="")
|
||||||
ASCIIColors.green(f"{self.lollms_paths.personal_path}")
|
ASCIIColors.green(f"{self.lollms_paths.personal_path}")
|
||||||
|
|
||||||
|
self.start_servers(
|
||||||
|
load_sd_service=load_sd_service,
|
||||||
|
load_voice_service=load_voice_service
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_uploads_path(self, client_id):
|
||||||
|
return self.db.discussion_db_path/f'{self.connections[client_id]["current_discussion"].discussion_id}'
|
||||||
# Other methods and properties of the LoLLMSWebUI singleton class
|
# Other methods and properties of the LoLLMSWebUI singleton class
|
||||||
def check_module_update_(self, repo_path, branch_name="main"):
|
def check_module_update_(self, repo_path, branch_name="main"):
|
||||||
try:
|
try:
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
web/dist/index.html
vendored
4
web/dist/index.html
vendored
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>LoLLMS WebUI - Welcome</title>
|
<title>LoLLMS WebUI - Welcome</title>
|
||||||
<script type="module" crossorigin src="/assets/index-338e837b.js"></script>
|
<script type="module" crossorigin src="/assets/index-94f249ad.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/index-67427921.css">
|
<link rel="stylesheet" href="/assets/index-55148c7c.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
@ -222,12 +222,13 @@
|
|||||||
</textarea>
|
</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
<div v-if="message.metadata !== null">
|
<div v-if="message.metadata !== null">
|
||||||
<div v-for="(metadata, index) in message.metadata" :key="'json-' + message.id + '-' + index" class="json font-bold">
|
<div v-for="(metadata, index) in message.metadata.filter(metadata => metadata!=null && metadata.hasOwnProperty('title') && metadata.hasOwnProperty('content') )" :key="'json-' + message.id + '-' + index" class="json font-bold">
|
||||||
<JsonViewer :jsonFormText="metadata.title" :jsonData="metadata.content" />
|
<JsonViewer :jsonFormText="metadata.title" :jsonData="metadata.content" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
<DynamicUIRenderer v-if="message.ui !== null && message.ui !== undefined && message.ui !== ''" class="w-full h-full" :code="message.ui"></DynamicUIRenderer>
|
<DynamicUIRenderer v-if="message.ui !== null && message.ui !== undefined && message.ui !== ''" class="w-full h-full" :code="message.ui"></DynamicUIRenderer>
|
||||||
<audio controls autoplay v-if="audio_url!=null" :key="audio_url">
|
<audio controls autoplay v-if="audio_url!=null" :key="audio_url">
|
||||||
@ -370,10 +371,25 @@ export default {
|
|||||||
feather.replace()
|
feather.replace()
|
||||||
this.mdRenderHeight = this.$refs.mdRender.$el.offsetHeight
|
this.mdRenderHeight = this.$refs.mdRender.$el.offsetHeight
|
||||||
})
|
})
|
||||||
|
console.log("Checking metadata")
|
||||||
if (this.message.hasOwnProperty("metadata")){
|
console.log(this.message)
|
||||||
|
|
||||||
|
if (Object.prototype.hasOwnProperty.call(this.message,"metadata")){
|
||||||
if(this.message.metadata!=null){
|
if(this.message.metadata!=null){
|
||||||
this.audio_url = this.message.metadata.hasOwnProperty("audio_url") ? this.message.metadata.audio_url : null
|
console.log("Metadata found!")
|
||||||
|
if (!Array.isArray(this.message.metadata)) {
|
||||||
|
this.message.metadata = [];
|
||||||
|
}
|
||||||
|
console.log(typeof this.message.metadata)
|
||||||
|
console.log(this.message.metadata)
|
||||||
|
for(let metadata_entry of this.message.metadata){
|
||||||
|
if (Object.prototype.hasOwnProperty.call(metadata_entry, "audio_url")){
|
||||||
|
if(metadata_entry.audio_url!=null){
|
||||||
|
this.audio_url = metadata_entry.audio_url
|
||||||
|
console.log("Audio URL:", this.audio_url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,6 +484,22 @@ export default {
|
|||||||
let url = response.data.url
|
let url = response.data.url
|
||||||
console.log(url)
|
console.log(url)
|
||||||
this.audio_url = url
|
this.audio_url = url
|
||||||
|
if(!this.message.metadata) {
|
||||||
|
this.message.metadata = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let found = false;
|
||||||
|
|
||||||
|
for(let metadata_entry of this.message.metadata){
|
||||||
|
if (Object.prototype.hasOwnProperty.call(metadata_entry, "audio_url")){
|
||||||
|
metadata_entry.audio_url = this.audio_url;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
this.message.metadata.push({audio_url: this.audio_url});
|
||||||
|
}
|
||||||
this.$emit('updateMessage', this.message.id, this.message.content, this.audio_url)
|
this.$emit('updateMessage', this.message.id, this.message.content, this.audio_url)
|
||||||
}).catch(ex=>{
|
}).catch(ex=>{
|
||||||
this.$store.state.toast.showToast(`Error: ${ex}`,4,false)
|
this.$store.state.toast.showToast(`Error: ${ex}`,4,false)
|
||||||
|
@ -630,6 +630,7 @@ export default {
|
|||||||
|
|
||||||
|
|
||||||
socket.on('discussion', (data)=>{
|
socket.on('discussion', (data)=>{
|
||||||
|
console.log("Discussion recovered")
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.setDiscussionLoading(id, this.loading)
|
this.setDiscussionLoading(id, this.loading)
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -653,6 +654,7 @@ export default {
|
|||||||
})
|
})
|
||||||
|
|
||||||
socket.emit('load_discussion',{"id":id});
|
socket.emit('load_discussion',{"id":id});
|
||||||
|
console.log("here")
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -801,7 +803,7 @@ export default {
|
|||||||
},
|
},
|
||||||
async message_rank_up(id) {
|
async message_rank_up(id) {
|
||||||
try {
|
try {
|
||||||
const res = await axios.post('/message_rank_up', { params: { client_id: this.client_id, id: id } }, {headers: this.posts_headers})
|
const res = await axios.post('/message_rank_up', { client_id: this.client_id, id: id }, {headers: this.posts_headers})
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
return res.data
|
return res.data
|
||||||
@ -813,7 +815,7 @@ export default {
|
|||||||
},
|
},
|
||||||
async message_rank_down(id) {
|
async message_rank_down(id) {
|
||||||
try {
|
try {
|
||||||
const res = await axios.post('/message_rank_down', { params: { client_id: this.client_id, id: id } }, {headers: this.posts_headers})
|
const res = await axios.post('/message_rank_down', { client_id: this.client_id, id: id } , {headers: this.posts_headers})
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
return res.data
|
return res.data
|
||||||
@ -825,7 +827,17 @@ export default {
|
|||||||
},
|
},
|
||||||
async edit_message(id, message, audio_url) {
|
async edit_message(id, message, audio_url) {
|
||||||
try {
|
try {
|
||||||
const res = await axios.post('/edit_message', { params: { client_id: this.client_id, id: id, message: message, metadata: {audio_url:audio_url} } }, {headers: this.posts_headers})
|
console.log(typeof this.client_id)
|
||||||
|
console.log(typeof id)
|
||||||
|
console.log(typeof message)
|
||||||
|
console.log(typeof {audio_url:audio_url})
|
||||||
|
const res = await axios.post('/edit_message', {
|
||||||
|
client_id: this.client_id,
|
||||||
|
id: id,
|
||||||
|
message: message,
|
||||||
|
metadata: [{audio_url:audio_url}]
|
||||||
|
}, {headers: this.posts_headers}
|
||||||
|
)
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
return res.data
|
return res.data
|
||||||
@ -841,7 +853,7 @@ export default {
|
|||||||
const res = await axios.post('/export_multiple_discussions', {
|
const res = await axios.post('/export_multiple_discussions', {
|
||||||
discussion_ids: discussionIdArr,
|
discussion_ids: discussionIdArr,
|
||||||
export_format: export_format
|
export_format: export_format
|
||||||
})
|
}, {headers: this.posts_headers})
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
return res.data
|
return res.data
|
||||||
@ -859,7 +871,7 @@ export default {
|
|||||||
console.log('sending import', jArray)
|
console.log('sending import', jArray)
|
||||||
const res = await axios.post('/import_multiple_discussions', {
|
const res = await axios.post('/import_multiple_discussions', {
|
||||||
jArray
|
jArray
|
||||||
})
|
}, {headers: this.posts_headers})
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
console.log('import response', res.data)
|
console.log('import response', res.data)
|
||||||
@ -974,7 +986,7 @@ export default {
|
|||||||
|
|
||||||
}
|
}
|
||||||
catch{
|
catch{
|
||||||
|
console.log("error")
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
@ -1189,16 +1201,16 @@ export default {
|
|||||||
message_type: this.msgTypes.MSG_TYPE_FULL,
|
message_type: this.msgTypes.MSG_TYPE_FULL,
|
||||||
sender_type: this.senderTypes.SENDER_TYPES_USER,
|
sender_type: this.senderTypes.SENDER_TYPES_USER,
|
||||||
content: msg,
|
content: msg,
|
||||||
id: lastmsgid,
|
id: lastmsgid,
|
||||||
discussion_id: this.discussion_id,
|
discussion_id: this.discussion_id,
|
||||||
parent_id: lastmsgid,
|
parent_id: lastmsgid,
|
||||||
|
|
||||||
binding: "",
|
binding: "",
|
||||||
model: "",
|
model: "",
|
||||||
personality: "",
|
personality: "",
|
||||||
|
|
||||||
created_at: new Date().toLocaleString(),
|
created_at: new Date().toLocaleString(),
|
||||||
finished_generating_at: new Date().toLocaleString(),
|
finished_generating_at: new Date().toLocaleString(),
|
||||||
rank: 0,
|
rank: 0,
|
||||||
|
|
||||||
steps: [],
|
steps: [],
|
||||||
@ -2078,7 +2090,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
formatted_database_name() {
|
formatted_database_name() {
|
||||||
const db_name = this.$store.state.config.db_path;
|
const db_name = this.$store.state.config.discussion_db_name;
|
||||||
const trimmed_name = db_name.slice(0, db_name.length - 3);
|
const trimmed_name = db_name.slice(0, db_name.length - 3);
|
||||||
return trimmed_name;
|
return trimmed_name;
|
||||||
},
|
},
|
||||||
|
@ -252,14 +252,14 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="min-width: 200px;">
|
<td style="min-width: 200px;">
|
||||||
<label for="db_path" class="text-sm font-bold" style="margin-right: 1rem;">Database path:</label>
|
<label for="discussion_db_name" class="text-sm font-bold" style="margin-right: 1rem;">Database path:</label>
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 100%;">
|
<td style="width: 100%;">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="db_path"
|
id="discussion_db_name"
|
||||||
required
|
required
|
||||||
v-model="configFile.db_path"
|
v-model="configFile.discussion_db_name"
|
||||||
@change="settingsChanged=true"
|
@change="settingsChanged=true"
|
||||||
class="w-full w-full mt-1 px-2 py-1 border border-gray-300 rounded dark:bg-gray-600 dark:bg-gray-600"
|
class="w-full w-full mt-1 px-2 py-1 border border-gray-300 rounded dark:bg-gray-600 dark:bg-gray-600"
|
||||||
>
|
>
|
||||||
@ -1137,7 +1137,7 @@
|
|||||||
<table class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
<table class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||||
<tr>
|
<tr>
|
||||||
<td style="min-width: 200px;">
|
<td style="min-width: 200px;">
|
||||||
<label for="db_path" class="text-sm font-bold" style="margin-right: 1rem;">Host:</label>
|
<label for="discussion_db_name" class="text-sm font-bold" style="margin-right: 1rem;">Host:</label>
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 100%;">
|
<td style="width: 100%;">
|
||||||
<input
|
<input
|
||||||
@ -1152,7 +1152,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="min-width: 200px;">
|
<td style="min-width: 200px;">
|
||||||
<label for="db_path" class="text-sm font-bold" style="margin-right: 1rem;">Port:</label>
|
<label for="discussion_db_name" class="text-sm font-bold" style="margin-right: 1rem;">Port:</label>
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 100%;">
|
<td style="width: 100%;">
|
||||||
<input
|
<input
|
||||||
@ -1168,7 +1168,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="min-width: 200px;">
|
<td style="min-width: 200px;">
|
||||||
<label for="db_path" class="text-sm font-bold" style="margin-right: 1rem;">Activate headless server mode (deactivates all code exectuion to protect the PC from attacks):</label>
|
<label for="discussion_db_name" class="text-sm font-bold" style="margin-right: 1rem;">Activate headless server mode (deactivates all code exectuion to protect the PC from attacks):</label>
|
||||||
</td>
|
</td>
|
||||||
<td style="width: 100%;">
|
<td style="width: 100%;">
|
||||||
<input
|
<input
|
||||||
@ -2536,6 +2536,10 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
posts_headers : {
|
||||||
|
'accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
defaultModelImgPlaceholder:defaultModelImgPlaceholder,
|
defaultModelImgPlaceholder:defaultModelImgPlaceholder,
|
||||||
voices: [],
|
voices: [],
|
||||||
voice_languages:{
|
voice_languages:{
|
||||||
@ -3589,6 +3593,7 @@ export default {
|
|||||||
try {
|
try {
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
axios.get('/get_active_binding_settings').then(res => {
|
axios.get('/get_active_binding_settings').then(res => {
|
||||||
|
console.log(res)
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
if (res) {
|
if (res) {
|
||||||
|
|
||||||
@ -3602,7 +3607,7 @@ export default {
|
|||||||
// send new data
|
// send new data
|
||||||
try {
|
try {
|
||||||
axios.post('/set_active_binding_settings',
|
axios.post('/set_active_binding_settings',
|
||||||
res).then(response => {
|
res, {headers: this.posts_headers}).then(response => {
|
||||||
if (response && response.data) {
|
if (response && response.data) {
|
||||||
console.log('binding set with new settings', response.data)
|
console.log('binding set with new settings', response.data)
|
||||||
this.$store.state.toast.showToast("Binding settings updated successfully!", 4, true)
|
this.$store.state.toast.showToast("Binding settings updated successfully!", 4, true)
|
||||||
@ -3639,7 +3644,7 @@ export default {
|
|||||||
onReloadBinding(binding_object){
|
onReloadBinding(binding_object){
|
||||||
console.log("Reloading binding")
|
console.log("Reloading binding")
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
axios.post('/reload_binding', { name: binding_object.binding.folder }).then((res) => {
|
axios.post('/reload_binding', { name: binding_object.binding.folder }, {headers: this.posts_headers}).then((res) => {
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
@ -4914,13 +4919,13 @@ export default {
|
|||||||
this.$store.state.config.use_user_name_in_discussions = value
|
this.$store.state.config.use_user_name_in_discussions = value
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
db_path: {
|
discussion_db_name: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.config.db_path;
|
return this.$store.state.config.discussion_db_name;
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
// You should not set the value directly here; use the updateSetting method instead
|
// You should not set the value directly here; use the updateSetting method instead
|
||||||
this.$store.state.config.db_path = value
|
this.$store.state.config.discussion_db_name = value
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit eb864579f77d8a0ad922d4e9e714cefa359e2709
|
Subproject commit d02faf591872f3e4495e8b91ea6eb7fe4d4fb217
|
@ -1 +1 @@
|
|||||||
Subproject commit 4f328753175352e2adb8a5222ffe7204a9484e04
|
Subproject commit 08a94ac1f5eb71966e5775e16ea8a3f8aede845c
|
Loading…
Reference in New Issue
Block a user