diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml deleted file mode 100644 index 8e68d46c..00000000 --- a/.github/workflows/docker.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: Docker Build and Lint - -on: - push: - branches: - - main - pull_request: - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Build Docker Image - uses: docker/build-push-action@v5 - with: - context: . - push: false - tags: lollms-webui:latest - - lint: - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Run Hadolint - run: | - docker run --rm -i -v $PWD/.hadolint.yaml:/.config/hadolint.yaml hadolint/hadolint < Dockerfile diff --git a/.github/workflows/rsync.yml b/.github/workflows/rsync.yml deleted file mode 100644 index 38f78a07..00000000 --- a/.github/workflows/rsync.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Upstream Sync - -permissions: - contents: write - -on: - schedule: - - cron: "0 0 * * *" # every day - workflow_dispatch: - -jobs: - sync_latest_from_upstream: - name: Sync latest commits from upstream repo - runs-on: ubuntu-latest - if: ${{ github.event.repository.fork }} - - steps: - # Step 1: run a standard checkout action - - name: Checkout target repo - uses: actions/checkout@v4 - - # Step 2: run the sync action - - name: Sync upstream changes - id: sync - uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 - with: - upstream_sync_repo: ParisNeo/lollms-webui - upstream_sync_branch: main - target_sync_branch: main - target_repo_token: ${{ secrets.GITHUB_TOKEN }} # automatically generated, no need to set - - # Set test_mode true to run tests instead of the true action!! - test_mode: false - - - name: Sync check - if: failure() - run: | - echo "::error::Synchronization failed due to insufficient permissions (this is the expected behavior), please go to the warehouse homepage to execute manually[Sync fork]。" - echo "::error::Due to insufficient permissions, synchronization failed (as expected). Please go to the repository homepage and manually perform [Sync fork]." - exit 1 diff --git a/app.py b/app.py index 0ff68c54..7e9689e2 100644 --- a/app.py +++ b/app.py @@ -303,8 +303,6 @@ try: self.add_endpoint("/get_current_personality_path_infos", "get_current_personality_path_infos", self.get_current_personality_path_infos, methods=["GET"]) - self.add_endpoint("/list_databases", "list_databases", self.list_databases, methods=["GET"]) - self.add_endpoint("/select_database", "select_database", self.select_database, methods=["POST"]) self.add_endpoint("/uploads/", "serve_uploads", self.serve_uploads, methods=["GET"]) @@ -334,9 +332,17 @@ try: self.add_endpoint("/list_discussions", "list_discussions", self.list_discussions, methods=["GET"]) - + self.add_endpoint("/export_discussion", "export_discussion", self.export_discussion, methods=["GET"]) + self.add_endpoint("/list_databases", "list_databases", self.list_databases, methods=["GET"]) + self.add_endpoint("/select_database", "select_database", self.select_database, methods=["POST"]) + self.add_endpoint("/rename_discussion", "rename_discussion", self.rename_discussion, methods=["POST"]) + self.add_endpoint("/delete_discussion","delete_discussion",self.delete_discussion,methods=["POST"]) + self.add_endpoint("/edit_title", "edit_title", self.edit_title, methods=["POST"]) + self.add_endpoint("/make_title", "make_title", self.make_title, methods=["POST"]) + self.add_endpoint("/export", "export", self.export, methods=["GET"]) self.add_endpoint("/get_generation_status", "get_generation_status", self.get_generation_status, methods=["GET"]) + self.add_endpoint("/stop_gen", "stop_gen", self.stop_gen, methods=["GET"]) self.add_endpoint("/", "", self.index, methods=["GET"]) @@ -344,12 +350,22 @@ try: self.add_endpoint("/playground/", "", self.index, methods=["GET"]) + self.add_endpoint("/switch_personal_path", "switch_personal_path", self.switch_personal_path, methods=["POST"]) + self.add_endpoint("/upload_avatar", "upload_avatar", self.upload_avatar, methods=["POST"]) + + + + self.add_endpoint("/edit_message", "edit_message", self.edit_message, methods=["GET"]) + self.add_endpoint("/message_rank_up", "message_rank_up", self.message_rank_up, methods=["GET"]) + self.add_endpoint("/message_rank_down", "message_rank_down", self.message_rank_down, methods=["GET"]) + self.add_endpoint("/delete_message", "delete_message", self.delete_message, methods=["GET"]) + + + # ---- - self.add_endpoint("/switch_personal_path", "switch_personal_path", self.switch_personal_path, methods=["POST"]) - self.add_endpoint("/upload_avatar", "upload_avatar", self.upload_avatar, methods=["POST"]) @@ -364,29 +380,13 @@ try: - self.add_endpoint("/export_discussion", "export_discussion", self.export_discussion, methods=["GET"]) - self.add_endpoint("/export", "export", self.export, methods=["GET"]) - self.add_endpoint("/stop_gen", "stop_gen", self.stop_gen, methods=["GET"]) - self.add_endpoint("/rename", "rename", self.rename, methods=["POST"]) - self.add_endpoint("/edit_title", "edit_title", self.edit_title, methods=["POST"]) - self.add_endpoint("/make_title", "make_title", self.make_title, methods=["POST"]) self.add_endpoint("/get_server_address", "get_server_address", self.get_server_address, methods=["GET"]) - self.add_endpoint( - "/delete_discussion", - "delete_discussion", - self.delete_discussion, - methods=["POST"], - ) - self.add_endpoint("/edit_message", "edit_message", self.edit_message, methods=["GET"]) - self.add_endpoint("/message_rank_up", "message_rank_up", self.message_rank_up, methods=["GET"]) - self.add_endpoint("/message_rank_down", "message_rank_down", self.message_rank_down, methods=["GET"]) - self.add_endpoint("/delete_message", "delete_message", self.delete_message, methods=["GET"]) self.add_endpoint("/get_config", "get_config", self.get_config, methods=["GET"]) @@ -2431,12 +2431,12 @@ try: - def rename(self): + def rename_discussion(self): data = request.get_json() client_id = data["client_id"] title = data["title"] self.connections[client_id]["current_discussion"].rename(title) - return "renamed successfully" + return {"status":True} def edit_title(self): data = request.get_json() diff --git a/endpoints/lollms_discussion.py b/endpoints/lollms_discussion.py index a88c47de..e9d9bd90 100644 --- a/endpoints/lollms_discussion.py +++ b/endpoints/lollms_discussion.py @@ -14,7 +14,7 @@ from starlette.responses import StreamingResponse from lollms.types import MSG_TYPE from lollms.utilities import detect_antiprompt, remove_text_from_string from ascii_colors import ASCIIColors -from api.db import DiscussionsDB +from api.db import DiscussionsDB, Discussion from safe_store.text_vectorizer import TextVectorizer, VectorizationMethod, VisualizationMethod import tqdm @@ -25,8 +25,21 @@ class GenerateRequest(BaseModel): class DatabaseSelectionParameters(BaseModel): name: str +class EditTitleParameters(BaseModel): + client_id: str + title: str + id: int + +class MakeTitleParameters(BaseModel): + id: int + +class DeleteDiscussionParameters(BaseModel): + client_id: str + id: int + + router = APIRouter() -lollmsElfServer = LOLLMSWebUI.get_instance() +lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance() @router.get("/list_discussions") @@ -93,3 +106,41 @@ def select_database(data:DatabaseSelectionParameters): return {"status":False} return {"status":True} + + +@router.post("/export_discussion") +def export_discussion(): + return {"discussion_text":lollmsElfServer.get_discussion_to()} + + +@router.post("/edit_title") +def edit_title(data:EditTitleParameters): + client_id = data.client_id + title = data.title + discussion_id = data.id + lollmsElfServer.connections[client_id]["current_discussion"] = Discussion(discussion_id, lollmsElfServer.db) + lollmsElfServer.connections[client_id]["current_discussion"].rename(title) + return {'status':True} + +@router.post("/make_title") +def make_title(data:MakeTitleParameters): + ASCIIColors.info("Making title") + discussion_id = data.id + discussion = Discussion(discussion_id, lollmsElfServer.db) + title = lollmsElfServer.make_discussion_title(discussion) + discussion.rename(title) + return {'status':True, 'title':title} + +@router.get("/export") +def export(): + return lollmsElfServer.db.export_to_json() + + +@router.post("/make_title") +def delete_discussion(data: DeleteDiscussionParameters): + client_id = data.client_id + discussion_id = data.id + lollmsElfServer.connections[client_id]["current_discussion"] = Discussion(discussion_id, lollmsElfServer.db) + lollmsElfServer.connections[client_id]["current_discussion"].delete_discussion() + lollmsElfServer.connections[client_id]["current_discussion"] = None + return {'status':True} \ No newline at end of file diff --git a/endpoints/lollms_message.py b/endpoints/lollms_message.py index 949533c6..9c79da1b 100644 --- a/endpoints/lollms_message.py +++ b/endpoints/lollms_message.py @@ -12,7 +12,7 @@ from lollms_webui import LOLLMSWebUI from pydantic import BaseModel from starlette.responses import StreamingResponse from lollms.types import MSG_TYPE -from lollms.utilities import detect_antiprompt, remove_text_from_string +from lollms.utilities import detect_antiprompt, remove_text_from_string, trace_exception from ascii_colors import ASCIIColors from api.db import DiscussionsDB @@ -21,5 +21,58 @@ import tqdm router = APIRouter() -lollmsElfServer = LOLLMSWebUI.get_instance() +lollmsElfServer:LOLLMSWebUI = LOLLMSWebUI.get_instance() +class EditMessageParameters(BaseModel): + client_id :str + id :int + message :str + metadata :dict + +@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 + try: + 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)} + +class MessageRankParameters(BaseModel): + client_id :str + id :int + +class MessageDeleteParameters(BaseModel): + client_id :str + id :int + +@router.get("/message_rank_up") +def message_rank_up(client_id:str, id:int): + discussion_id = 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)} + +@router.get("/message_rank_down") +def message_rank_down(client_id:str, id:int): + discussion_id = 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)} + +@router.get("/delete_message") +def delete_message(client_id:str, id:int): + discussion_id = 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} diff --git a/endpoints/lollms_user.py b/endpoints/lollms_user.py index 902a3a95..7012f09a 100644 --- a/endpoints/lollms_user.py +++ b/endpoints/lollms_user.py @@ -19,7 +19,8 @@ from api.db import DiscussionsDB from pathlib import Path from safe_store.text_vectorizer import TextVectorizer, VectorizationMethod, VisualizationMethod import tqdm - +from fastapi import FastAPI, UploadFile, File +import shutil class PersonalPathParameters(BaseModel): path:str @@ -42,7 +43,7 @@ def switch_personal_path(data:PersonalPathParameters): return {"status": False, 'error':f"Couldn't switch path: {ex}"} @router.post("/upload_avatar") -def upload_avatar(data): - file = data.files['avatar'] - file.save(lollmsElfServer.lollms_paths.personal_user_infos_path/file.filename) - return {"status": True,"fileName":file.filename} \ No newline at end of file +def upload_avatar(avatar: UploadFile = File(...)): + with open(lollmsElfServer.lollms_paths.personal_user_infos_path/avatar.filename, "wb") as buffer: + shutil.copyfileobj(avatar.file, buffer) + return {"status": True,"fileName":avatar.filename} diff --git a/lollms_core b/lollms_core index 4ef9f5d7..310eafa0 160000 --- a/lollms_core +++ b/lollms_core @@ -1 +1 @@ -Subproject commit 4ef9f5d72c3b9a8af1ec2caea52e203191feb9c4 +Subproject commit 310eafa0abd54e1e9cd5c5c49a3b26a312dd95cb diff --git a/new_app.py b/new_app.py index c23f57ab..1c70a08a 100644 --- a/new_app.py +++ b/new_app.py @@ -101,8 +101,10 @@ if __name__ == "__main__": lollms_webui_generation_events_add(sio) lollms_webui_discussion_events_add(sio) - app.mount("/", StaticFiles(directory=Path(__file__).parent/"web"/"dist", html=True), name="static") + app.mount("/playground", StaticFiles(directory=Path(__file__).parent/"web"/"dist", html=True), name="playground") + app.mount("/settings", StaticFiles(directory=Path(__file__).parent/"web"/"dist", html=True), name="settings") + app.mount("/", StaticFiles(directory=Path(__file__).parent/"web"/"dist", html=True), name="static") app = ASGIApp(socketio_server=sio, other_asgi_app=app)