mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2025-02-05 02:19:16 +00:00
upgraded datra management ui
This commit is contained in:
parent
53d8530ace
commit
afd2096d15
17
web/dist/assets/index-BkRL-g00.css
vendored
Normal file
17
web/dist/assets/index-BkRL-g00.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
17
web/dist/assets/index-zuZ7rDcs.css
vendored
17
web/dist/assets/index-zuZ7rDcs.css
vendored
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 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
|
||||||
<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</title>
|
<title>LoLLMS WebUI</title>
|
||||||
<script type="module" crossorigin src="/assets/index-B_kgz78p.js"></script>
|
<script type="module" crossorigin src="/assets/index-CsOg18Ru.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-zuZ7rDcs.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-BkRL-g00.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
@ -1358,7 +1358,44 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-center" :key="index">
|
||||||
|
<div class="relative mr-2">
|
||||||
|
<button
|
||||||
|
@click="toggleStatus(index)"
|
||||||
|
class="flex items-center space-x-1"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:class="[
|
||||||
|
'w-3 h-3 rounded-full',
|
||||||
|
getStatusColor(index)
|
||||||
|
]"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
v-if="expandedStatusIndex === index"
|
||||||
|
class="absolute left-5 top-0 bg-white shadow-lg rounded-md p-2 z-10 text-sm"
|
||||||
|
>
|
||||||
|
<div v-if="serverStatuses[index]">
|
||||||
|
<p>Status: {{ serverStatuses[index].status }}</p>
|
||||||
|
<p>Indexed Files: {{ serverStatuses[index].indexed_files_count }}</p>
|
||||||
|
<p>Model: {{ serverStatuses[index].configuration?.llm_model }}</p>
|
||||||
|
</div>
|
||||||
|
<p v-else>No status available</p>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
v-if="source.type === 'lightrag'"
|
||||||
|
@click="checkLightRagServerHealth(index)"
|
||||||
|
class="inline-flex items-center px-3 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
||||||
|
title="Check LightRAG server health"
|
||||||
|
>
|
||||||
|
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||||||
|
</svg>
|
||||||
|
LightRAG Status
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<!-- Actions Row -->
|
<!-- Actions Row -->
|
||||||
<div class="flex items-center justify-between mt-4 pt-3 border-t border-gray-200 dark:border-gray-700">
|
<div class="flex items-center justify-between mt-4 pt-3 border-t border-gray-200 dark:border-gray-700">
|
||||||
<div class="flex items-center space-x-4">
|
<div class="flex items-center space-x-4">
|
||||||
@ -1404,7 +1441,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
Select work Folder
|
Select work Folder
|
||||||
</button>
|
</button>
|
||||||
|
<!-- Health Check Button for LightRAG -->
|
||||||
<button @click="removeServedDataBase(index)"
|
<button @click="removeServedDataBase(index)"
|
||||||
class="inline-flex items-center px-3 py-2 text-sm font-medium text-white bg-red-600 rounded-md hover:bg-red-700 focus:ring-2 focus:ring-offset-2 focus:ring-red-500">
|
class="inline-flex items-center px-3 py-2 text-sm font-medium text-white bg-red-600 rounded-md hover:bg-red-700 focus:ring-2 focus:ring-offset-2 focus:ring-red-500">
|
||||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
@ -4365,7 +4402,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="settingsChanged"
|
<div v-if="settingsChanged"
|
||||||
class="fixed bottom-4 right-4 z-50 bg-white dark:bg-gray-800 shadow-lg rounded-lg p-4 flex gap-3 items-center border border-gray-200 dark:border-gray-700">
|
class="fixed bottom-4 right-4 z-50 bg-white dark:bg-gray-800 shadow-lg rounded-lg p-4 flex flex-col gap-2 border border-gray-200 dark:border-gray-700">
|
||||||
|
<!-- Status Message -->
|
||||||
|
<div class="flex items-center gap-2 text-amber-600 dark:text-amber-400">
|
||||||
|
<i data-feather="alert-circle" class="w-4 h-4"></i>
|
||||||
|
<span class="text-sm font-medium">Settings have been modified</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Action Buttons -->
|
||||||
<div v-if="!isLoading" class="flex items-center gap-2">
|
<div v-if="!isLoading" class="flex items-center gap-2">
|
||||||
<button class="flex items-center gap-2 px-3 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 duration-75 active:scale-95"
|
<button class="flex items-center gap-2 px-3 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 duration-75 active:scale-95"
|
||||||
title="Apply changes"
|
title="Apply changes"
|
||||||
@ -4539,10 +4583,13 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
||||||
posts_headers : {
|
posts_headers : {
|
||||||
'accept': 'application/json',
|
'accept': 'application/json',
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
|
serverStatuses: {}, // Object to store status for each server
|
||||||
|
expandedStatusIndex: null, // Track which status panel is expanded
|
||||||
isUploading: false,
|
isUploading: false,
|
||||||
defaultModelImgPlaceholder:defaultModelImgPlaceholder,
|
defaultModelImgPlaceholder:defaultModelImgPlaceholder,
|
||||||
snd_input_devices: [],
|
snd_input_devices: [],
|
||||||
@ -4669,43 +4716,185 @@ export default {
|
|||||||
//await socket.on('install_progress', this.progressListener);
|
//await socket.on('install_progress', this.progressListener);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
triggerFileInput() {
|
async checkLightRagServerHealth(index) {
|
||||||
this.$refs.fileInput.click()
|
try {
|
||||||
|
const source = this.configFile.datalakes[index];
|
||||||
|
const headers = source.key ? { 'X-API-Key': source.key } : {};
|
||||||
|
|
||||||
|
const response = await fetch(`${source.url.replace(/\/+$/, '')}/health`, { headers });
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
// Update status for this specific server
|
||||||
|
this.serverStatuses[index]= {
|
||||||
|
status: 'healthy',
|
||||||
|
indexed_files_count: data.indexed_files_count,
|
||||||
|
configuration: data.configuration
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$store.state.toast.showToast(
|
||||||
|
`Healthy | ${data.indexed_files_count} files indexed | Model: ${data.configuration.llm_model}`,
|
||||||
|
4,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
// Update status for this specific server on error
|
||||||
|
this.serverStatuses[index]= {
|
||||||
|
status: 'unhealthy'
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$store.state.toast.showToast('Could not connect to LightRAG server', 4, false);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async handleFileUpload(event) {
|
|
||||||
const files = event.target.files
|
|
||||||
if (!files.length) return
|
|
||||||
|
|
||||||
this.isUploading = true
|
// Optional: Method to check all servers at once
|
||||||
const formData = new FormData()
|
async checkAllServers() {
|
||||||
|
for (let i = 0; i < this.configFile.datalakes.length; i++) {
|
||||||
|
if (this.configFile.datalakes[i].type === 'lightrag') {
|
||||||
|
await this.checkLightRagServerHealth(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Add database name
|
async uploadFilesToLightRag(index, files) {
|
||||||
formData.append('database_name', this.databaseName)
|
const source = this.configFile.datalakes[index];
|
||||||
|
const headers = source.key ? { 'X-API-Key': source.key } : {};
|
||||||
|
|
||||||
// Add all files
|
for (const file of files) {
|
||||||
Array.from(files).forEach(file => {
|
const formData = new FormData();
|
||||||
formData.append('files', file)
|
formData.append('file', file);
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.post('/upload_files_2_rag_db', formData, {
|
const response = await fetch(`${source.url}/documents/upload`, {
|
||||||
headers: {
|
method: 'POST',
|
||||||
'Content-Type': 'multipart/form-data'
|
headers,
|
||||||
},
|
body: formData
|
||||||
onUploadProgress: (progressEvent) => {
|
});
|
||||||
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
|
|
||||||
this.$emit('upload-progress', percentCompleted)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
this.$emit('upload-success', response.data)
|
const result = await response.json();
|
||||||
|
this.$emit('show-notification', {
|
||||||
|
title: 'LightRAG Upload Success',
|
||||||
|
message: `${file.name} uploaded successfully`,
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Upload failed:', error)
|
this.$emit('show-notification', {
|
||||||
this.$emit('upload-error', error)
|
title: 'LightRAG Upload Error',
|
||||||
} finally {
|
message: `Failed to upload ${file.name}: ${error.message}`,
|
||||||
this.isUploading = false
|
type: 'error'
|
||||||
event.target.value = ''
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async handleFileUpload(event, index) {
|
||||||
|
const files = Array.from(event.target.files);
|
||||||
|
const source = this.configFile.datalakes[index];
|
||||||
|
|
||||||
|
const supportedExtensions = {
|
||||||
|
lightrag: ['.txt', '.md', '.pdf', '.docx', '.pptx', '.xlsx'],
|
||||||
|
lollmsvectordb: [".sh",
|
||||||
|
".json",
|
||||||
|
".sym",
|
||||||
|
".log",
|
||||||
|
".snippet",
|
||||||
|
".se",
|
||||||
|
".yml",
|
||||||
|
".snippets",
|
||||||
|
".lua",
|
||||||
|
".pdf",
|
||||||
|
".md",
|
||||||
|
".docx",
|
||||||
|
".xlsx",
|
||||||
|
".png",
|
||||||
|
".bmp",
|
||||||
|
".jpg",
|
||||||
|
".yaml",
|
||||||
|
".inc",
|
||||||
|
".txt",
|
||||||
|
".ini",
|
||||||
|
".pas",
|
||||||
|
".pptx",
|
||||||
|
".map",
|
||||||
|
".php",
|
||||||
|
".xlsx",
|
||||||
|
".rtf",
|
||||||
|
".hpp",
|
||||||
|
".h",
|
||||||
|
".asm",
|
||||||
|
".xml",
|
||||||
|
".hh",
|
||||||
|
".sql",
|
||||||
|
".java",
|
||||||
|
".c",
|
||||||
|
".html",
|
||||||
|
".inf",
|
||||||
|
".rb",
|
||||||
|
".py",
|
||||||
|
".cs",
|
||||||
|
".js",
|
||||||
|
".bat",
|
||||||
|
".css",
|
||||||
|
".s",
|
||||||
|
".cpp",
|
||||||
|
".csv",
|
||||||
|
".msg"
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const validFiles = files.filter(file => {
|
||||||
|
const ext = '.' + file.name.split('.').pop().toLowerCase();
|
||||||
|
return supportedExtensions[source.type].includes(ext);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (validFiles.length !== files.length) {
|
||||||
|
this.$emit('show-notification', {
|
||||||
|
title: 'Warning',
|
||||||
|
message: 'Some files were skipped due to unsupported format',
|
||||||
|
type: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source.type === 'lightrag') {
|
||||||
|
await this.uploadFilesToLightRag(index, validFiles);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (!files.length) return
|
||||||
|
|
||||||
|
this.isUploading = true
|
||||||
|
const formData = new FormData()
|
||||||
|
|
||||||
|
// Add database name
|
||||||
|
formData.append('database_name', this.databaseName)
|
||||||
|
|
||||||
|
// Add all files
|
||||||
|
Array.from(files).forEach(file => {
|
||||||
|
formData.append('files', file)
|
||||||
|
})
|
||||||
|
const response = await axios.post('/upload_files_2_rag_db', formData, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
},
|
||||||
|
onUploadProgress: (progressEvent) => {
|
||||||
|
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
|
||||||
|
this.$emit('upload-progress', percentCompleted)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$emit('upload-success', response.data)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Upload failed:', error)
|
||||||
|
this.$emit('upload-error', error)
|
||||||
|
} finally {
|
||||||
|
this.isUploading = false
|
||||||
|
event.target.value = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
triggerFileInput() {
|
||||||
|
this.$refs.fileInput.click()
|
||||||
},
|
},
|
||||||
updateRagDatabase(index, value, field) {
|
updateRagDatabase(index, value, field) {
|
||||||
if (field) {
|
if (field) {
|
||||||
@ -6953,6 +7142,14 @@ export default {
|
|||||||
//this.load_everything()
|
//this.load_everything()
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
getStatusColor() {
|
||||||
|
return (index) => {
|
||||||
|
const status = this.serverStatuses[index]
|
||||||
|
if (!status) return 'bg-gray-400' // Unknown status
|
||||||
|
if (status.status === 'healthy') return 'bg-green-500' // Healthy
|
||||||
|
return 'bg-red-500' // Unhealthy
|
||||||
|
}
|
||||||
|
},
|
||||||
full_template:{
|
full_template:{
|
||||||
get(){
|
get(){
|
||||||
return (this.configFile.start_header_id_template+this.configFile.system_message_template+this.configFile.end_header_id_template+" system message"+this.configFile.separator_template+this.configFile.start_user_header_id_template+"user name"+this.configFile.end_user_header_id_template+" User prompt"+this.configFile.separator_template+this.configFile.end_user_message_id_template+this.configFile.separator_template+this.configFile.start_ai_header_id_template+"ai personality"+this.configFile.end_ai_header_id_template+"ai response"+this.configFile.end_ai_message_id_template).replace("\n","<br>")
|
return (this.configFile.start_header_id_template+this.configFile.system_message_template+this.configFile.end_header_id_template+" system message"+this.configFile.separator_template+this.configFile.start_user_header_id_template+"user name"+this.configFile.end_user_header_id_template+" User prompt"+this.configFile.separator_template+this.configFile.end_user_message_id_template+this.configFile.separator_template+this.configFile.start_ai_header_id_template+"ai personality"+this.configFile.end_ai_header_id_template+"ai response"+this.configFile.end_ai_message_id_template).replace("\n","<br>")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user