Ver Fonte

feat: chat export

Timothy J. Baek há 1 ano atrás
pai
commit
4221594778

+ 5 - 2
backend/apps/web/main.py

@@ -1,7 +1,7 @@
 from fastapi import FastAPI, Request, Depends, HTTPException
 from fastapi import FastAPI, Request, Depends, HTTPException
 from fastapi.middleware.cors import CORSMiddleware
 from fastapi.middleware.cors import CORSMiddleware
 
 
-from apps.web.routers import auths, users, chats, utils
+from apps.web.routers import auths, users, chats, modelfiles, utils
 from config import WEBUI_VERSION, WEBUI_AUTH
 from config import WEBUI_VERSION, WEBUI_AUTH
 
 
 app = FastAPI()
 app = FastAPI()
@@ -19,8 +19,11 @@ app.add_middleware(
 
 
 app.include_router(auths.router, prefix="/auths", tags=["auths"])
 app.include_router(auths.router, prefix="/auths", tags=["auths"])
 app.include_router(users.router, prefix="/users", tags=["users"])
 app.include_router(users.router, prefix="/users", tags=["users"])
-app.include_router(utils.router, prefix="/utils", tags=["utils"])
 app.include_router(chats.router, prefix="/chats", tags=["chats"])
 app.include_router(chats.router, prefix="/chats", tags=["chats"])
+app.include_router(modelfiles.router, prefix="/modelfiles", tags=["modelfiles"])
+
+
+app.include_router(utils.router, prefix="/utils", tags=["utils"])
 
 
 
 
 @app.get("/")
 @app.get("/")

+ 8 - 0
backend/apps/web/models/chats.py

@@ -123,6 +123,14 @@ class ChatTable:
             # .offset(skip)
             # .offset(skip)
         ]
         ]
 
 
+    def get_all_chats_by_user_id(self, user_id: str) -> List[ChatModel]:
+        return [
+            ChatModel(**model_to_dict(chat))
+            for chat in Chat.select()
+            .where(Chat.user_id == user_id)
+            .order_by(Chat.timestamp.desc())
+        ]
+
     def get_chat_by_id_and_user_id(self, id: str, user_id: str) -> Optional[ChatModel]:
     def get_chat_by_id_and_user_id(self, id: str, user_id: str) -> Optional[ChatModel]:
         try:
         try:
             chat = Chat.get(Chat.id == id, Chat.user_id == user_id)
             chat = Chat.get(Chat.id == id, Chat.user_id == user_id)

+ 22 - 0
backend/apps/web/routers/chats.py

@@ -43,6 +43,28 @@ async def get_user_chats(skip: int = 0, limit: int = 50, cred=Depends(bearer_sch
         )
         )
 
 
 
 
+############################
+# GetAllChats
+############################
+
+
+@router.get("/all", response_model=List[ChatResponse])
+async def get_all_user_chats(cred=Depends(bearer_scheme)):
+    token = cred.credentials
+    user = Users.get_user_by_token(token)
+
+    if user:
+        return [
+            ChatResponse(**{**chat.model_dump(), "chat": json.loads(chat.chat)})
+            for chat in Chats.get_all_chats_by_user_id(user.id)
+        ]
+    else:
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail=ERROR_MESSAGES.INVALID_TOKEN,
+        )
+
+
 ############################
 ############################
 # CreateNewChat
 # CreateNewChat
 ############################
 ############################

+ 31 - 0
src/lib/apis/chats/index.ts

@@ -62,6 +62,37 @@ export const getChatList = async (token: string = '') => {
 	return res;
 	return res;
 };
 };
 
 
+export const getAllChats = async (token: string) => {
+	let error = null;
+
+	const res = await fetch(`${WEBUI_API_BASE_URL}/chats/all`, {
+		method: 'GET',
+		headers: {
+			Accept: 'application/json',
+			'Content-Type': 'application/json',
+			...(token && { authorization: `Bearer ${token}` })
+		}
+	})
+		.then(async (res) => {
+			if (!res.ok) throw await res.json();
+			return res.json();
+		})
+		.then((json) => {
+			return json;
+		})
+		.catch((err) => {
+			error = err;
+			console.log(err);
+			return null;
+		});
+
+	if (error) {
+		throw error;
+	}
+
+	return res;
+};
+
 export const getChatById = async (token: string, id: string) => {
 export const getChatById = async (token: string, id: string) => {
 	let error = null;
 	let error = null;
 
 

+ 15 - 9
src/lib/components/chat/SettingsModal.svelte

@@ -1,20 +1,23 @@
 <script lang="ts">
 <script lang="ts">
-	import Modal from '../common/Modal.svelte';
+	import toast from 'svelte-french-toast';
+	import fileSaver from 'file-saver';
+	const { saveAs } = fileSaver;
+
+	import { onMount } from 'svelte';
+	import { config, models, settings, user, chats } from '$lib/stores';
+	import { splitStream, getGravatarURL } from '$lib/utils';
 
 
+	import { getOllamaVersion } from '$lib/apis/ollama';
+	import { createNewChat, getAllChats, getChatList } from '$lib/apis/chats';
 	import {
 	import {
 		WEB_UI_VERSION,
 		WEB_UI_VERSION,
 		OLLAMA_API_BASE_URL,
 		OLLAMA_API_BASE_URL,
 		WEBUI_API_BASE_URL,
 		WEBUI_API_BASE_URL,
 		WEBUI_BASE_URL
 		WEBUI_BASE_URL
 	} from '$lib/constants';
 	} from '$lib/constants';
-	import toast from 'svelte-french-toast';
-	import { onMount } from 'svelte';
-	import { config, models, settings, user, chats } from '$lib/stores';
-	import { splitStream, getGravatarURL } from '$lib/utils';
+
 	import Advanced from './Settings/Advanced.svelte';
 	import Advanced from './Settings/Advanced.svelte';
-	import { stringify } from 'postcss';
-	import { getOllamaVersion } from '$lib/apis/ollama';
-	import { createNewChat, getChatList } from '$lib/apis/chats';
+	import Modal from '../common/Modal.svelte';
 
 
 	export let show = false;
 	export let show = false;
 
 
@@ -91,7 +94,10 @@
 	};
 	};
 
 
 	const exportChats = async () => {
 	const exportChats = async () => {
-		console.log('TODO: export all chats');
+		let blob = new Blob([JSON.stringify(await getAllChats(localStorage.token))], {
+			type: 'application/json'
+		});
+		saveAs(blob, `chat-export-${Date.now()}.json`);
 	};
 	};
 
 
 	$: if (importFiles) {
 	$: if (importFiles) {