mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2025-01-29 15:44:12 +00:00
enhanced
This commit is contained in:
parent
023e35a179
commit
1320331fa8
@ -1,5 +1,5 @@
|
||||
# =================== Lord Of Large Language Multimodal Systems Configuration file ===========================
|
||||
version: 61
|
||||
version: 63
|
||||
binding_name: null
|
||||
model_name: null
|
||||
|
||||
@ -7,7 +7,9 @@ show_news_panel: True
|
||||
|
||||
# Execution protection
|
||||
turn_on_code_execution: True
|
||||
turn_on_code_validation: False
|
||||
turn_on_code_validation: True
|
||||
turn_on_open_file_validation: False
|
||||
turn_on_send_file_validation: False
|
||||
|
||||
# Server information
|
||||
headless_server_mode: False
|
||||
|
@ -13,7 +13,7 @@ from pydantic import BaseModel, Field
|
||||
from starlette.responses import StreamingResponse
|
||||
from lollms.types import MSG_TYPE
|
||||
from lollms.main_config import BaseConfig
|
||||
from lollms.utilities import detect_antiprompt, remove_text_from_string, trace_exception
|
||||
from lollms.utilities import detect_antiprompt, remove_text_from_string, trace_exception, show_yes_no_dialog
|
||||
from ascii_colors import ASCIIColors
|
||||
from api.db import DiscussionsDB
|
||||
from pathlib import Path
|
||||
@ -52,24 +52,6 @@ router = APIRouter()
|
||||
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
||||
|
||||
|
||||
def show_yes_no_dialog(title, text):
|
||||
import tkinter as tk
|
||||
from tkinter import messagebox
|
||||
# Create a new Tkinter root window and hide it
|
||||
root = tk.Tk()
|
||||
root.withdraw()
|
||||
|
||||
# Make the window appear on top
|
||||
root.attributes('-topmost', True)
|
||||
|
||||
# Show the dialog box
|
||||
result = messagebox.askyesno(title, text)
|
||||
|
||||
# Destroy the root window
|
||||
root.destroy()
|
||||
|
||||
return result
|
||||
|
||||
class CodeRequest(BaseModel):
|
||||
code: str = Field(..., description="Code to be executed")
|
||||
discussion_id: int = Field(..., description="Discussion ID")
|
||||
@ -155,6 +137,10 @@ async def open_code_folder_in_vs_code(request: OpenCodeFolderInVsCodeRequestMode
|
||||
if lollmsElfServer.config.host=="0.0.0.0":
|
||||
return {"status":False,"error":"Open code folder in vscode is blocked when the server is exposed outside for very obvious reasons!"}
|
||||
|
||||
if lollmsElfServer.config.turn_on_open_file_validation:
|
||||
if not show_yes_no_dialog("Validation","Do you validate the opening of folder in vscode?"):
|
||||
return {"status":False,"error":"User refused the execution!"}
|
||||
|
||||
try:
|
||||
if request.discussion_id:
|
||||
ASCIIColors.info("Opening folder:")
|
||||
@ -197,6 +183,13 @@ async def open_file(file_path: FilePath):
|
||||
if lollmsElfServer.config.host=="0.0.0.0":
|
||||
return {"status":False,"error":"Open file is blocked when the server is exposed outside for very obvious reasons!"}
|
||||
|
||||
if lollmsElfServer.config.turn_on_open_file_validation:
|
||||
if not show_yes_no_dialog("Validation","Do you validate the opening of a file?"):
|
||||
return {"status":False,"error":"User refused the opeining file!"}
|
||||
|
||||
if(".." in path):
|
||||
raise "Detected an attempt of path traversal. Are you kidding me?"
|
||||
|
||||
try:
|
||||
# Validate the 'path' parameter
|
||||
path = file_path.path
|
||||
@ -235,6 +228,10 @@ async def open_code_in_vs_code(vs_code_data: VSCodeData):
|
||||
if lollmsElfServer.config.host=="0.0.0.0":
|
||||
return {"status":False,"error":"Open code in vs code is blocked when the server is exposed outside for very obvious reasons!"}
|
||||
|
||||
if lollmsElfServer.config.turn_on_open_file_validation:
|
||||
if not show_yes_no_dialog("Validation","Do you validate the opening of a code in vscode?"):
|
||||
return {"status":False,"error":"User refused the opeining file!"}
|
||||
|
||||
try:
|
||||
discussion_id = vs_code_data.discussion_id
|
||||
message_id = vs_code_data.message_id
|
||||
@ -275,6 +272,10 @@ async def open_code_folder(request: FolderRequest):
|
||||
if lollmsElfServer.config.host=="0.0.0.0":
|
||||
return {"status":False,"error":"Open code folder is blocked when the server is exposed outside for very obvious reasons!"}
|
||||
|
||||
if lollmsElfServer.config.turn_on_open_file_validation:
|
||||
if not show_yes_no_dialog("Validation","Do you validate the opening of a folder?"):
|
||||
return {"status":False,"error":"User refused the opeining folder!"}
|
||||
|
||||
try:
|
||||
if request.discussion_id:
|
||||
discussion_id = request.discussion_id
|
||||
|
@ -60,11 +60,14 @@ async def list_databases():
|
||||
|
||||
@router.post("/select_database")
|
||||
def select_database(data:DatabaseSelectionParameters):
|
||||
if(".." in data.name):
|
||||
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}')
|
||||
# Create database object
|
||||
lollmsElfServer.db = DiscussionsDB(lollmsElfServer.lollms_paths.personal_databases_path/data.name)
|
||||
lollmsElfServer.db = DiscussionsDB((lollmsElfServer.lollms_paths.personal_databases_path/data.name).resolve())
|
||||
ASCIIColors.info("Checking discussions database... ",end="")
|
||||
lollmsElfServer.db.create_tables()
|
||||
lollmsElfServer.db.add_missing_columns()
|
||||
|
@ -8,6 +8,7 @@ description:
|
||||
|
||||
"""
|
||||
from fastapi import APIRouter
|
||||
from pydantic import Field
|
||||
from lollms_webui import LOLLMSWebUI
|
||||
from pydantic import BaseModel
|
||||
from starlette.responses import StreamingResponse
|
||||
@ -25,55 +26,69 @@ router = APIRouter()
|
||||
lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance()
|
||||
|
||||
class EditMessageParameters(BaseModel):
|
||||
client_id :str
|
||||
id :int
|
||||
message :str
|
||||
metadata :dict
|
||||
client_id: str = Field(..., min_length=1)
|
||||
id: int = Field(..., gt=0)
|
||||
message: str = Field(..., min_length=1)
|
||||
metadata: dict = Field(default={})
|
||||
|
||||
@router.get("/edit_message")
|
||||
def edit_message(client_id:str,id:int, message:str,metadata:dict=None):
|
||||
message_id = id
|
||||
new_message = message
|
||||
metadata = metadata
|
||||
async def edit_message(edit_params: EditMessageParameters):
|
||||
client_id = edit_params.client_id
|
||||
message_id = edit_params.id
|
||||
new_message = edit_params.message
|
||||
metadata = edit_params.metadata
|
||||
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}
|
||||
except Exception as ex:
|
||||
trace_exception(ex)
|
||||
return {"status": False, "error":str(ex)}
|
||||
trace_exception(ex) # Assuming 'trace_exception' function logs the error
|
||||
return {"status": False, "error": "There was an error editing the message"}
|
||||
|
||||
|
||||
|
||||
class MessageRankParameters(BaseModel):
|
||||
client_id :str
|
||||
id :int
|
||||
|
||||
class MessageDeleteParameters(BaseModel):
|
||||
client_id :str
|
||||
id :int
|
||||
client_id: str = Field(..., min_length=1)
|
||||
id: int = Field(..., gt=0)
|
||||
|
||||
@router.get("/message_rank_up")
|
||||
def message_rank_up(client_id:str, id:int):
|
||||
discussion_id = id
|
||||
async def message_rank_up(rank_params: MessageRankParameters):
|
||||
client_id = rank_params.client_id
|
||||
discussion_id = rank_params.id
|
||||
|
||||
try:
|
||||
new_rank = lollmsElfServer.connections[client_id]["current_discussion"].message_rank_up(discussion_id)
|
||||
return {"status": True, "new_rank": new_rank}
|
||||
except Exception as ex:
|
||||
return {"status": False, "error":str(ex)}
|
||||
trace_exception(ex) # Assuming 'trace_exception' function logs the error
|
||||
return {"status": False, "error": "There was an error ranking up the message"}
|
||||
|
||||
|
||||
@router.get("/message_rank_down")
|
||||
def message_rank_down(client_id:str, id:int):
|
||||
discussion_id = id
|
||||
def message_rank_down(rank_params: MessageRankParameters):
|
||||
client_id = rank_params.client_id
|
||||
discussion_id = rank_params.id
|
||||
try:
|
||||
new_rank = lollmsElfServer.connections[client_id]["current_discussion"].message_rank_down(discussion_id)
|
||||
return {"status": True, "new_rank": new_rank}
|
||||
except Exception as ex:
|
||||
return {"status": False, "error":str(ex)}
|
||||
|
||||
class MessageDeleteParameters(BaseModel):
|
||||
client_id: str = Field(..., min_length=1)
|
||||
id: int = Field(..., gt=0)
|
||||
|
||||
@router.get("/delete_message")
|
||||
def delete_message(client_id:str, id:int):
|
||||
discussion_id = id
|
||||
async def delete_message(delete_params: MessageDeleteParameters):
|
||||
client_id = delete_params.client_id
|
||||
discussion_id = delete_params.id
|
||||
|
||||
if lollmsElfServer.connections[client_id]["current_discussion"] is None:
|
||||
return {"status": False,"message":"No discussion is selected"}
|
||||
else:
|
||||
new_rank = lollmsElfServer.connections[client_id]["current_discussion"].delete_message(discussion_id)
|
||||
ASCIIColors.yellow("Message deleted")
|
||||
return {"status":True,"new_rank": new_rank}
|
||||
try:
|
||||
new_rank = lollmsElfServer.connections[client_id]["current_discussion"].delete_message(discussion_id)
|
||||
ASCIIColors.yellow("Message deleted")
|
||||
return {"status":True,"new_rank": new_rank}
|
||||
except Exception as ex:
|
||||
trace_exception(ex) # Assuming 'trace_exception' function logs the error
|
||||
return {"status": False, "error": "There was an error deleting the message"}
|
||||
|
@ -8,8 +8,9 @@ description:
|
||||
|
||||
"""
|
||||
from fastapi import APIRouter, Request
|
||||
from fastapi import HTTPException
|
||||
from lollms_webui import LOLLMSWebUI
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, Field
|
||||
from starlette.responses import StreamingResponse
|
||||
from lollms.types import MSG_TYPE
|
||||
from lollms.main_config import BaseConfig
|
||||
@ -44,55 +45,75 @@ def get_presets():
|
||||
presets.append(preset)
|
||||
return presets
|
||||
|
||||
class PresetData(BaseModel):
|
||||
name: str = Field(..., min_length=1)
|
||||
|
||||
@router.post("/add_preset")
|
||||
async def add_preset(request: Request):
|
||||
async def add_preset(preset_data: PresetData):
|
||||
"""
|
||||
Changes current voice
|
||||
|
||||
:param request: The HTTP request object.
|
||||
:return: A JSON response with the status of the operation.
|
||||
"""
|
||||
# Get the JSON data from the POST request.
|
||||
preset_data = request.get_json()
|
||||
presets_folder = lollmsElfServer.lollms_paths.personal_databases_path/"lollms_playground_presets"
|
||||
if not presets_folder.exists():
|
||||
presets_folder.mkdir(exist_ok=True, parents=True)
|
||||
try:
|
||||
|
||||
fn = preset_data["name"].lower().replace(" ","_")
|
||||
filename = presets_folder/f"{fn}.yaml"
|
||||
with open(filename, 'w', encoding='utf-8') as file:
|
||||
yaml.dump(preset_data, file)
|
||||
return {"status": True}
|
||||
presets_folder = lollmsElfServer.lollms_paths.personal_databases_path/"lollms_playground_presets"
|
||||
if not presets_folder.exists():
|
||||
presets_folder.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
# Ensure the name doesn't contain any path manipulation characters
|
||||
if ".." in preset_data.name or "/" in preset_data.name:
|
||||
raise HTTPException(status_code=400, detail="Invalid preset name")
|
||||
|
||||
fn = preset_data.name.lower().replace(" ","_")
|
||||
filename = presets_folder/f"{fn}.yaml"
|
||||
with open(filename, 'w', encoding='utf-8') as file:
|
||||
yaml.dump(preset_data, file)
|
||||
return {"status": True}
|
||||
except Exception as ex:
|
||||
trace_exception(ex) # Assuming 'trace_exception' function logs the error
|
||||
return {"status": False, "error": "There was an error adding the preset"}
|
||||
|
||||
@router.post("/del_preset")
|
||||
async def del_preset(request: Request):
|
||||
async def del_preset(preset_data: PresetData):
|
||||
"""
|
||||
Saves a preset to a file.
|
||||
|
||||
:param request: The HTTP request object.
|
||||
:param preset_data: The data of the preset.
|
||||
:return: A JSON response with the status of the operation.
|
||||
"""
|
||||
# Get the JSON data from the POST request.
|
||||
preset_data = request.get_json()
|
||||
presets_folder = lollmsElfServer.lollms_paths.personal_databases_path/"lollms_playground_presets"
|
||||
# TODO : process
|
||||
return {"status":True}
|
||||
if preset_data.name is None:
|
||||
raise HTTPException(status_code=400, detail="Preset name is missing in the request")
|
||||
|
||||
# Ensure the name doesn't contain any path manipulation characters
|
||||
if ".." in preset_data.name or "/" in preset_data.name:
|
||||
raise HTTPException(status_code=400, detail="Invalid preset name")
|
||||
|
||||
presets_file = lollmsElfServer.lollms_paths.personal_databases_path/"lollms_playground_presets"/preset_data.name
|
||||
try:
|
||||
presets_file.unlink()
|
||||
return {"status":True}
|
||||
except:
|
||||
return {"status":False}
|
||||
|
||||
|
||||
@router.post("/save_presets")
|
||||
async def save_presets(request: Request):
|
||||
async def save_presets(preset_data: PresetData):
|
||||
"""
|
||||
Saves a preset to a file.
|
||||
|
||||
:param request: The HTTP request object.
|
||||
:param preset_data: The data of the preset.
|
||||
:return: A JSON response with the status of the operation.
|
||||
"""
|
||||
# Get the JSON data from the POST request.
|
||||
preset_data = request.get_json()
|
||||
if preset_data.preset is None:
|
||||
raise HTTPException(status_code=400, detail="Preset data is missing in the request")
|
||||
|
||||
presets_file = lollmsElfServer.lollms_paths.personal_databases_path/"presets.json"
|
||||
# Save the JSON data to a file.
|
||||
with open(presets_file, "w") as f:
|
||||
json.dump(preset_data, f, indent=4)
|
||||
json.dump(preset_data.preset, f, indent=4)
|
||||
|
||||
return {"status":True,"message":"Preset saved successfully!"}
|
@ -1 +1 @@
|
||||
Subproject commit 61c2f0ed2ad24c6125309650f0a58fad4a84c02a
|
||||
Subproject commit 8c40b159c546c0d9a2e09b1659207b3f78043115
|
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">
|
||||
<title>LoLLMS WebUI - Welcome</title>
|
||||
<script type="module" crossorigin src="/assets/index-19afe86a.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-015056f5.css">
|
||||
<script type="module" crossorigin src="/assets/index-458fe287.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-94163e69.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
@ -17,7 +17,8 @@
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@click="startRecording"
|
||||
title="Start audio to audio"
|
||||
@click="startRecordingAndTranscribing"
|
||||
:class="{ 'text-green-500': isLesteningToVoice }"
|
||||
class="w-6 hover:text-secondary duration-75 active:scale-90 cursor-pointer text-red-500"
|
||||
>
|
||||
@ -639,7 +640,8 @@ export default {
|
||||
// This event will be triggered when the voices are loaded
|
||||
this.voices = this.speechSynthesis.getVoices();
|
||||
},
|
||||
read(){
|
||||
read(){
|
||||
console.log("READING...")
|
||||
this.isSynthesizingVoice=true
|
||||
let ss =this.$refs.mdTextarea.selectionStart
|
||||
let se =this.$refs.mdTextarea.selectionEnd
|
||||
@ -864,8 +866,6 @@ export default {
|
||||
this.is_recording = true;
|
||||
this.pending = false;
|
||||
console.log(response.data)
|
||||
this.presets=response.data
|
||||
this.selectedPreset = this.presets[0]
|
||||
}).catch(ex=>{
|
||||
this.$refs.toast.showToast(`Error: ${ex}`,4,false)
|
||||
});
|
||||
@ -889,7 +889,7 @@ export default {
|
||||
},
|
||||
startRecordingAndTranscribing(){
|
||||
this.pending = true;
|
||||
if(!this.is_recording){
|
||||
if(!this.is_deaf_transcribing){
|
||||
axios.get('/start_recording').then(response => {
|
||||
this.is_deaf_transcribing = true;
|
||||
this.pending = false;
|
||||
|
@ -4669,6 +4669,7 @@ export default {
|
||||
try{
|
||||
let idx = this.$store.state.modelsZoo.findIndex(item => item.name == this.$store.state.selectedModel)
|
||||
if(idx>=0){
|
||||
console.log(`model avatar : ${this.$store.state.modelsZoo[idx].avatar}`)
|
||||
return this.$store.state.modelsZoo[idx].avatar
|
||||
}
|
||||
else{
|
||||
|
Loading…
x
Reference in New Issue
Block a user