From 2d507c0bcf644e142a8384ce1a78367553b91bfe Mon Sep 17 00:00:00 2001 From: aylvn Date: Mon, 17 Mar 2025 23:15:14 +0800 Subject: [PATCH] Desktop client reads llm configuration from the config/config.toml file --- desktop/app.go | 15 + desktop/frontend/src/assets/js/files.js | 325 +++++++++++----------- desktop/frontend/src/assets/js/utils.js | 9 + desktop/frontend/src/views/config/Llm.vue | 193 ++++++++++++- desktop/frontend/wailsjs/go/main/App.d.ts | 2 + desktop/frontend/wailsjs/go/main/App.js | 4 + desktop/src/utils/file.go | 29 ++ desktop/src/utils/http.go | 2 +- desktop/src/utils/log.go | 2 +- desktop/src/utils/str.go | 19 +- 10 files changed, 432 insertions(+), 168 deletions(-) create mode 100644 desktop/src/utils/file.go diff --git a/desktop/app.go b/desktop/app.go index af53038..30ec41d 100644 --- a/desktop/app.go +++ b/desktop/app.go @@ -1,6 +1,7 @@ package main import ( + "OpenManus/src/utils" "context" "fmt" ) @@ -10,6 +11,12 @@ type App struct { ctx context.Context } +type File struct { + Result string `json:"result"` + Error string `json:"error"` + Callbackid string `json:"callbackid"` +} + // NewApp creates a new App application struct func NewApp() *App { return &App{} @@ -25,3 +32,11 @@ func (a *App) startup(ctx context.Context) { func (a *App) Greet(name string) string { return fmt.Sprintf("Hello %s, It's show time!", name) } + +// ReadAll reads file content +func (a *App) ReadAll(filePath string) string { + // 读取文件内容,得到一个含文件内容和callbackid的json字符串 + data := string(utils.ReadAll(filePath)) + utils.Log("ReadAll data: ", data) + return data +} diff --git a/desktop/frontend/src/assets/js/files.js b/desktop/frontend/src/assets/js/files.js index 05c93c1..66d17bd 100644 --- a/desktop/frontend/src/assets/js/files.js +++ b/desktop/frontend/src/assets/js/files.js @@ -1,201 +1,206 @@ import utils from '@/assets/js/utils' +import { ReadAll } from '@/../wailsjs/go/main/App.js' // 临时缓存文件信息 function cache(fileObj, $event) { - console.log('cache fileObj start:', fileObj, $event.target, $event.dataTransfer) - console.log('typeof fileObj:', Array.isArray(fileObj)) - // 如果fileObj是数组,创建一个新的元素,追加到数组 - // event.target.files和event.dataTransfer.files是JavaScript中与文件上传和拖放相关的事件属性。 - // event.target.files:这个属性是在HTML的文件输入元素()上使用时, - // 当用户选择文件并触发change事件时,可以通过event.target.files获取到用户选择的文件列表。 - // event.dataTransfer.files:这个属性是在用户拖放文件到一个元素上时, - // 可以通过event.dataTransfer.files获取到拖放的文件列表。 - console.log('$event:', $event, $event.type) - let files - if ($event.type == 'change') { - files = $event.target.files - } else if ($event.type == 'drop') { - files = $event.dataTransfer.files - } else { - console.error("无法识别的事件") - return - } - const file = files[0] - console.log("file:", file) - const fileInfo = Array.isArray(fileObj) ? new Object() : fileObj - fileInfo.file = file - let URL = window.URL || window.webkitURL - fileInfo.fileUrl = URL.createObjectURL(file) - const fileType = file.type - console.log(fileType, typeof (fileType)) - if (utils.notNull(fileType) && fileType.startsWith("image")) { - fileInfo.imgUrl = fileInfo.fileUrl - } - fileInfo.fileName = file.name - console.log('cache fileObj end:', fileInfo) - if (Array.isArray(fileObj)) { - // 操作成功后追加到数组末尾 - fileObj.push(fileInfo) - } - if ($event.type == 'change') { - // 解决选择相同的文件 不触发change事件的问题,放在最后清理 - $event.target.value = null - } + console.log('cache fileObj start:', fileObj, $event.target, $event.dataTransfer) + console.log('typeof fileObj:', Array.isArray(fileObj)) + // 如果fileObj是数组,创建一个新的元素,追加到数组 + // event.target.files和event.dataTransfer.files是JavaScript中与文件上传和拖放相关的事件属性。 + // event.target.files:这个属性是在HTML的文件输入元素()上使用时, + // 当用户选择文件并触发change事件时,可以通过event.target.files获取到用户选择的文件列表。 + // event.dataTransfer.files:这个属性是在用户拖放文件到一个元素上时, + // 可以通过event.dataTransfer.files获取到拖放的文件列表。 + console.log('$event:', $event, $event.type) + let files + if ($event.type == 'change') { + files = $event.target.files + } else if ($event.type == 'drop') { + files = $event.dataTransfer.files + } else { + console.error("无法识别的事件") + return + } + const file = files[0] + console.log("file:", file) + const fileInfo = Array.isArray(fileObj) ? new Object() : fileObj + fileInfo.file = file + let URL = window.URL || window.webkitURL + fileInfo.fileUrl = URL.createObjectURL(file) + const fileType = file.type + console.log(fileType, typeof (fileType)) + if (utils.notNull(fileType) && fileType.startsWith("image")) { + fileInfo.imgUrl = fileInfo.fileUrl + } + fileInfo.fileName = file.name + console.log('cache fileObj end:', fileInfo) + if (Array.isArray(fileObj)) { + // 操作成功后追加到数组末尾 + fileObj.push(fileInfo) + } + if ($event.type == 'change') { + // 解决选择相同的文件 不触发change事件的问题,放在最后清理 + $event.target.value = null + } } // 上传文件 async function upload(fileObj) { - console.log("准备开始上传文件!", fileObj, fileObj.file, fileObj.fileId) - // 当前地址 - if (utils.isNull(fileObj.file)) { - if (utils.notNull(fileObj.fileId) && fileObj.remark != fileObj.remarkUpd) { - let remark = null - if (utils.notNull(fileObj.remarkUpd)) { - remark = fileObj.remarkUpd - } - await updRemark(fileObj.fileId, remark) - } - return + console.log("准备开始上传文件!", fileObj, fileObj.file, fileObj.fileId) + // 当前地址 + if (utils.isNull(fileObj.file)) { + if (utils.notNull(fileObj.fileId) && fileObj.remark != fileObj.remarkUpd) { + let remark = null + if (utils.notNull(fileObj.remarkUpd)) { + remark = fileObj.remarkUpd + } + await updRemark(fileObj.fileId, remark) } - console.log("开始上传文件!", fileObj, fileObj.file, fileObj.fileId) - const url = '/common/file/upload' - const formData = new FormData() - formData.append('file', fileObj.file) - if (utils.notNull(fileObj.remark)) { - formData.append('remark', fileObj.remark) - } else if (utils.notNull(fileObj.remarkUpd)) { - formData.append('remark', fileObj.remarkUpd) + return + } + console.log("开始上传文件!", fileObj, fileObj.file, fileObj.fileId) + const url = '/common/file/upload' + const formData = new FormData() + formData.append('file', fileObj.file) + if (utils.notNull(fileObj.remark)) { + formData.append('remark', fileObj.remark) + } else if (utils.notNull(fileObj.remarkUpd)) { + formData.append('remark', fileObj.remarkUpd) + } + const data = await utils.awaitPost(url, formData, { + headers: { + 'Content-Type': 'multipart/form-data' } - const data = await utils.awaitPost(url, formData, { - headers: { - 'Content-Type': 'multipart/form-data' - } - }) - Object.assign(fileObj, data) - console.log("文件同步上传处理完毕", fileObj) - return fileObj + }) + Object.assign(fileObj, data) + console.log("文件同步上传处理完毕", fileObj) + return fileObj } // 更新文件备注 async function updRemark(fileId, remarkUpd) { - const param = { - fileId: fileId, - remark: remarkUpd - } - await utils.awaitPost('/common/file/updRemark', param) - console.log("更新文件备注成功") + const param = { + fileId: fileId, + remark: remarkUpd + } + await utils.awaitPost('/common/file/updRemark', param) + console.log("更新文件备注成功") } // 批量上传文件 async function uploads(fileObjs) { - if (utils.isEmpty(fileObjs)) { - return - } - for (let index in fileObjs) { - console.log('fileObjs[index]:', fileObjs, index, fileObjs.length, fileObjs[index]) - await upload(fileObjs[index]) - console.log("uploads index:", index, "上传文件完毕", fileObjs[index]) - } + if (utils.isEmpty(fileObjs)) { + return + } + for (let index in fileObjs) { + console.log('fileObjs[index]:', fileObjs, index, fileObjs.length, fileObjs[index]) + await upload(fileObjs[index]) + console.log("uploads index:", index, "上传文件完毕", fileObjs[index]) + } } // 上传文件(onChange时) function upOnChg(fileObj, $event) { - const file = $event.target.files[0] || $event.dataTransfer.files[0] - // 当前地址 - let URL = window.URL || window.webkitURL - // 转成 blob地址 - fileObj.fileUrl = URL.createObjectURL(file) - const url = '/common/file/upload' - const formData = new FormData() - formData.append('file', file) - formData.append('remark', fileObj.remark) - utils.post(url, formData, { - headers: { - 'Content-Type': 'multipart/form-data' - } - }).then((data) => { - console.log("文件上传结果:", data) - Object.assign(fileObj, data) - fileObj.remarkUpd = data.remark - }) + const file = $event.target.files[0] || $event.dataTransfer.files[0] + // 当前地址 + let URL = window.URL || window.webkitURL + // 转成 blob地址 + fileObj.fileUrl = URL.createObjectURL(file) + const url = '/common/file/upload' + const formData = new FormData() + formData.append('file', file) + formData.append('remark', fileObj.remark) + utils.post(url, formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }).then((data) => { + console.log("文件上传结果:", data) + Object.assign(fileObj, data) + fileObj.remarkUpd = data.remark + }) } function add(fileList) { - const comp = { - index: fileList.length, - file: null, - fileId: null, - fileName: null, - fileUrl: null, - imgUrl: null, - remark: null - } - fileList.push(comp) + const comp = { + index: fileList.length, + file: null, + fileId: null, + fileName: null, + fileUrl: null, + imgUrl: null, + remark: null + } + fileList.push(comp) } function del(fileObj, index) { - console.log("fileObj,index:", fileObj, index) - if (Array.isArray(fileObj)) { - fileObj.splice(index, 1) - } else { - utils.clearProps(fileObj) - } + console.log("fileObj,index:", fileObj, index) + if (Array.isArray(fileObj)) { + fileObj.splice(index, 1) + } else { + utils.clearProps(fileObj) + } } function trans(javaFile, jsFile) { - if (jsFile == undefined || jsFile == null) { - return - } - // 如果是数组,先清空数组 - if (jsFile instanceof Array) { - jsFile.splice(0, jsFile.length) - } else { - utils.clearProps(jsFile) - } + if (jsFile == undefined || jsFile == null) { + return + } + // 如果是数组,先清空数组 + if (jsFile instanceof Array) { + jsFile.splice(0, jsFile.length) + } else { + utils.clearProps(jsFile) + } - if (javaFile == undefined || javaFile == null) { - return - } - // 数组类型 - if (jsFile instanceof Array) { - for (let java of javaFile) { - const js = {} - java.remarkUpd = java.remark - Object.assign(js, java) - jsFile.push(js) - } - } else { - // 对象类型 - console.log("对象类型", jsFile instanceof Array) - javaFile.remarkUpd = javaFile.remark - Object.assign(jsFile, javaFile) + if (javaFile == undefined || javaFile == null) { + return + } + // 数组类型 + if (jsFile instanceof Array) { + for (let java of javaFile) { + const js = {} + java.remarkUpd = java.remark + Object.assign(js, java) + jsFile.push(js) } + } else { + // 对象类型 + console.log("对象类型", jsFile instanceof Array) + javaFile.remarkUpd = javaFile.remark + Object.assign(jsFile, javaFile) + } } // 从Comps中收集fileId function fileIds(fileList) { - return fileList.map(comp => comp.fileId).join(',') + return fileList.map(comp => comp.fileId).join(',') +} + +function readAll(filePath) { + return ReadAll(filePath) } export default { - - // onChange时缓存 - cache, - // 上传文件 - upload, - // 上传文件 - uploads, - // 上传文件 - upOnChg, - // onChange时上传 - upOnChg, - // 添加到组件列表 - add, - // 从组件列表中删除组件 - del, - // 文件Java对象与js对象转换 - trans, - // 从Comps中收集fileId - fileIds - + // onChange时缓存 + cache, + // 上传文件 + upload, + // 上传文件 + uploads, + // 上传文件 + upOnChg, + // onChange时上传 + upOnChg, + // 添加到组件列表 + add, + // 从组件列表中删除组件 + del, + // 文件Java对象与js对象转换 + trans, + // 从Comps中收集fileId + fileIds, + // 读取文件 + readAll } \ No newline at end of file diff --git a/desktop/frontend/src/assets/js/utils.js b/desktop/frontend/src/assets/js/utils.js index aabd53d..fb3ceaa 100644 --- a/desktop/frontend/src/assets/js/utils.js +++ b/desktop/frontend/src/assets/js/utils.js @@ -494,6 +494,13 @@ function debounce(func, delay) { } } +function stringToLines(str) { + if (str == undefined || str == null) { + return [] + } + return str.split('\n') +} + export default { /** * http请求 GET请求 @@ -636,4 +643,6 @@ export default { debounce, + stringToLines, + } \ No newline at end of file diff --git a/desktop/frontend/src/views/config/Llm.vue b/desktop/frontend/src/views/config/Llm.vue index bf659d4..0fecb49 100644 --- a/desktop/frontend/src/views/config/Llm.vue +++ b/desktop/frontend/src/views/config/Llm.vue @@ -3,30 +3,213 @@ + + +
{{ t('noData') }}
+ + +
+
+ model: + {{ llmConfig.model }} +
+ +
+ base_url: + {{ llmConfig.base_url }} +
+ +
+ api_key: + {{ llmConfig.api_key }} +
+ +
+ max_tokens: + {{ llmConfig.max_tokens }} +
+ +
+ temperature: + {{ llmConfig.temperature }} +
+
+ + + +
+
+ model: + + + +
+ +
+ base_url: + + + +
+ +
+ api_key: + + + +
+ +
+ max_tokens: + + + +
+ +
+ temperature: + + + +
+ +
+ {{ t('cancel') }} + {{ t('submit') }} +
+
+
diff --git a/desktop/frontend/wailsjs/go/main/App.d.ts b/desktop/frontend/wailsjs/go/main/App.d.ts index 02a3bb9..fdbcac7 100644 --- a/desktop/frontend/wailsjs/go/main/App.d.ts +++ b/desktop/frontend/wailsjs/go/main/App.d.ts @@ -2,3 +2,5 @@ // This file is automatically generated. DO NOT EDIT export function Greet(arg1:string):Promise; + +export function ReadAll(arg1:string):Promise; diff --git a/desktop/frontend/wailsjs/go/main/App.js b/desktop/frontend/wailsjs/go/main/App.js index c71ae77..15ea61e 100644 --- a/desktop/frontend/wailsjs/go/main/App.js +++ b/desktop/frontend/wailsjs/go/main/App.js @@ -5,3 +5,7 @@ export function Greet(arg1) { return window['go']['main']['App']['Greet'](arg1); } + +export function ReadAll(arg1) { + return window['go']['main']['App']['ReadAll'](arg1); +} diff --git a/desktop/src/utils/file.go b/desktop/src/utils/file.go new file mode 100644 index 0000000..4019085 --- /dev/null +++ b/desktop/src/utils/file.go @@ -0,0 +1,29 @@ +package utils + +import ( + "fmt" + "io" + "os" +) + +// 打开文件 +func ReadAll(filePath string) []byte { + if IsBlank(filePath) { + fmt.Println("File path is nil") + return nil + } + file, err := os.Open(filePath) + if err != nil { + fmt.Println("Error opening file:", err) + return nil + } + // 确保文件最后被关闭 + defer file.Close() + + data, err := io.ReadAll(file) + if err != nil { + fmt.Println("Read file error:", err) + return nil + } + return data +} diff --git a/desktop/src/utils/http.go b/desktop/src/utils/http.go index 2e106fe..17b7c4c 100644 --- a/desktop/src/utils/http.go +++ b/desktop/src/utils/http.go @@ -1,4 +1,4 @@ -package main +package utils import ( "encoding/json" diff --git a/desktop/src/utils/log.go b/desktop/src/utils/log.go index 05d4a66..a6dc32c 100644 --- a/desktop/src/utils/log.go +++ b/desktop/src/utils/log.go @@ -1,4 +1,4 @@ -package main +package utils import ( "log" diff --git a/desktop/src/utils/str.go b/desktop/src/utils/str.go index 9ac86a1..6e5a701 100644 --- a/desktop/src/utils/str.go +++ b/desktop/src/utils/str.go @@ -1,10 +1,11 @@ -package main +package utils import ( "encoding/json" "fmt" "reflect" "strconv" + "strings" ) // AnyToStr 任意类型数据转string @@ -45,3 +46,19 @@ func AnyToStr(i interface{}) (string, error) { return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i) } } + +func IsEmpty(s string) bool { + return len(s) == 0 +} + +func IsNotEmpty(s string) bool { + return len(s) > 0 +} + +func IsBlank(s string) bool { + return len(s) == 0 || strings.TrimSpace(s) == "" +} + +func IsNotBlank(s string) bool { + return len(s) > 0 && strings.TrimSpace(s) != "" +}