From 0f15fd255059663a35c18a690b1a0164b6e1daaf Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sat, 4 Mar 2023 17:16:53 +0800 Subject: [PATCH 01/10] =?UTF-8?q?:sparkles:=20=E6=A1=8C=E9=9D=A2=E7=AB=AF?= =?UTF-8?q?=E6=8E=A5=E5=85=A5=20OpenAI=20Chat=20API=20https://github.com/s?= =?UTF-8?q?iyuan-note/siyuan/issues/7560?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20210808180117-6v0mkxr/.siyuan/sort.json | 15 ++++++++------- .../20230304000547-ibldj1z.sy | 14 +++++++------- .../20210808180117-czj9bvb/.siyuan/sort.json | 15 ++++++++------- .../20230303235619-ex5l63e.sy | 19 ++++++++++++------- .../20211226090932-5lcq56f/.siyuan/sort.json | 15 ++++++++------- .../20230304000829-9jwu3po.sy | 14 +++++++------- 6 files changed, 50 insertions(+), 42 deletions(-) diff --git a/app/guide/20210808180117-6v0mkxr/.siyuan/sort.json b/app/guide/20210808180117-6v0mkxr/.siyuan/sort.json index bf0d71b95..03580dd4b 100644 --- a/app/guide/20210808180117-6v0mkxr/.siyuan/sort.json +++ b/app/guide/20210808180117-6v0mkxr/.siyuan/sort.json @@ -6,24 +6,24 @@ "20200924095938-a9p5450": 2, "20200924100110-vcg96wy": 1, "20200924100635-ms0p9lb": 6, - "20200924100717-yzwzn64": 18, + "20200924100717-yzwzn64": 19, "20200924100744-br924ar": 8, "20200924100808-j9sddk9": 2, "20200924100906-0u4zfq3": 4, - "20200924100950-9op5xi1": 15, + "20200924100950-9op5xi1": 16, "20200924101106-19z4kaa": 1, "20200924101200-gss5vee": 4, "20200924101225-k254i8g": 2, "20200924101256-f8b1sbi": 3, - "20201004194026-s8h2cog": 16, + "20201004194026-s8h2cog": 17, "20201117112518-dott91x": 6, "20201121224345-rc27qvo": 5, "20201204184532-3qm9l8n": 9, "20201210233038-3xr19g5": 5, "20201222100222-q47d64s": 2, "20201222100339-i5hzcph": 1, - "20201227201128-m1wrouw": 17, - "20201227201751-gv0fpx2": 19, + "20201227201128-m1wrouw": 18, + "20201227201751-gv0fpx2": 20, "20210110181011-fbhoesf": 5, "20210117215840-jcl17fx": 3, "20210127203829-qe2mzof": 10, @@ -47,6 +47,7 @@ "20220708103401-mgydrfg": 3, "20221016204105-qx2aq0g": 3, "20221223221636-ms2b4w9": 14, - "20230104152135-1iei0xa": 20, - "20230106104821-9nfphwm": 1 + "20230104152135-1iei0xa": 21, + "20230106104821-9nfphwm": 1, + "20230304000547-ibldj1z": 15 } \ No newline at end of file diff --git a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20230304000547-ibldj1z.sy b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20230304000547-ibldj1z.sy index 8c73fab3a..a787e959a 100644 --- a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20230304000547-ibldj1z.sy +++ b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20230304000547-ibldj1z.sy @@ -5,7 +5,7 @@ "Properties": { "id": "20230304000547-ibldj1z", "title": "Artificial Intelligence", - "updated": "20230304000723" + "updated": "20230304171533" }, "Children": [ { @@ -70,7 +70,7 @@ }, "Properties": { "id": "20230304000646-a5e7srt", - "updated": "20230304000646" + "updated": "20230304171533" }, "Children": [ { @@ -114,7 +114,7 @@ }, "Properties": { "id": "20230304000646-6207b6r", - "updated": "20230304000646" + "updated": "20230304171533" }, "Children": [ { @@ -137,7 +137,7 @@ "ListData": {}, "Properties": { "id": "20230304000646-aj5szch", - "updated": "20230304000646" + "updated": "20230304171533" }, "Children": [ { @@ -260,7 +260,7 @@ }, "Properties": { "id": "20230304000646-8swnrqn", - "updated": "20230304000646" + "updated": "20230304171533" }, "Children": [ { @@ -268,7 +268,7 @@ "Type": "NodeParagraph", "Properties": { "id": "20230304000646-33hvl2k", - "updated": "20230304000646" + "updated": "20230304171533" }, "Children": [ { @@ -282,7 +282,7 @@ }, { "Type": "NodeText", - "Data": "​ specifies the number of tokens, the default is 0, that is unlimited (optional)" + "Data": "​ specifies the number of tokens, the default is 0, that is, the default value of the model is used (optional)" } ] } diff --git a/app/guide/20210808180117-czj9bvb/.siyuan/sort.json b/app/guide/20210808180117-czj9bvb/.siyuan/sort.json index 8feb53c43..4527c8396 100644 --- a/app/guide/20210808180117-czj9bvb/.siyuan/sort.json +++ b/app/guide/20210808180117-czj9bvb/.siyuan/sort.json @@ -1,6 +1,6 @@ { "20200812220555-lj3enxa": 1, - "20200813004551-gm0pbn1": 15, + "20200813004551-gm0pbn1": 16, "20200813004931-q4cu8na": 1, "20200813013559-sgbzl5k": 3, "20200813093015-u6bopdt": 2, @@ -9,20 +9,20 @@ "20200813163359-v04n73b": 4, "20200822191536-rm6hwid": 4, "20200825162036-4dx365o": 1, - "20200828105441-r76vmu5": 18, + "20200828105441-r76vmu5": 19, "20200905090211-2vixtlf": 2, "20200910201551-h4twhas": 6, "20200915214115-42b8zma": 8, "20200922102318-oz84yu3": 2, - "20201004184819-nj8ibyg": 16, + "20201004184819-nj8ibyg": 17, "20201117101902-2ewjjum": 6, "20201121212605-9td1a62": 5, "20201204181006-7bkppue": 9, "20201210103036-1x3vm8t": 5, "20201222093044-rx4zjoy": 1, "20201222095049-hghafhe": 2, - "20201227173504-847cs1q": 17, - "20201227194925-7ipoiv6": 19, + "20201227173504-847cs1q": 18, + "20201227194925-7ipoiv6": 20, "20210110175347-2xrwoiq": 5, "20210117211155-56n4odu": 3, "20210127202655-2334vvv": 10, @@ -48,6 +48,7 @@ "20220708095345-tu7nz95": 3, "20221016213308-uz5af79": 3, "20221223215557-o6gfsoy": 14, - "20230104144904-39br4c6": 20, - "20230106101434-e6g4av3": 1 + "20230104144904-39br4c6": 21, + "20230106101434-e6g4av3": 1, + "20230303235619-ex5l63e": 15 } \ No newline at end of file diff --git a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20230303235619-ex5l63e.sy b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20230303235619-ex5l63e.sy index 5fae78b80..5412ff89b 100644 --- a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20230303235619-ex5l63e.sy +++ b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20230303235619-ex5l63e.sy @@ -5,7 +5,7 @@ "Properties": { "id": "20230303235619-ex5l63e", "title": "人工智能", - "updated": "20230304000753" + "updated": "20230304171349" }, "Children": [ { @@ -70,7 +70,7 @@ }, "Properties": { "id": "20230303235749-kurfjky", - "updated": "20230304000517" + "updated": "20230304171349" }, "Children": [ { @@ -113,7 +113,8 @@ "Num": 2 }, "Properties": { - "id": "20230303235819-0o648f9" + "id": "20230303235819-0o648f9", + "updated": "20230304171349" }, "Children": [ { @@ -136,7 +137,7 @@ "ListData": {}, "Properties": { "id": "20230303235950-z00ou0r", - "updated": "20230303235950" + "updated": "20230304171349" }, "Children": [ { @@ -259,7 +260,7 @@ }, "Properties": { "id": "20230303235950-5y60wvh", - "updated": "20230303235950" + "updated": "20230304171349" }, "Children": [ { @@ -267,7 +268,7 @@ "Type": "NodeParagraph", "Properties": { "id": "20230303235950-ffevwk8", - "updated": "20230303235950" + "updated": "20230304171349" }, "Children": [ { @@ -281,7 +282,11 @@ }, { "Type": "NodeText", - "Data": "​ 指定 tokens 数量,默认为 0,即不限制(可选)" + "Data": "​​ 指定 tokens 数量,默认为 0,即使用模型默认值" + }, + { + "Type": "NodeText", + "Data": "(可选)" } ] } diff --git a/app/guide/20211226090932-5lcq56f/.siyuan/sort.json b/app/guide/20211226090932-5lcq56f/.siyuan/sort.json index 786641455..4a3672b5a 100644 --- a/app/guide/20211226090932-5lcq56f/.siyuan/sort.json +++ b/app/guide/20211226090932-5lcq56f/.siyuan/sort.json @@ -18,14 +18,14 @@ "20211226121203-rjjngpz": 6, "20211226121232-23s79xr": 7, "20211226121319-emrk2yy": 1, - "20211226121329-c5v3dto": 19, + "20211226121329-c5v3dto": 20, "20211226121332-irgblss": 4, "20211226121438-xaafdo8": 2, "20211226121503-k3jma6m": 1, - "20211226122358-hctqcn5": 18, - "20211226122459-08mi5cq": 17, - "20211226122523-rl8356a": 16, - "20211226122549-jktxego": 15, + "20211226122358-hctqcn5": 19, + "20211226122459-08mi5cq": 18, + "20211226122523-rl8356a": 17, + "20211226122549-jktxego": 16, "20211226122707-8cr09co": 13, "20211226122728-cnqf7rz": 12, "20211226122814-r1rdpcx": 11, @@ -43,6 +43,7 @@ "20220708102441-u6wopo9": 3, "20221016213639-1nag9jj": 3, "20221223221501-mops33i": 14, - "20230104151953-48hwkwf": 20, - "20230106104645-o838uew": 1 + "20230104151953-48hwkwf": 21, + "20230106104645-o838uew": 1, + "20230304000829-9jwu3po": 15 } \ No newline at end of file diff --git a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20230304000829-9jwu3po.sy b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20230304000829-9jwu3po.sy index 2414fb137..8f784b3c7 100644 --- a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20230304000829-9jwu3po.sy +++ b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20230304000829-9jwu3po.sy @@ -5,7 +5,7 @@ "Properties": { "id": "20230304000829-9jwu3po", "title": "人工智能", - "updated": "20230304000912" + "updated": "20230304171553" }, "Children": [ { @@ -70,7 +70,7 @@ }, "Properties": { "id": "20230304000837-t0swnf6", - "updated": "20230304000837" + "updated": "20230304171553" }, "Children": [ { @@ -114,7 +114,7 @@ }, "Properties": { "id": "20230304000837-ktv65zx", - "updated": "20230304000837" + "updated": "20230304171553" }, "Children": [ { @@ -137,7 +137,7 @@ "ListData": {}, "Properties": { "id": "20230304000837-8z180b1", - "updated": "20230304000837" + "updated": "20230304171553" }, "Children": [ { @@ -260,7 +260,7 @@ }, "Properties": { "id": "20230304000837-sd6h4qn", - "updated": "20230304000837" + "updated": "20230304171553" }, "Children": [ { @@ -268,7 +268,7 @@ "Type": "NodeParagraph", "Properties": { "id": "20230304000837-y8kj8ki", - "updated": "20230304000837" + "updated": "20230304171553" }, "Children": [ { @@ -282,7 +282,7 @@ }, { "Type": "NodeText", - "Data": "​ 指定 tokens 數量,默認為 0,即不限制(可選)" + "Data": "​​ 指定 tokens 數量,默認為 0,即使用模型默認值(可選)" } ] } From 3c9e80b4117b5a97f11b33616ff3b734dcd9e711 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sat, 4 Mar 2023 18:11:17 +0800 Subject: [PATCH 02/10] =?UTF-8?q?:art:=20=E6=94=B9=E8=BF=9B=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E5=B7=A5=E4=BD=9C=E7=A9=BA=E9=97=B4=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=20Fix=20https://github.com/siyuan-note/siyua?= =?UTF-8?q?n/issues/7569?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/api/workspace.go | 6 ++++-- kernel/util/file.go | 10 +++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/kernel/api/workspace.go b/kernel/api/workspace.go index fe2a4c145..3b6b1510c 100644 --- a/kernel/api/workspace.go +++ b/kernel/api/workspace.go @@ -198,8 +198,10 @@ func setWorkspaceDir(c *gin.Context) { } if gulu.OS.IsWindows() { - installDir := filepath.Dir(util.WorkingDir) - if strings.HasPrefix(path, installDir) { + // 改进判断工作空间路径实现 https://github.com/siyuan-note/siyuan/issues/7569 + installDirLower := strings.ToLower(filepath.Dir(util.WorkingDir)) + pathLower := strings.ToLower(path) + if strings.HasPrefix(pathLower, installDirLower) && util.IsSubPath(installDirLower, pathLower) { ret.Code = -1 ret.Msg = model.Conf.Language(98) ret.Data = map[string]interface{}{"closeTimeout": 5000} diff --git a/kernel/util/file.go b/kernel/util/file.go index f39ebe004..090956dcf 100644 --- a/kernel/util/file.go +++ b/kernel/util/file.go @@ -148,13 +148,13 @@ func FilterFileName(name string) string { return name } -func IsSubFolder(parent, sub string) bool { - if 1 > len(parent) || 1 > len(sub) { +func IsSubPath(absPath, toCheckPath string) bool { + if 1 > len(absPath) || 1 > len(toCheckPath) { return false } if gulu.OS.IsWindows() { - if filepath.IsAbs(parent) && filepath.IsAbs(sub) { - if strings.ToLower(parent)[0] != strings.ToLower(sub)[0] { + if filepath.IsAbs(absPath) && filepath.IsAbs(toCheckPath) { + if strings.ToLower(absPath)[0] != strings.ToLower(toCheckPath)[0] { // 不在一个盘 return false } @@ -162,7 +162,7 @@ func IsSubFolder(parent, sub string) bool { } up := ".." + string(os.PathSeparator) - rel, err := filepath.Rel(parent, sub) + rel, err := filepath.Rel(absPath, toCheckPath) if err != nil { return false } From 5eae66a35e9e1197dac1c05c9cb37bffae880615 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sun, 5 Mar 2023 00:20:07 +0800 Subject: [PATCH 03/10] =?UTF-8?q?:art:=20AI=20=E5=8A=A0=E5=85=A5=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/util/openai.go | 59 ++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/kernel/util/openai.go b/kernel/util/openai.go index 7478f8138..ada939c33 100644 --- a/kernel/util/openai.go +++ b/kernel/util/openai.go @@ -40,7 +40,15 @@ var ( OpenAIAPIMaxTokens = 0 ) +var cachedContextMsg []string + func ChatGPT(msg string) (ret string) { + ret, retCtxMsgs := ChatGPTContinueWrite(msg, cachedContextMsg) + cachedContextMsg = append(cachedContextMsg, retCtxMsgs...) + return +} + +func ChatGPTContinueWrite(msg string, contextMsgs []string) (ret string, retContextMsgs []string) { if "" == OpenAIAPIKey { return } @@ -48,30 +56,31 @@ func ChatGPT(msg string) (ret string) { PushEndlessProgress("Requesting...") defer ClearPushProgress(100) - config := gogpt.DefaultConfig(OpenAIAPIKey) - if "" != OpenAIAPIProxy { - proxyUrl, err := url.Parse(OpenAIAPIProxy) - if nil != err { - logging.LogErrorf("OpenAI API proxy error: %v", err) - } else { - config.HTTPClient = &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}} - } + c := newOpenAIClient() + + var reqMsgs []gogpt.ChatCompletionMessage + if 7 < len(contextMsgs) { + contextMsgs = contextMsgs[len(contextMsgs)-7:] } - c := gogpt.NewClientWithConfig(config) - ctx, cancel := context.WithTimeout(context.Background(), OpenAIAPITimeout) - defer cancel() + for _, ctxMsg := range contextMsgs { + reqMsgs = append(reqMsgs, gogpt.ChatCompletionMessage{ + Role: "user", + Content: ctxMsg, + }) + } + reqMsgs = append(reqMsgs, gogpt.ChatCompletionMessage{ + Role: "user", + Content: msg, + }) + req := gogpt.ChatCompletionRequest{ Model: gogpt.GPT3Dot5Turbo, MaxTokens: OpenAIAPIMaxTokens, - Messages: []gogpt.ChatCompletionMessage{ - { - Role: "user", - Content: msg, - }, - }, + Messages: reqMsgs, } - + ctx, cancel := context.WithTimeout(context.Background(), OpenAIAPITimeout) + defer cancel() stream, err := c.CreateChatCompletionStream(ctx, req) if nil != err { logging.LogErrorf("create chat completion stream failed: %s", err) @@ -100,9 +109,23 @@ func ChatGPT(msg string) (ret string) { ret = buf.String() ret = strings.TrimSpace(ret) + retContextMsgs = append(retContextMsgs, msg, ret) return } +func newOpenAIClient() *gogpt.Client { + config := gogpt.DefaultConfig(OpenAIAPIKey) + if "" != OpenAIAPIProxy { + proxyUrl, err := url.Parse(OpenAIAPIProxy) + if nil != err { + logging.LogErrorf("OpenAI API proxy failed: %v", err) + } else { + config.HTTPClient = &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}} + } + } + return gogpt.NewClientWithConfig(config) +} + func initOpenAI() { OpenAIAPIKey = os.Getenv("SIYUAN_OPENAI_API_KEY") if "" == OpenAIAPIKey { From d85568a0030e83cc1a07de682fd6ca810f558190 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sun, 5 Mar 2023 10:27:46 +0800 Subject: [PATCH 04/10] =?UTF-8?q?:sparkles:=20=E6=A1=8C=E9=9D=A2=E7=AB=AF?= =?UTF-8?q?=E6=8E=A5=E5=85=A5=20OpenAI=20Chat=20API=20https://github.com/s?= =?UTF-8?q?iyuan-note/siyuan/issues/7560?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20230304000547-ibldj1z.sy | 14 ++--- .../20230303235619-ex5l63e.sy | 14 ++--- .../20230304000829-9jwu3po.sy | 14 ++--- kernel/util/openai.go | 58 +++++++++++-------- 4 files changed, 55 insertions(+), 45 deletions(-) diff --git a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20230304000547-ibldj1z.sy b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20230304000547-ibldj1z.sy index a787e959a..a25bc9ffe 100644 --- a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20230304000547-ibldj1z.sy +++ b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-xaduj2o/20230304000547-ibldj1z.sy @@ -5,7 +5,7 @@ "Properties": { "id": "20230304000547-ibldj1z", "title": "Artificial Intelligence", - "updated": "20230304171533" + "updated": "20230305102525" }, "Children": [ { @@ -70,7 +70,7 @@ }, "Properties": { "id": "20230304000646-a5e7srt", - "updated": "20230304171533" + "updated": "20230305102525" }, "Children": [ { @@ -114,7 +114,7 @@ }, "Properties": { "id": "20230304000646-6207b6r", - "updated": "20230304171533" + "updated": "20230305102525" }, "Children": [ { @@ -137,7 +137,7 @@ "ListData": {}, "Properties": { "id": "20230304000646-aj5szch", - "updated": "20230304171533" + "updated": "20230305102525" }, "Children": [ { @@ -186,7 +186,7 @@ }, "Properties": { "id": "20230304000646-78w2ck5", - "updated": "20230304000646" + "updated": "20230305102525" }, "Children": [ { @@ -194,7 +194,7 @@ "Type": "NodeParagraph", "Properties": { "id": "20230304000646-2blt9e0", - "updated": "20230304000646" + "updated": "20230305102525" }, "Children": [ { @@ -208,7 +208,7 @@ }, { "Type": "NodeText", - "Data": "​ specifies the timeout time (seconds), the default is 15 seconds (optional)" + "Data": "​ specifies the timeout time (seconds), the default is 30 seconds (optional)" } ] } diff --git a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20230303235619-ex5l63e.sy b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20230303235619-ex5l63e.sy index 5412ff89b..9e8b0fda7 100644 --- a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20230303235619-ex5l63e.sy +++ b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180321-hbvl5c2/20230303235619-ex5l63e.sy @@ -5,7 +5,7 @@ "Properties": { "id": "20230303235619-ex5l63e", "title": "人工智能", - "updated": "20230304171349" + "updated": "20230305102554" }, "Children": [ { @@ -70,7 +70,7 @@ }, "Properties": { "id": "20230303235749-kurfjky", - "updated": "20230304171349" + "updated": "20230305102554" }, "Children": [ { @@ -114,7 +114,7 @@ }, "Properties": { "id": "20230303235819-0o648f9", - "updated": "20230304171349" + "updated": "20230305102554" }, "Children": [ { @@ -137,7 +137,7 @@ "ListData": {}, "Properties": { "id": "20230303235950-z00ou0r", - "updated": "20230304171349" + "updated": "20230305102554" }, "Children": [ { @@ -186,7 +186,7 @@ }, "Properties": { "id": "20230303235950-l6o3a5a", - "updated": "20230303235950" + "updated": "20230305102554" }, "Children": [ { @@ -194,7 +194,7 @@ "Type": "NodeParagraph", "Properties": { "id": "20230303235950-zfhft7e", - "updated": "20230303235950" + "updated": "20230305102554" }, "Children": [ { @@ -208,7 +208,7 @@ }, { "Type": "NodeText", - "Data": "​ 指定超时时间(秒),默认为 15 秒(可选)" + "Data": "​ 指定超时时间(秒),默认为 30 秒(可选)" } ] } diff --git a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20230304000829-9jwu3po.sy b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20230304000829-9jwu3po.sy index 8f784b3c7..db97e3ec5 100644 --- a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20230304000829-9jwu3po.sy +++ b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226121203-rjjngpz/20230304000829-9jwu3po.sy @@ -5,7 +5,7 @@ "Properties": { "id": "20230304000829-9jwu3po", "title": "人工智能", - "updated": "20230304171553" + "updated": "20230305102546" }, "Children": [ { @@ -70,7 +70,7 @@ }, "Properties": { "id": "20230304000837-t0swnf6", - "updated": "20230304171553" + "updated": "20230305102546" }, "Children": [ { @@ -114,7 +114,7 @@ }, "Properties": { "id": "20230304000837-ktv65zx", - "updated": "20230304171553" + "updated": "20230305102546" }, "Children": [ { @@ -137,7 +137,7 @@ "ListData": {}, "Properties": { "id": "20230304000837-8z180b1", - "updated": "20230304171553" + "updated": "20230305102546" }, "Children": [ { @@ -186,7 +186,7 @@ }, "Properties": { "id": "20230304000837-71slt0q", - "updated": "20230304000837" + "updated": "20230305102546" }, "Children": [ { @@ -194,7 +194,7 @@ "Type": "NodeParagraph", "Properties": { "id": "20230304000837-t2um8y2", - "updated": "20230304000837" + "updated": "20230305102546" }, "Children": [ { @@ -208,7 +208,7 @@ }, { "Type": "NodeText", - "Data": "​ 指定超時時間(秒),默認為 15 秒(可選)" + "Data": "​ 指定超時時間(秒),默認為 30 秒(可選)" } ] } diff --git a/kernel/util/openai.go b/kernel/util/openai.go index ada939c33..5a549239d 100644 --- a/kernel/util/openai.go +++ b/kernel/util/openai.go @@ -19,9 +19,6 @@ package util import ( "bytes" "context" - "errors" - "github.com/88250/lute/html" - "io" "net/http" "net/url" "os" @@ -35,7 +32,7 @@ import ( var ( OpenAIAPIKey = "" - OpenAIAPITimeout = 15 * time.Second + OpenAIAPITimeout = 30 * time.Second OpenAIAPIProxy = "" OpenAIAPIMaxTokens = 0 ) @@ -57,7 +54,25 @@ func ChatGPTContinueWrite(msg string, contextMsgs []string) (ret string, retCont defer ClearPushProgress(100) c := newOpenAIClient() + buf := &bytes.Buffer{} + for i := 0; i < 7; i++ { + part, stop := chatGPT(msg, contextMsgs, c) + buf.WriteString(part) + if stop { + break + } + + PushEndlessProgress("Continue writing...") + } + + ret = buf.String() + ret = strings.TrimSpace(ret) + retContextMsgs = append(retContextMsgs, msg, ret) + return +} + +func chatGPT(msg string, contextMsgs []string, c *gogpt.Client) (ret string, stop bool) { var reqMsgs []gogpt.ChatCompletionMessage if 7 < len(contextMsgs) { contextMsgs = contextMsgs[len(contextMsgs)-7:] @@ -81,35 +96,30 @@ func ChatGPTContinueWrite(msg string, contextMsgs []string) (ret string, retCont } ctx, cancel := context.WithTimeout(context.Background(), OpenAIAPITimeout) defer cancel() - stream, err := c.CreateChatCompletionStream(ctx, req) + resp, err := c.CreateChatCompletion(ctx, req) if nil != err { - logging.LogErrorf("create chat completion stream failed: %s", err) + PushErrMsg("Requesting failed, please check kernel log for more details", 3000) + logging.LogErrorf("create chat completion failed: %s", err) + stop = true return } - defer stream.Close() - buf := bytes.Buffer{} - for { - resp, recvErr := stream.Recv() - if errors.Is(recvErr, io.EOF) { - break - } + if 1 > len(resp.Choices) { + stop = true + return + } - if nil != recvErr { - logging.LogErrorf("create chat completion stream recv failed: %s", recvErr) - break - } - - for _, choice := range resp.Choices { - content := choice.Delta.Content - buf.WriteString(content) - PushEndlessProgress(html.EscapeHTMLStr(buf.String())) - } + buf := &strings.Builder{} + choice := resp.Choices[0] + buf.WriteString(choice.Message.Content) + if "length" == choice.FinishReason { + stop = false + } else { + stop = true } ret = buf.String() ret = strings.TrimSpace(ret) - retContextMsgs = append(retContextMsgs, msg, ret) return } From db636d8b5b4d28594c5ed5e7fbf02c615f0b868b Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sun, 5 Mar 2023 10:33:58 +0800 Subject: [PATCH 05/10] =?UTF-8?q?:sparkles:=20=E6=A1=8C=E9=9D=A2=E7=AB=AF?= =?UTF-8?q?=E6=8E=A5=E5=85=A5=20OpenAI=20Chat=20API=20https://github.com/s?= =?UTF-8?q?iyuan-note/siyuan/issues/7560?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/util/openai.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/util/openai.go b/kernel/util/openai.go index 5a549239d..db71654c4 100644 --- a/kernel/util/openai.go +++ b/kernel/util/openai.go @@ -63,7 +63,7 @@ func ChatGPTContinueWrite(msg string, contextMsgs []string) (ret string, retCont break } - PushEndlessProgress("Continue writing...") + PushEndlessProgress("Continue requesting...") } ret = buf.String() From 436f487171a1697e67a433dc4a23833b50cc98d7 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sun, 5 Mar 2023 11:27:26 +0800 Subject: [PATCH 06/10] =?UTF-8?q?:art:=20=E5=9D=97=E7=BA=A7=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=20`=E4=BA=BA=E5=B7=A5=E6=99=BA=E8=83=BD`=20https://gi?= =?UTF-8?q?thub.com/siyuan-note/siyuan/issues/7566?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/api/ai.go | 18 +++++++++++++++--- kernel/api/router.go | 1 + kernel/model/ai.go | 41 +++++++++++++++++++++++++++++++++++++++++ kernel/util/openai.go | 2 ++ 4 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 kernel/model/ai.go diff --git a/kernel/api/ai.go b/kernel/api/ai.go index 0182b7916..1def61b5b 100644 --- a/kernel/api/ai.go +++ b/kernel/api/ai.go @@ -35,10 +35,22 @@ func chatGPT(c *gin.Context) { } msg := arg["msg"].(string) - if "" == util.OpenAIAPIKey { - util.PushMsg(model.Conf.Language(193), 5000) + ret.Data = model.ChatGPT(msg) +} + +func chatGPTContinueWriteBlocks(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { return } - ret.Data = util.ChatGPT(msg) + idsArg := arg["ids"].([]interface{}) + var ids []string + for _, id := range idsArg { + ids = append(ids, id.(string)) + } + ret.Data = model.ChatGPTContinueWriteBlocks(ids) } diff --git a/kernel/api/router.go b/kernel/api/router.go index 32ec0addb..2030ed49c 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -329,4 +329,5 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/av/renderAttributeView", model.CheckAuth, renderAttributeView) ginServer.Handle("POST", "/api/ai/chatGPT", model.CheckAuth, chatGPT) + ginServer.Handle("POST", "/api/ai/chatGPTContinueWriteBlocks", model.CheckAuth, chatGPTContinueWriteBlocks) } diff --git a/kernel/model/ai.go b/kernel/model/ai.go new file mode 100644 index 000000000..7f73840cf --- /dev/null +++ b/kernel/model/ai.go @@ -0,0 +1,41 @@ +// SiYuan - Build Your Eternal Digital Garden +// Copyright (c) 2020-present, b3log.org +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package model + +import ( + "bytes" + + "github.com/siyuan-note/siyuan/kernel/sql" + "github.com/siyuan-note/siyuan/kernel/util" +) + +func ChatGPTContinueWriteBlocks(ids []string) (ret string) { + sqlBlocks := sql.GetBlocks(ids) + + buf := bytes.Buffer{} + for _, sqlBlock := range sqlBlocks { + buf.WriteString(sqlBlock.Content) + buf.WriteString("\n\n") + } + + msg := buf.String() + ret, _ = util.ChatGPTContinueWrite(msg, nil) + return +} +func ChatGPT(msg string) (ret string) { + return util.ChatGPT(msg) +} diff --git a/kernel/util/openai.go b/kernel/util/openai.go index db71654c4..083063a68 100644 --- a/kernel/util/openai.go +++ b/kernel/util/openai.go @@ -19,6 +19,7 @@ package util import ( "bytes" "context" + "github.com/siyuan-note/siyuan/kernel/model" "net/http" "net/url" "os" @@ -47,6 +48,7 @@ func ChatGPT(msg string) (ret string) { func ChatGPTContinueWrite(msg string, contextMsgs []string) (ret string, retContextMsgs []string) { if "" == OpenAIAPIKey { + PushMsg(model.Conf.Language(193), 5000) return } From cc1bb7775a567bc65c91a7e98ee332e0239bcba5 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sun, 5 Mar 2023 11:30:25 +0800 Subject: [PATCH 07/10] =?UTF-8?q?:art:=20=E5=9D=97=E7=BA=A7=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=20`=E4=BA=BA=E5=B7=A5=E6=99=BA=E8=83=BD`=20https://gi?= =?UTF-8?q?thub.com/siyuan-note/siyuan/issues/7566?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/api/ai.go | 2 +- kernel/model/ai.go | 10 ++++++++++ kernel/util/openai.go | 2 -- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/kernel/api/ai.go b/kernel/api/ai.go index 1def61b5b..2aa5b1005 100644 --- a/kernel/api/ai.go +++ b/kernel/api/ai.go @@ -17,11 +17,11 @@ package api import ( - "github.com/siyuan-note/siyuan/kernel/model" "net/http" "github.com/88250/gulu" "github.com/gin-gonic/gin" + "github.com/siyuan-note/siyuan/kernel/model" "github.com/siyuan-note/siyuan/kernel/util" ) diff --git a/kernel/model/ai.go b/kernel/model/ai.go index 7f73840cf..d82a7ab77 100644 --- a/kernel/model/ai.go +++ b/kernel/model/ai.go @@ -24,6 +24,11 @@ import ( ) func ChatGPTContinueWriteBlocks(ids []string) (ret string) { + if "" == util.OpenAIAPIKey { + util.PushMsg(Conf.Language(193), 5000) + return + } + sqlBlocks := sql.GetBlocks(ids) buf := bytes.Buffer{} @@ -37,5 +42,10 @@ func ChatGPTContinueWriteBlocks(ids []string) (ret string) { return } func ChatGPT(msg string) (ret string) { + if "" == util.OpenAIAPIKey { + util.PushMsg(Conf.Language(193), 5000) + return + } + return util.ChatGPT(msg) } diff --git a/kernel/util/openai.go b/kernel/util/openai.go index 083063a68..db71654c4 100644 --- a/kernel/util/openai.go +++ b/kernel/util/openai.go @@ -19,7 +19,6 @@ package util import ( "bytes" "context" - "github.com/siyuan-note/siyuan/kernel/model" "net/http" "net/url" "os" @@ -48,7 +47,6 @@ func ChatGPT(msg string) (ret string) { func ChatGPTContinueWrite(msg string, contextMsgs []string) (ret string, retContextMsgs []string) { if "" == OpenAIAPIKey { - PushMsg(model.Conf.Language(193), 5000) return } From ba400854b0a19d164c393e1244c6e6897bef2f88 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sun, 5 Mar 2023 11:31:36 +0800 Subject: [PATCH 08/10] =?UTF-8?q?:art:=20=E5=9D=97=E7=BA=A7=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=20`=E4=BA=BA=E5=B7=A5=E6=99=BA=E8=83=BD`=20https://gi?= =?UTF-8?q?thub.com/siyuan-note/siyuan/issues/7566?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/ai.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/kernel/model/ai.go b/kernel/model/ai.go index d82a7ab77..de3f1872a 100644 --- a/kernel/model/ai.go +++ b/kernel/model/ai.go @@ -24,8 +24,7 @@ import ( ) func ChatGPTContinueWriteBlocks(ids []string) (ret string) { - if "" == util.OpenAIAPIKey { - util.PushMsg(Conf.Language(193), 5000) + if !isOpenAIAPIEnabled() { return } @@ -41,11 +40,19 @@ func ChatGPTContinueWriteBlocks(ids []string) (ret string) { ret, _ = util.ChatGPTContinueWrite(msg, nil) return } + func ChatGPT(msg string) (ret string) { - if "" == util.OpenAIAPIKey { - util.PushMsg(Conf.Language(193), 5000) + if !isOpenAIAPIEnabled() { return } return util.ChatGPT(msg) } + +func isOpenAIAPIEnabled() bool { + if "" == util.OpenAIAPIKey { + util.PushMsg(Conf.Language(193), 5000) + return false + } + return true +} From 69c18db9ed799e1108fb9d461d4cd85bdd42678e Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sun, 5 Mar 2023 11:49:57 +0800 Subject: [PATCH 09/10] =?UTF-8?q?:art:=20=E5=9D=97=E7=BA=A7=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=20`=E4=BA=BA=E5=B7=A5=E6=99=BA=E8=83=BD`=20https://gi?= =?UTF-8?q?thub.com/siyuan-note/siyuan/issues/7566?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/api/ai.go | 35 +++++++++++++++++++++++++++++++++++ kernel/api/router.go | 2 ++ kernel/model/ai.go | 41 ++++++++++++++++++++++++++++++++--------- kernel/util/openai.go | 12 ++++++++++++ 4 files changed, 81 insertions(+), 9 deletions(-) diff --git a/kernel/api/ai.go b/kernel/api/ai.go index 2aa5b1005..13717e233 100644 --- a/kernel/api/ai.go +++ b/kernel/api/ai.go @@ -54,3 +54,38 @@ func chatGPTContinueWriteBlocks(c *gin.Context) { } ret.Data = model.ChatGPTContinueWriteBlocks(ids) } + +func chatGPTTranslate(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + idsArg := arg["ids"].([]interface{}) + var ids []string + for _, id := range idsArg { + ids = append(ids, id.(string)) + } + lang := arg["lang"].(string) + ret.Data = model.ChatGPTTranslate(ids, lang) +} + +func chatGPTSummary(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + idsArg := arg["ids"].([]interface{}) + var ids []string + for _, id := range idsArg { + ids = append(ids, id.(string)) + } + ret.Data = model.ChatGPTSummary(ids) +} diff --git a/kernel/api/router.go b/kernel/api/router.go index 2030ed49c..de415a515 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -330,4 +330,6 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/ai/chatGPT", model.CheckAuth, chatGPT) ginServer.Handle("POST", "/api/ai/chatGPTContinueWriteBlocks", model.CheckAuth, chatGPTContinueWriteBlocks) + ginServer.Handle("POST", "/api/ai/chatGPTTranslate", model.CheckAuth, chatGPTTranslate) + ginServer.Handle("POST", "/api/ai/chatGPTSummary", model.CheckAuth, chatGPTSummary) } diff --git a/kernel/model/ai.go b/kernel/model/ai.go index de3f1872a..401e69014 100644 --- a/kernel/model/ai.go +++ b/kernel/model/ai.go @@ -23,20 +23,32 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) +func ChatGPTSummary(ids []string) (ret string) { + if !isOpenAIAPIEnabled() { + return + } + + msg := getBlocksContent(ids) + ret = util.ChatGPTSummary(msg, Conf.Lang) + return +} + +func ChatGPTTranslate(ids []string, lang string) (ret string) { + if !isOpenAIAPIEnabled() { + return + } + + msg := getBlocksContent(ids) + ret = util.ChatGPTTranslate(msg, lang) + return +} + func ChatGPTContinueWriteBlocks(ids []string) (ret string) { if !isOpenAIAPIEnabled() { return } - sqlBlocks := sql.GetBlocks(ids) - - buf := bytes.Buffer{} - for _, sqlBlock := range sqlBlocks { - buf.WriteString(sqlBlock.Content) - buf.WriteString("\n\n") - } - - msg := buf.String() + msg := getBlocksContent(ids) ret, _ = util.ChatGPTContinueWrite(msg, nil) return } @@ -56,3 +68,14 @@ func isOpenAIAPIEnabled() bool { } return true } + +func getBlocksContent(ids []string) string { + sqlBlocks := sql.GetBlocks(ids) + buf := bytes.Buffer{} + for _, sqlBlock := range sqlBlocks { + buf.WriteString(sqlBlock.Content) + buf.WriteString("\n\n") + } + + return buf.String() +} diff --git a/kernel/util/openai.go b/kernel/util/openai.go index db71654c4..ca98d6528 100644 --- a/kernel/util/openai.go +++ b/kernel/util/openai.go @@ -45,6 +45,18 @@ func ChatGPT(msg string) (ret string) { return } +func ChatGPTTranslate(msg string, lang string) (ret string) { + msg = "Translate to " + lang + ":\n" + msg + ret, _ = ChatGPTContinueWrite(msg, nil) + return +} + +func ChatGPTSummary(msg string, lang string) (ret string) { + msg = "Summarized as follows, the result is in {" + lang + "}:\n" + msg + ret, _ = ChatGPTContinueWrite(msg, nil) + return +} + func ChatGPTContinueWrite(msg string, contextMsgs []string) (ret string, retContextMsgs []string) { if "" == OpenAIAPIKey { return From e09b37e2855bf6af8fa4c8a0e3b3f45ae6fbc176 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sun, 5 Mar 2023 12:16:47 +0800 Subject: [PATCH 10/10] =?UTF-8?q?:art:=20=E5=9D=97=E7=BA=A7=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=20`=E4=BA=BA=E5=B7=A5=E6=99=BA=E8=83=BD`=20https://gi?= =?UTF-8?q?thub.com/siyuan-note/siyuan/issues/7566?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/ai.go | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/kernel/model/ai.go b/kernel/model/ai.go index 401e69014..bc48dc5a9 100644 --- a/kernel/model/ai.go +++ b/kernel/model/ai.go @@ -19,7 +19,9 @@ package model import ( "bytes" - "github.com/siyuan-note/siyuan/kernel/sql" + "github.com/88250/lute/ast" + "github.com/88250/lute/parse" + "github.com/siyuan-note/siyuan/kernel/treenode" "github.com/siyuan-note/siyuan/kernel/util" ) @@ -70,12 +72,40 @@ func isOpenAIAPIEnabled() bool { } func getBlocksContent(ids []string) string { - sqlBlocks := sql.GetBlocks(ids) - buf := bytes.Buffer{} - for _, sqlBlock := range sqlBlocks { - buf.WriteString(sqlBlock.Content) - buf.WriteString("\n\n") + var nodes []*ast.Node + trees := map[string]*parse.Tree{} + for _, id := range ids { + bt := treenode.GetBlockTree(id) + if nil == bt { + continue + } + + var tree *parse.Tree + if tree = trees[bt.RootID]; nil == tree { + tree, _ = loadTreeByBlockID(bt.RootID) + if nil == tree { + continue + } + + trees[bt.RootID] = tree + } + + if node := treenode.GetNodeInTree(tree, id); nil != node { + if ast.NodeDocument == node.Type { + for child := node.FirstChild; nil != child; child = child.Next { + nodes = append(nodes, child) + } + } else { + nodes = append(nodes, node) + } + } } + buf := bytes.Buffer{} + for _, node := range nodes { + content := treenode.NodeStaticContent(node, nil, true) + buf.WriteString(content) + buf.WriteString("\n\n") + } return buf.String() }