Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
3f95ee9527
6 changed files with 156 additions and 0 deletions
38
kernel/api/ai.go
Normal file
38
kernel/api/ai.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/88250/gulu"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
)
|
||||
|
||||
func chatGPT(c *gin.Context) {
|
||||
ret := gulu.Ret.NewResult()
|
||||
defer c.JSON(http.StatusOK, ret)
|
||||
|
||||
arg, ok := util.JsonArg(c, ret)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
msg := arg["msg"].(string)
|
||||
ret.Data = util.ChatGPT(msg)
|
||||
}
|
|
@ -327,4 +327,6 @@ func ServeAPI(ginServer *gin.Engine) {
|
|||
ginServer.Handle("GET", "/snippets/*filepath", serveSnippets)
|
||||
|
||||
ginServer.Handle("POST", "/api/av/renderAttributeView", model.CheckAuth, renderAttributeView)
|
||||
|
||||
ginServer.Handle("POST", "/api/ai/chatGPT", model.CheckAuth, chatGPT)
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ require (
|
|||
github.com/panjf2000/ants/v2 v2.7.1
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/radovskyb/watcher v1.0.7
|
||||
github.com/sashabaranov/go-gpt3 v1.3.3
|
||||
github.com/shirou/gopsutil/v3 v3.23.1
|
||||
github.com/siyuan-note/dejavu v0.0.0-20230223101417-691d54268764
|
||||
github.com/siyuan-note/encryption v0.0.0-20220713091850-5ecd92177b75
|
||||
|
|
|
@ -266,6 +266,8 @@ github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUA
|
|||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI=
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
|
||||
github.com/sashabaranov/go-gpt3 v1.3.3 h1:S8Zd4YybnBaNMK+w+XGGWgsjQY1R+6QE2n9SLzVna9k=
|
||||
github.com/sashabaranov/go-gpt3 v1.3.3/go.mod h1:BIZdbwdzxZbCrcKGMGH6u2eyGe1xFuX9Anmh3tCP8lQ=
|
||||
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
|
||||
github.com/shirou/gopsutil/v3 v3.23.1 h1:a9KKO+kGLKEvcPIs4W62v0nu3sciVDOOOPUD0Hz7z/4=
|
||||
github.com/shirou/gopsutil/v3 v3.23.1/go.mod h1:NN6mnm5/0k8jw4cBfCnJtr5L7ErOTg18tMNpgFkn0hA=
|
||||
|
|
111
kernel/util/openai.go
Normal file
111
kernel/util/openai.go
Normal file
|
@ -0,0 +1,111 @@
|
|||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
gogpt "github.com/sashabaranov/go-gpt3"
|
||||
"github.com/siyuan-note/logging"
|
||||
)
|
||||
|
||||
var (
|
||||
OpenAIAPIKey = ""
|
||||
OpenAIAPITimeout = 15 * time.Second
|
||||
OpenAIAPIProxy = ""
|
||||
OpenAIAPIMaxTokens = 4096
|
||||
)
|
||||
|
||||
func ChatGPT(msg string) (ret string) {
|
||||
if "" == OpenAIAPIKey {
|
||||
return
|
||||
}
|
||||
|
||||
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 := gogpt.NewClientWithConfig(config)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), OpenAIAPITimeout)
|
||||
defer cancel()
|
||||
req := gogpt.ChatCompletionRequest{
|
||||
Model: gogpt.GPT3Dot5Turbo,
|
||||
MaxTokens: OpenAIAPIMaxTokens,
|
||||
Messages: []gogpt.ChatCompletionMessage{
|
||||
{
|
||||
Role: "user",
|
||||
Content: msg,
|
||||
},
|
||||
},
|
||||
}
|
||||
resp, err := c.CreateChatCompletion(ctx, req)
|
||||
if nil != err {
|
||||
logging.LogErrorf("create chat completion failed: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if 0 < len(resp.Choices) {
|
||||
ret = resp.Choices[0].Message.Content
|
||||
ret = strings.TrimSpace(ret)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func initOpenAI() {
|
||||
OpenAIAPIKey = os.Getenv("SIYUAN_OPENAI_API_KEY")
|
||||
if "" == OpenAIAPIKey {
|
||||
return
|
||||
}
|
||||
|
||||
timeout := os.Getenv("SIYUAN_OPENAI_API_TIMEOUT")
|
||||
if "" != timeout {
|
||||
timeoutInt, err := strconv.Atoi(timeout)
|
||||
if nil == err {
|
||||
OpenAIAPITimeout = time.Duration(timeoutInt) * time.Second
|
||||
}
|
||||
}
|
||||
|
||||
proxy := os.Getenv("SIYUAN_OPENAI_API_PROXY")
|
||||
if "" != proxy {
|
||||
OpenAIAPIProxy = proxy
|
||||
}
|
||||
|
||||
maxTokens := os.Getenv("SIYUAN_OPENAI_API_MAX_TOKENS")
|
||||
if "" != maxTokens {
|
||||
maxTokensInt, err := strconv.Atoi(maxTokens)
|
||||
if nil == err {
|
||||
OpenAIAPIMaxTokens = maxTokensInt
|
||||
}
|
||||
}
|
||||
if 1 > OpenAIAPIMaxTokens {
|
||||
OpenAIAPIMaxTokens = 4096
|
||||
}
|
||||
|
||||
logging.LogInfof("OpenAI API enabled [maxTokens=%d, timeout=%ds, proxy=%s]", OpenAIAPIMaxTokens, int(OpenAIAPITimeout.Seconds()), OpenAIAPIProxy)
|
||||
}
|
|
@ -118,6 +118,8 @@ func Boot() {
|
|||
bootBanner := figure.NewColorFigure("SiYuan", "isometric3", "green", true)
|
||||
logging.LogInfof("\n" + bootBanner.String())
|
||||
logBootInfo()
|
||||
|
||||
initOpenAI()
|
||||
}
|
||||
|
||||
func setBootDetails(details string) {
|
||||
|
|
Loading…
Add table
Reference in a new issue