From 6eb62b51f6b417ccfb8b31e1ff4a23b52201f676 Mon Sep 17 00:00:00 2001 From: Miao Zhuang <1060950782@163.com> Date: Mon, 8 Jan 2024 10:23:44 +0800 Subject: [PATCH] fix: bug (#729) * fix: bug * fix: rm ngtools --- app/components/MonacoEditor/index.tsx | 1 - app/config/locale/en-US.ts | 2 ++ app/config/locale/zh-CN.ts | 3 ++ app/pages/Console/OutputBox/index.tsx | 2 +- app/pages/Import/AIImport/Create.tsx | 20 +++++++---- app/pages/Import/AIImport/index.module.less | 1 + .../Import/TaskList/TaskItem/AIImportItem.tsx | 2 +- .../TaskList/TaskItem/LogModal/index.tsx | 4 ++- app/pages/LLMBot/chat.module.less | 33 ++++--------------- app/pages/LLMBot/chat.tsx | 31 +++++++++++++---- app/stores/import.ts | 2 +- package-lock.json | 28 ++++++++-------- package.json | 4 +-- .../api/studio/internal/service/llm/import.go | 9 ++++- server/api/studio/pkg/llm/importjob.go | 20 +++++++---- server/api/studio/pkg/llm/transformer/qwen.go | 12 +++++-- 16 files changed, 103 insertions(+), 71 deletions(-) diff --git a/app/components/MonacoEditor/index.tsx b/app/components/MonacoEditor/index.tsx index f4825d45..5178128c 100644 --- a/app/components/MonacoEditor/index.tsx +++ b/app/components/MonacoEditor/index.tsx @@ -1,5 +1,4 @@ import { useCallback, useEffect, useMemo, useRef } from 'react'; -// eslint-disable-next-line import/no-extraneous-dependencies import * as monaco from 'monaco-editor'; import type { editor as TMonacoEditor } from 'monaco-editor'; import Editor, { useMonaco, loader, type Monaco } from '@monaco-editor/react'; diff --git a/app/config/locale/en-US.ts b/app/config/locale/en-US.ts index df3fb0f1..a6c9a4a6 100644 --- a/app/config/locale/en-US.ts +++ b/app/config/locale/en-US.ts @@ -564,5 +564,7 @@ export default { start: 'Start', aiImport: 'AI Import', pleaseConfigLLMFirst: 'Please configure LLM API first', + tokenTip: "The current token consumption is an estimated value, and there may be some differences from the actual consumption in the end.", + fileRequired: 'Please select the file', }, }; diff --git a/app/config/locale/zh-CN.ts b/app/config/locale/zh-CN.ts index ae1af2e6..88168e46 100644 --- a/app/config/locale/zh-CN.ts +++ b/app/config/locale/zh-CN.ts @@ -542,5 +542,8 @@ export default { previous: '上一步', start: '开始', aiImport: 'AI 导入', + pleaseConfigLLMFirst: '请先配置 LLM 接口地址', + tokenTip: '当前 token 消耗为预估值,最终消耗可能与实际消耗有所差异。', + fileRequired: '请先选择文件', }, }; diff --git a/app/pages/Console/OutputBox/index.tsx b/app/pages/Console/OutputBox/index.tsx index bfa7e368..29036171 100644 --- a/app/pages/Console/OutputBox/index.tsx +++ b/app/pages/Console/OutputBox/index.tsx @@ -329,7 +329,7 @@ const OutputBox = (props: IProps) => { children:
{item}
; + return+
{item}+ ; } else { item = item.replace(/^(\n|ngql|gql|cypher)/g, '').replace(/\n$/g, ''); item = item.replace(/\n\n/, '\n'); diff --git a/app/stores/import.ts b/app/stores/import.ts index 14f092a1..0da85de1 100644 --- a/app/stores/import.ts +++ b/app/stores/import.ts @@ -341,7 +341,7 @@ export class ImportStore { trackEvent('import', 'download_task_log'); }; - getLogDetail = async (params: ITaskItem) => { + getLogDetail = async (params: any) => { const { code, data } = await service.getLogDetail(params); if (code === 0) { return data; diff --git a/package-lock.json b/package-lock.json index 5616e5ac..8df3072b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,8 +15,8 @@ "@monaco-editor/react": "^4.6.0", "@vesoft-inc/force-graph": "2.0.7", "@vesoft-inc/i18n": "^1.0.1", - "@vesoft-inc/icons": "^1.2.0", - "@vesoft-inc/nebula-explain-graph": "^1.0.2-beta.2", + "@vesoft-inc/icons": "^1.7.0", + "@vesoft-inc/nebula-explain-graph": "^1.0.3", "@vesoft-inc/veditor": "^4.4.12", "antd": "^5.8.4", "axios": "^0.23.0", @@ -2058,14 +2058,14 @@ } }, "node_modules/@vesoft-inc/icons": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vesoft-inc/icons/-/icons-1.2.0.tgz", - "integrity": "sha512-tqoAlsc1ofmaawQL15ok98wlAzD5NAWSPu5RBva85jvw7XREJM5+VjYeOg9lYAEWsdraUvw4iFNMBY9GvZtXhA==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@vesoft-inc/icons/-/icons-1.7.0.tgz", + "integrity": "sha512-862wYZP+oueH7WqykjV9xMqOP9lYQajqdrGjhTT18C57Y0g7HFikzrujArSk9q63qdo8viNO/27hl1iKULH4bQ==" }, "node_modules/@vesoft-inc/nebula-explain-graph": { - "version": "1.0.2-beta.2", - "resolved": "https://registry.npmmirror.com/@vesoft-inc/nebula-explain-graph/-/nebula-explain-graph-1.0.2-beta.2.tgz", - "integrity": "sha512-Pgcun3Zkq/pQ0dNzfStRmhRa2HH2hZOLB7878HZPnZ2cGSfRWM5XhuO5JsnrZMhgdbuoINQ1iuHK1T61+m2hvg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@vesoft-inc/nebula-explain-graph/-/nebula-explain-graph-1.0.3.tgz", + "integrity": "sha512-oP5SPYVVvkuw3LlCBiaZ/eLC5EnjQrRCNYyFWGSjT1ZJcmsqzee0Ts4wBuyiebgi2MyBX/TIZJNTRurCjrWrlg==", "peerDependencies": { "@vesoft-inc/veditor": "^4.4.11", "antd": "^4||^5", @@ -10495,14 +10495,14 @@ } }, "@vesoft-inc/icons": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vesoft-inc/icons/-/icons-1.2.0.tgz", - "integrity": "sha512-tqoAlsc1ofmaawQL15ok98wlAzD5NAWSPu5RBva85jvw7XREJM5+VjYeOg9lYAEWsdraUvw4iFNMBY9GvZtXhA==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@vesoft-inc/icons/-/icons-1.7.0.tgz", + "integrity": "sha512-862wYZP+oueH7WqykjV9xMqOP9lYQajqdrGjhTT18C57Y0g7HFikzrujArSk9q63qdo8viNO/27hl1iKULH4bQ==" }, "@vesoft-inc/nebula-explain-graph": { - "version": "1.0.2-beta.2", - "resolved": "https://registry.npmmirror.com/@vesoft-inc/nebula-explain-graph/-/nebula-explain-graph-1.0.2-beta.2.tgz", - "integrity": "sha512-Pgcun3Zkq/pQ0dNzfStRmhRa2HH2hZOLB7878HZPnZ2cGSfRWM5XhuO5JsnrZMhgdbuoINQ1iuHK1T61+m2hvg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@vesoft-inc/nebula-explain-graph/-/nebula-explain-graph-1.0.3.tgz", + "integrity": "sha512-oP5SPYVVvkuw3LlCBiaZ/eLC5EnjQrRCNYyFWGSjT1ZJcmsqzee0Ts4wBuyiebgi2MyBX/TIZJNTRurCjrWrlg==", "requires": {} }, "@vesoft-inc/veditor": { diff --git a/package.json b/package.json index f1ac516d..e16a5cbe 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "@monaco-editor/react": "^4.6.0", "@vesoft-inc/force-graph": "2.0.7", "@vesoft-inc/i18n": "^1.0.1", - "@vesoft-inc/icons": "^1.2.0", + "@vesoft-inc/icons": "^1.7.0", "@vesoft-inc/nebula-explain-graph": "^1.0.3", "@vesoft-inc/veditor": "^4.4.12", "antd": "^5.8.4", @@ -103,7 +103,7 @@ "lint-staged": { "./app/**/*.{js,jsx,ts,tsx}": [ "npx prettier --write", - "eslint './app/**/*.{js,jsx,ts,tsx}' --fix" + "eslint './app/**/*.{js,jsx,ts,tsx}' --fix --quiet" ] }, "ci": { diff --git a/server/api/studio/internal/service/llm/import.go b/server/api/studio/internal/service/llm/import.go index 03e414af..dbec123f 100644 --- a/server/api/studio/internal/service/llm/import.go +++ b/server/api/studio/internal/service/llm/import.go @@ -2,8 +2,10 @@ package llm import ( "fmt" + "hash/fnv" "os" "path/filepath" + "strconv" "time" "github.com/vesoft-inc/go-pkg/response" @@ -16,6 +18,11 @@ import ( "gorm.io/datatypes" ) +func hashString(s string) string { + h := fnv.New64a() + h.Write([]byte(s)) + return strconv.FormatUint(h.Sum64(), 8) +} func (g *llmService) AddImportJob(req *types.LLMImportRequest) (resp *types.LLMResponse, err error) { auth := g.ctx.Value(auth.CtxKeyUserInfo{}).(*auth.AuthData) config := db.LLMConfig{ @@ -40,7 +47,7 @@ func (g *llmService) AddImportJob(req *types.LLMImportRequest) (resp *types.LLMR Host: config.Host, UserName: config.UserName, UserPrompt: req.UserPrompt, - JobID: space + "_" + time.Now().Format("20060102150405000"), + JobID: time.Now().Format("20060102150405000") + "_" + hashString(space), } task := &db.TaskInfo{ BID: job.JobID, diff --git a/server/api/studio/pkg/llm/importjob.go b/server/api/studio/pkg/llm/importjob.go index 16196bb8..d73be879 100644 --- a/server/api/studio/pkg/llm/importjob.go +++ b/server/api/studio/pkg/llm/importjob.go @@ -467,7 +467,7 @@ func (i *ImportJob) MakeGQLFile(filePath string) ([]string, error) { for key, field := range typeSchema { value, ok := props[key] - if !ok { + if !ok || value == nil { if field.Nullable { continue } else { @@ -483,9 +483,13 @@ func (i *ImportJob) MakeGQLFile(filePath string) ([]string, error) { valueStr += "," } if strings.Contains(strings.ToLower(field.DataType), "string") { - valueStr += fmt.Sprintf(`"%v"`, value) + valueStr += fmt.Sprintf(`"%s"`, value) } else { - valueStr += fmt.Sprintf(`%v`, value) + if value == nil { + valueStr += "null" + } else { + valueStr += fmt.Sprintf(`%s`, value) + } } } @@ -580,11 +584,15 @@ func (i *ImportJob) RunGQLFile(gqls []string) error { return nil } +func replaceBackslash(s string) string { + return strings.ReplaceAll(s, "\\", "\\\\") +} + func (i *ImportJob) MakeSchema() error { schema := Schema{ Space: i.LLMJob.Space, } - gql := fmt.Sprintf("DESCRIBE SPACE `%s`", i.LLMJob.Space) + gql := fmt.Sprintf("DESCRIBE SPACE `%s`", replaceBackslash(i.LLMJob.Space)) spaceInfo, err := client.Execute(i.NSID, i.LLMJob.Space, []string{gql}) if err != nil { return err @@ -612,7 +620,7 @@ func (i *ImportJob) MakeSchema() error { tag := NodeType{ Type: row["Name"].(string), } - gql = fmt.Sprintf("DESCRIBE TAG `%s`", tag.Type) + gql = fmt.Sprintf("DESCRIBE TAG `%s`", replaceBackslash(tag.Type)) res, err := client.Execute(i.NSID, i.LLMJob.Space, []string{gql}) if err != nil { return err @@ -649,7 +657,7 @@ func (i *ImportJob) MakeSchema() error { edge := EdgeType{ Type: row["Name"].(string), } - gql = fmt.Sprintf("DESCRIBE EDGE `%s`", edge.Type) + gql = fmt.Sprintf("DESCRIBE EDGE `%s`", replaceBackslash(edge.Type)) res, err := client.Execute(i.NSID, i.LLMJob.Space, []string{gql}) if err != nil { return err diff --git a/server/api/studio/pkg/llm/transformer/qwen.go b/server/api/studio/pkg/llm/transformer/qwen.go index 92d104a3..dfd78660 100644 --- a/server/api/studio/pkg/llm/transformer/qwen.go +++ b/server/api/studio/pkg/llm/transformer/qwen.go @@ -89,8 +89,16 @@ func (o *Qwen) HandleResponse(resp *http.Response, callback func(str string)) (m return nil, fmt.Errorf("failed to parse response data: %s %v", string(bodyBytes), err) } - respData["choices"] = respData["output"].(map[string]any)["choices"] - usage := respData["usage"].(map[string]any) + output, ok := respData["output"].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("output is not a map[string]interface{},data: %s", string(bodyBytes)) + } + respData["choices"] = output["choices"] + + usage, ok := respData["usage"].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("usage is not a map[string]interface{}, data:%s", string(bodyBytes)) + } usage["completion_tokens"] = usage["output_tokens"] usage["prompt_tokens"] = usage["input_tokens"] return respData, nil