From 3e6c5a1821dea7eb0f1da90db852d17eef175ffb Mon Sep 17 00:00:00 2001 From: feiloo <105425286+feiloo@users.noreply.github.com> Date: Fri, 20 Jun 2025 19:34:23 +0200 Subject: [PATCH 1/6] add initial export of Dexie/llamacpp webui --- .../webui/src/components/SettingDialog.tsx | 20 +++++++++++++++++++ tools/server/webui/src/utils/storage.ts | 6 ++++++ 2 files changed, 26 insertions(+) diff --git a/tools/server/webui/src/components/SettingDialog.tsx b/tools/server/webui/src/components/SettingDialog.tsx index 45a8d73b00592..37515352a0b6f 100644 --- a/tools/server/webui/src/components/SettingDialog.tsx +++ b/tools/server/webui/src/components/SettingDialog.tsx @@ -197,6 +197,26 @@ const SETTING_SECTIONS: SettingSection[] = [ ); }, }, + { + type: SettingInputType.CUSTOM, + key: 'custom', // dummy key, won't be used + component: () => { + const eexportDB = async () => { + const blob = await StorageUtils.export(); + const a = document.createElement('a'); + document.body.appendChild(a); + a.href = URL.createObjectURL(blob); + document.body.appendChild(a); + a.download = `aa_dump.json`; + a.click(); + }; + return ( + + ); + }, + }, { type: SettingInputType.CHECKBOX, label: 'Show tokens per second', diff --git a/tools/server/webui/src/utils/storage.ts b/tools/server/webui/src/utils/storage.ts index 505693e9272ac..208cae51d7dd9 100644 --- a/tools/server/webui/src/utils/storage.ts +++ b/tools/server/webui/src/utils/storage.ts @@ -4,6 +4,7 @@ import { CONFIG_DEFAULT } from '../Config'; import { Conversation, Message, TimingReport } from './types'; import Dexie, { Table } from 'dexie'; +import {importDB, exportDB, importInto, peakImportFile} from "dexie-export-import"; const event = new EventTarget(); @@ -35,6 +36,11 @@ const StorageUtils = { /** * manage conversations */ + async export() { + return await exportDB(db); + + }, + async getAllConversations(): Promise { await migrationLStoIDB().catch(console.error); // noop if already migrated return (await db.conversations.toArray()).sort( From 59adef25e709b93f1d42ef5a77eb57c0de74e8e4 Mon Sep 17 00:00:00 2001 From: feiloo <105425286+feiloo@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:14:38 +0200 Subject: [PATCH 2/6] add db importing --- .../webui/src/components/SettingDialog.tsx | 32 +++++++++++++++++-- tools/server/webui/src/utils/storage.ts | 10 +++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/tools/server/webui/src/components/SettingDialog.tsx b/tools/server/webui/src/components/SettingDialog.tsx index 37515352a0b6f..8a4fbb5013efd 100644 --- a/tools/server/webui/src/components/SettingDialog.tsx +++ b/tools/server/webui/src/components/SettingDialog.tsx @@ -201,7 +201,7 @@ const SETTING_SECTIONS: SettingSection[] = [ type: SettingInputType.CUSTOM, key: 'custom', // dummy key, won't be used component: () => { - const eexportDB = async () => { + const exportDB = async () => { const blob = await StorageUtils.export(); const a = document.createElement('a'); document.body.appendChild(a); @@ -209,14 +209,42 @@ const SETTING_SECTIONS: SettingSection[] = [ document.body.appendChild(a); a.download = `aa_dump.json`; a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); }; return ( - ); }, }, + { + type: SettingInputType.CUSTOM, + key: 'custom', // dummy key, won't be used + component: () => { + const importDB = async (e) => { + if (e.target.files.length != 1) throw new Error( + "Number of selected files for DB import must be 1 but was " + e.target.files.length + "."); + const file = e.target.files[0]; + try { + if (!file) throw new Error("No DB found to import."); + console.log("Importing DB " + file.name); + await StorageUtils.importDB(file, { + }); + console.log("Import complete"); + } catch (error) { + console.error(''+error); + } + }; + return ( +
+ + +
+ ); + }, + }, { type: SettingInputType.CHECKBOX, label: 'Show tokens per second', diff --git a/tools/server/webui/src/utils/storage.ts b/tools/server/webui/src/utils/storage.ts index 208cae51d7dd9..3f2ddc347b611 100644 --- a/tools/server/webui/src/utils/storage.ts +++ b/tools/server/webui/src/utils/storage.ts @@ -37,10 +37,18 @@ const StorageUtils = { * manage conversations */ async export() { - return await exportDB(db); + return await exportDB(db); }, + async importDB(file, callback) { + return db.delete().then(() => { + db.open().then(() => { + db.import(file,callback); + }) + }); + }, + async getAllConversations(): Promise { await migrationLStoIDB().catch(console.error); // noop if already migrated return (await db.conversations.toArray()).sort( From 2d0f618ba11726158119bf025d1c8ca479426820 Mon Sep 17 00:00:00 2001 From: feiloo <105425286+feiloo@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:33:39 +0200 Subject: [PATCH 3/6] reload after importing DB to show all imported conversations --- tools/server/webui/src/components/SettingDialog.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/server/webui/src/components/SettingDialog.tsx b/tools/server/webui/src/components/SettingDialog.tsx index 8a4fbb5013efd..4cb54700f9fd4 100644 --- a/tools/server/webui/src/components/SettingDialog.tsx +++ b/tools/server/webui/src/components/SettingDialog.tsx @@ -236,6 +236,8 @@ const SETTING_SECTIONS: SettingSection[] = [ } catch (error) { console.error(''+error); } + + window.location.reload(); }; return (
From 8f22425f9d14a1c61d368821b6fd0401bda40021 Mon Sep 17 00:00:00 2001 From: feiloo <105425286+feiloo@users.noreply.github.com> Date: Mon, 23 Jun 2025 18:05:48 +0200 Subject: [PATCH 4/6] fix reload asynchronicity --- .../webui/src/components/SettingDialog.tsx | 54 +++++++++++++------ tools/server/webui/src/utils/storage.ts | 14 +++-- 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/tools/server/webui/src/components/SettingDialog.tsx b/tools/server/webui/src/components/SettingDialog.tsx index 4cb54700f9fd4..89fdb04a83e07 100644 --- a/tools/server/webui/src/components/SettingDialog.tsx +++ b/tools/server/webui/src/components/SettingDialog.tsx @@ -210,7 +210,6 @@ const SETTING_SECTIONS: SettingSection[] = [ a.download = `aa_dump.json`; a.click(); document.body.removeChild(a); - URL.revokeObjectURL(url); }; return (