enhance: chat with LLM

This commit is contained in:
Jacky 2024-05-02 12:49:01 +08:00
parent e84ea98be9
commit 642e21a260
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
40 changed files with 544 additions and 250 deletions

View file

@ -1,8 +1,6 @@
root = true root = true
[*] [*]
block_comment_start = /*
block_comment_end = */
charset = utf-8 charset = utf-8
indent_style = space indent_style = space
indent_size = 2 indent_size = 2

View file

@ -23,7 +23,7 @@ func GetEnvironment(c *gin.Context) {
return return
} }
c.JSON(http.StatusOK, env) c.JSON(http.StatusOK, analytic.GetNode(env))
} }
func GetEnvironmentList(c *gin.Context) { func GetEnvironmentList(c *gin.Context) {

View file

@ -1,52 +1,52 @@
package config package config
import ( import (
"github.com/0xJacky/Nginx-UI/api" "github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/config" "github.com/0xJacky/Nginx-UI/internal/config"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
"net/http" "net/http"
"os" "os"
) )
func GetConfig(c *gin.Context) { func GetConfig(c *gin.Context) {
name := c.Param("name") name := c.Param("name")
path := nginx.GetConfPath("/", name) path := nginx.GetConfPath("/", name)
stat, err := os.Stat(path) stat, err := os.Stat(path)
if err != nil { if err != nil {
api.ErrHandler(c, err) api.ErrHandler(c, err)
return return
} }
content, err := os.ReadFile(path) content, err := os.ReadFile(path)
if err != nil { if err != nil {
api.ErrHandler(c, err) api.ErrHandler(c, err)
return return
} }
g := query.ChatGPTLog g := query.ChatGPTLog
chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate() chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) api.ErrHandler(c, err)
return return
} }
if chatgpt.Content == nil { if chatgpt.Content == nil {
chatgpt.Content = make([]openai.ChatCompletionMessage, 0) chatgpt.Content = make([]openai.ChatCompletionMessage, 0)
} }
c.JSON(http.StatusOK, config.Config{ c.JSON(http.StatusOK, config.Config{
Name: name, Name: stat.Name(),
Content: string(content), Content: string(content),
ChatGPTMessages: chatgpt.Content, ChatGPTMessages: chatgpt.Content,
FilePath: path, FilePath: path,
ModifiedAt: stat.ModTime(), ModifiedAt: stat.ModTime(),
}) })
} }

View file

@ -1,123 +1,132 @@
package openai package openai
import ( import (
"context" "context"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/0xJacky/Nginx-UI/api" "github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/settings" "github.com/0xJacky/Nginx-UI/internal/chatbot"
"github.com/gin-gonic/gin" "github.com/0xJacky/Nginx-UI/settings"
"github.com/pkg/errors" "github.com/gin-gonic/gin"
"github.com/sashabaranov/go-openai" "github.com/pkg/errors"
"io" "github.com/sashabaranov/go-openai"
"net/http" "io"
"net/url" "net/http"
"os" "net/url"
) )
const ChatGPTInitPrompt = "You are a assistant who can help users write and optimise the configurations of Nginx, the first user message contains the content of the configuration file which is currently opened by the user and the current language code(CLC). You suppose to use the language corresponding to the CLC to give the first reply. Later the language environment depends on the user message. The first reply should involve the key information of the file and ask user what can you help them." const ChatGPTInitPrompt = `You are a assistant who can help users write and optimise the configurations of Nginx,
the first user message contains the content of the configuration file which is currently opened by the user and
the current language code(CLC). You suppose to use the language corresponding to the CLC to give the first reply.
Later the language environment depends on the user message.
The first reply should involve the key information of the file and ask user what can you help them.`
func MakeChatCompletionRequest(c *gin.Context) { func MakeChatCompletionRequest(c *gin.Context) {
var json struct { var json struct {
Messages []openai.ChatCompletionMessage `json:"messages"` Filepath string `json:"filepath"`
} Messages []openai.ChatCompletionMessage `json:"messages"`
}
if !api.BindAndValid(c, &json) { if !api.BindAndValid(c, &json) {
return return
} }
messages := []openai.ChatCompletionMessage{ messages := []openai.ChatCompletionMessage{
{ {
Role: openai.ChatMessageRoleSystem, Role: openai.ChatMessageRoleSystem,
Content: ChatGPTInitPrompt, Content: ChatGPTInitPrompt,
}, },
} }
messages = append(messages, json.Messages...)
// sse server
c.Writer.Header().Set("Content-Type", "text/event-stream; charset=utf-8")
c.Writer.Header().Set("Cache-Control", "no-cache")
c.Writer.Header().Set("Connection", "keep-alive")
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
config := openai.DefaultConfig(settings.OpenAISettings.Token) messages = append(messages, json.Messages...)
if settings.OpenAISettings.Proxy != "" { if json.Filepath != "" {
proxyUrl, err := url.Parse(settings.OpenAISettings.Proxy) messages = chatbot.ChatCompletionWithContext(json.Filepath, messages)
if err != nil { }
c.Stream(func(w io.Writer) bool {
c.SSEvent("message", gin.H{
"type": "error",
"content": err.Error(),
})
return false
})
return
}
transport := &http.Transport{
Proxy: http.ProxyURL(proxyUrl),
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
config.HTTPClient = &http.Client{
Transport: transport,
}
}
if settings.OpenAISettings.BaseUrl != "" { // SSE server
config.BaseURL = settings.OpenAISettings.BaseUrl c.Writer.Header().Set("Content-Type", "text/event-stream; charset=utf-8")
} c.Writer.Header().Set("Cache-Control", "no-cache")
c.Writer.Header().Set("Connection", "keep-alive")
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
openaiClient := openai.NewClientWithConfig(config) config := openai.DefaultConfig(settings.OpenAISettings.Token)
ctx := context.Background()
req := openai.ChatCompletionRequest{ if settings.OpenAISettings.Proxy != "" {
Model: settings.OpenAISettings.Model, proxyUrl, err := url.Parse(settings.OpenAISettings.Proxy)
Messages: messages, if err != nil {
Stream: true, c.Stream(func(w io.Writer) bool {
} c.SSEvent("message", gin.H{
stream, err := openaiClient.CreateChatCompletionStream(ctx, req) "type": "error",
if err != nil { "content": err.Error(),
fmt.Printf("CompletionStream error: %v\n", err) })
c.Stream(func(w io.Writer) bool { return false
c.SSEvent("message", gin.H{ })
"type": "error", return
"content": err.Error(), }
}) transport := &http.Transport{
return false Proxy: http.ProxyURL(proxyUrl),
}) TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
return }
} config.HTTPClient = &http.Client{
defer stream.Close() Transport: transport,
msgChan := make(chan string) }
go func() { }
defer close(msgChan)
for {
response, err := stream.Recv()
if errors.Is(err, io.EOF) {
fmt.Println()
return
}
if err != nil { if settings.OpenAISettings.BaseUrl != "" {
fmt.Printf("Stream error: %v\n", err) config.BaseURL = settings.OpenAISettings.BaseUrl
return }
}
message := fmt.Sprintf("%s", response.Choices[0].Delta.Content) openaiClient := openai.NewClientWithConfig(config)
fmt.Printf("%s", message) ctx := context.Background()
_ = os.Stdout.Sync()
msgChan <- message req := openai.ChatCompletionRequest{
} Model: settings.OpenAISettings.Model,
}() Messages: messages,
Stream: true,
}
stream, err := openaiClient.CreateChatCompletionStream(ctx, req)
if err != nil {
fmt.Printf("CompletionStream error: %v\n", err)
c.Stream(func(w io.Writer) bool {
c.SSEvent("message", gin.H{
"type": "error",
"content": err.Error(),
})
return false
})
return
}
defer stream.Close()
msgChan := make(chan string)
go func() {
defer close(msgChan)
for {
response, err := stream.Recv()
if errors.Is(err, io.EOF) {
fmt.Println()
return
}
c.Stream(func(w io.Writer) bool { if err != nil {
if m, ok := <-msgChan; ok { fmt.Printf("Stream error: %v\n", err)
c.SSEvent("message", gin.H{ return
"type": "message", }
"content": m,
}) message := fmt.Sprintf("%s", response.Choices[0].Delta.Content)
return true
} msgChan <- message
return false }
}) }()
c.Stream(func(w io.Writer) bool {
if m, ok := <-msgChan; ok {
c.SSEvent("message", gin.H{
"type": "message",
"content": m,
})
return true
}
return false
})
} }

View file

@ -4,6 +4,6 @@ import "github.com/gin-gonic/gin"
func InitRouter(r *gin.RouterGroup) { func InitRouter(r *gin.RouterGroup) {
// ChatGPT // ChatGPT
r.POST("chat_gpt", MakeChatCompletionRequest) r.POST("chatgpt", MakeChatCompletionRequest)
r.POST("chat_gpt_record", StoreChatGPTRecord) r.POST("chatgpt_record", StoreChatGPTRecord)
} }

View file

@ -132,6 +132,7 @@ func GetDomain(c *gin.Context) {
Config: string(origContent), Config: string(origContent),
AutoCert: certModel.AutoCert == model.AutoCertEnabled, AutoCert: certModel.AutoCert == model.AutoCertEnabled,
ChatGPTMessages: chatgpt.Content, ChatGPTMessages: chatgpt.Content,
Filepath: path,
}) })
return return
} }
@ -173,6 +174,7 @@ func GetDomain(c *gin.Context) {
AutoCert: certModel.AutoCert == model.AutoCertEnabled, AutoCert: certModel.AutoCert == model.AutoCertEnabled,
CertInfo: certInfoMap, CertInfo: certInfoMap,
ChatGPTMessages: chatgpt.Content, ChatGPTMessages: chatgpt.Content,
Filepath: path,
}) })
} }

View file

@ -17,4 +17,5 @@ type Site struct {
ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"` ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"`
Tokenized *nginx.NgxConfig `json:"tokenized,omitempty"` Tokenized *nginx.NgxConfig `json:"tokenized,omitempty"`
CertInfo map[int]*cert.Info `json:"cert_info,omitempty"` CertInfo map[int]*cert.Info `json:"cert_info,omitempty"`
Filepath string `json:"filepath"`
} }

View file

@ -22,6 +22,7 @@ type Stream struct {
Config string `json:"config"` Config string `json:"config"`
ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"` ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"`
Tokenized *nginx.NgxConfig `json:"tokenized,omitempty"` Tokenized *nginx.NgxConfig `json:"tokenized,omitempty"`
Filepath string `json:"filepath"`
} }
func GetStreams(c *gin.Context) { func GetStreams(c *gin.Context) {
@ -133,6 +134,7 @@ func GetStream(c *gin.Context) {
Name: name, Name: name,
Config: string(origContent), Config: string(origContent),
ChatGPTMessages: chatgpt.Content, ChatGPTMessages: chatgpt.Content,
Filepath: path,
}) })
return return
} }
@ -152,6 +154,7 @@ func GetStream(c *gin.Context) {
Config: nginxConfig.FmtCode(), Config: nginxConfig.FmtCode(),
Tokenized: nginxConfig, Tokenized: nginxConfig,
ChatGPTMessages: chatgpt.Content, ChatGPTMessages: chatgpt.Content,
Filepath: path,
}) })
} }

View file

@ -5,7 +5,7 @@ export interface Config {
name: string name: string
content: string content: string
chatgpt_messages: ChatComplicationMessage[] chatgpt_messages: ChatComplicationMessage[]
file_path: string filepath: string
modified_at: string modified_at: string
} }

View file

@ -10,6 +10,7 @@ export interface Site {
advanced: boolean advanced: boolean
enabled: boolean enabled: boolean
name: string name: string
filepath: string
config: string config: string
auto_cert: boolean auto_cert: boolean
chatgpt_messages: ChatComplicationMessage[] chatgpt_messages: ChatComplicationMessage[]

View file

@ -8,7 +8,7 @@ export interface ChatComplicationMessage {
const openai = { const openai = {
store_record(data: { file_name?: string; messages?: ChatComplicationMessage[] }) { store_record(data: { file_name?: string; messages?: ChatComplicationMessage[] }) {
return http.post('/chat_gpt_record', data) return http.post('/chatgpt_record', data)
}, },
} }

View file

@ -8,6 +8,7 @@ export interface Stream {
advanced: boolean advanced: boolean
enabled: boolean enabled: boolean
name: string name: string
filepath: string
config: string config: string
chatgpt_messages: ChatComplicationMessage[] chatgpt_messages: ChatComplicationMessage[]
tokenized?: NgxConfig tokenized?: NgxConfig

View file

@ -49,26 +49,18 @@ async function request() {
const { token } = storeToRefs(user) const { token } = storeToRefs(user)
console.log('fetching...')
messages.value?.push(t.value) messages.value?.push(t.value)
emit('update:history_messages', messages.value) emit('update:history_messages', messages.value)
const res = await fetch(urlJoin(window.location.pathname, '/api/chat_gpt'), { const res = await fetch(urlJoin(window.location.pathname, '/api/chatgpt'), {
method: 'POST', method: 'POST',
headers: { Accept: 'text/event-stream', Authorization: token.value }, headers: { Accept: 'text/event-stream', Authorization: token.value },
body: JSON.stringify({ messages: messages.value?.slice(0, messages.value?.length - 1) }), body: JSON.stringify({ filepath: props.path, messages: messages.value?.slice(0, messages.value?.length - 1) }),
}) })
// read body as stream
console.info('reading...')
const reader = res.body!.getReader() const reader = res.body!.getReader()
// read stream
console.info('reading stream...')
let buffer = '' let buffer = ''
let hasCodeBlockIndicator = false let hasCodeBlockIndicator = false
@ -76,7 +68,6 @@ async function request() {
while (true) { while (true) {
const { done, value } = await reader.read() const { done, value } = await reader.read()
if (done) { if (done) {
console.info('done')
setTimeout(() => { setTimeout(() => {
scrollToBottom() scrollToBottom()
}, 500) }, 500)

View file

@ -175,7 +175,7 @@ msgstr "Base information"
#: src/views/config/ConfigEdit.vue:116 #: src/views/config/ConfigEdit.vue:116
#: src/views/domain/components/RightSettings.vue:76 #: src/views/domain/components/RightSettings.vue:76
#: src/views/preference/Preference.vue:93 #: src/views/preference/Preference.vue:94
#: src/views/stream/components/RightSettings.vue:76 #: src/views/stream/components/RightSettings.vue:76
#, fuzzy #, fuzzy
msgid "Basic" msgid "Basic"
@ -650,6 +650,10 @@ msgstr "Enable failed"
msgid "Enable successfully" msgid "Enable successfully"
msgstr "Enabled successfully" msgstr "Enabled successfully"
#: src/views/preference/OpenAISettings.vue:67
msgid "Enable this option will significantly increase the token usage."
msgstr ""
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175
msgid "Enable TLS" msgid "Enable TLS"
msgstr "Enable TLS" msgstr "Enable TLS"
@ -967,7 +971,7 @@ msgstr "Login successful"
msgid "Logout successful" msgid "Logout successful"
msgstr "Logout successful" msgstr "Logout successful"
#: src/views/preference/Preference.vue:111 #: src/views/preference/Preference.vue:112
msgid "Logrotate" msgid "Logrotate"
msgstr "" msgstr ""
@ -1097,7 +1101,7 @@ msgstr ""
msgid "Next" msgid "Next"
msgstr "Next" msgstr "Next"
#: src/views/preference/Preference.vue:99 #: src/views/preference/Preference.vue:100
msgid "Nginx" msgid "Nginx"
msgstr "" msgstr ""
@ -1225,7 +1229,7 @@ msgstr ""
msgid "Online" msgid "Online"
msgstr "" msgstr ""
#: src/views/preference/Preference.vue:105 #: src/views/preference/Preference.vue:106
msgid "OpenAI" msgid "OpenAI"
msgstr "" msgstr ""
@ -1319,7 +1323,7 @@ msgstr ""
msgid "Pre-release" msgid "Pre-release"
msgstr "" msgstr ""
#: src/routes/index.ts:239 src/views/preference/Preference.vue:88 #: src/routes/index.ts:239 src/views/preference/Preference.vue:89
msgid "Preference" msgid "Preference"
msgstr "" msgstr ""
@ -1472,7 +1476,7 @@ msgstr ""
#: src/views/certificate/CertificateEditor.vue:242 #: src/views/certificate/CertificateEditor.vue:242
#: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260 #: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120
#: src/views/preference/Preference.vue:122 src/views/stream/StreamEdit.vue:251 #: src/views/preference/Preference.vue:123 src/views/stream/StreamEdit.vue:251
msgid "Save" msgid "Save"
msgstr "Save" msgstr "Save"
@ -1488,7 +1492,7 @@ msgstr "Save error %{msg}"
#: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104
#: src/views/certificate/CertificateEditor.vue:45 #: src/views/certificate/CertificateEditor.vue:45
#: src/views/preference/Preference.vue:58 #: src/views/preference/Preference.vue:59
#, fuzzy #, fuzzy
msgid "Save successfully" msgid "Save successfully"
msgstr "Saved successfully" msgstr "Saved successfully"
@ -1513,6 +1517,10 @@ msgstr ""
msgid "Send" msgid "Send"
msgstr "Send" msgstr "Send"
#: src/views/preference/OpenAISettings.vue:66
msgid "Send Include Context"
msgstr ""
#: src/components/NginxControl/NginxControl.vue:28 #: src/components/NginxControl/NginxControl.vue:28
#: src/components/NginxControl/NginxControl.vue:42 #: src/components/NginxControl/NginxControl.vue:42
#: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46 #: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46
@ -1521,7 +1529,7 @@ msgstr "Send"
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:182 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:182
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:221 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:221
#: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81 #: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81
#: src/views/other/Install.vue:70 src/views/preference/Preference.vue:62 #: src/views/other/Install.vue:70 src/views/preference/Preference.vue:63
#: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
#: src/views/system/Upgrade.vue:42 #: src/views/system/Upgrade.vue:42
msgid "Server error" msgid "Server error"

View file

@ -173,7 +173,7 @@ msgstr "Información general"
#: src/views/config/ConfigEdit.vue:116 #: src/views/config/ConfigEdit.vue:116
#: src/views/domain/components/RightSettings.vue:76 #: src/views/domain/components/RightSettings.vue:76
#: src/views/preference/Preference.vue:93 #: src/views/preference/Preference.vue:94
#: src/views/stream/components/RightSettings.vue:76 #: src/views/stream/components/RightSettings.vue:76
msgid "Basic" msgid "Basic"
msgstr "Básico" msgstr "Básico"
@ -623,6 +623,10 @@ msgstr "Falló la habilitación"
msgid "Enable successfully" msgid "Enable successfully"
msgstr "Habilitado con Éxito" msgstr "Habilitado con Éxito"
#: src/views/preference/OpenAISettings.vue:67
msgid "Enable this option will significantly increase the token usage."
msgstr ""
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175
msgid "Enable TLS" msgid "Enable TLS"
msgstr "Habilitar TLS" msgstr "Habilitar TLS"
@ -925,7 +929,7 @@ msgstr "Acceso exitoso"
msgid "Logout successful" msgid "Logout successful"
msgstr "Cierre de sesión exitoso" msgstr "Cierre de sesión exitoso"
#: src/views/preference/Preference.vue:111 #: src/views/preference/Preference.vue:112
msgid "Logrotate" msgid "Logrotate"
msgstr "" msgstr ""
@ -1049,7 +1053,7 @@ msgstr "Se liberó una nueva versión"
msgid "Next" msgid "Next"
msgstr "Siguiente" msgstr "Siguiente"
#: src/views/preference/Preference.vue:99 #: src/views/preference/Preference.vue:100
msgid "Nginx" msgid "Nginx"
msgstr "Nginx" msgstr "Nginx"
@ -1171,7 +1175,7 @@ msgstr "Una vez que se complete la verificación, los registros se eliminarán."
msgid "Online" msgid "Online"
msgstr "En línea" msgstr "En línea"
#: src/views/preference/Preference.vue:105 #: src/views/preference/Preference.vue:106
msgid "OpenAI" msgid "OpenAI"
msgstr "OpenAI" msgstr "OpenAI"
@ -1273,7 +1277,7 @@ msgstr "¡Seleccione al menos un nodo!"
msgid "Pre-release" msgid "Pre-release"
msgstr "Prelanzamiento" msgstr "Prelanzamiento"
#: src/routes/index.ts:239 src/views/preference/Preference.vue:88 #: src/routes/index.ts:239 src/views/preference/Preference.vue:89
msgid "Preference" msgid "Preference"
msgstr "Configuración" msgstr "Configuración"
@ -1419,7 +1423,7 @@ msgstr "Corriendo"
#: src/views/certificate/CertificateEditor.vue:242 #: src/views/certificate/CertificateEditor.vue:242
#: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260 #: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120
#: src/views/preference/Preference.vue:122 src/views/stream/StreamEdit.vue:251 #: src/views/preference/Preference.vue:123 src/views/stream/StreamEdit.vue:251
msgid "Save" msgid "Save"
msgstr "Guardar" msgstr "Guardar"
@ -1435,7 +1439,7 @@ msgstr "Error al guardar %{msg}"
#: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104
#: src/views/certificate/CertificateEditor.vue:45 #: src/views/certificate/CertificateEditor.vue:45
#: src/views/preference/Preference.vue:58 #: src/views/preference/Preference.vue:59
msgid "Save successfully" msgid "Save successfully"
msgstr "Guardado con éxito" msgstr "Guardado con éxito"
@ -1459,6 +1463,10 @@ msgstr "Selector"
msgid "Send" msgid "Send"
msgstr "Enviado" msgstr "Enviado"
#: src/views/preference/OpenAISettings.vue:66
msgid "Send Include Context"
msgstr ""
#: src/components/NginxControl/NginxControl.vue:28 #: src/components/NginxControl/NginxControl.vue:28
#: src/components/NginxControl/NginxControl.vue:42 #: src/components/NginxControl/NginxControl.vue:42
#: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46 #: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46
@ -1467,7 +1475,7 @@ msgstr "Enviado"
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:182 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:182
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:221 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:221
#: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81 #: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81
#: src/views/other/Install.vue:70 src/views/preference/Preference.vue:62 #: src/views/other/Install.vue:70 src/views/preference/Preference.vue:63
#: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
#: src/views/system/Upgrade.vue:42 #: src/views/system/Upgrade.vue:42
msgid "Server error" msgid "Server error"

View file

@ -176,7 +176,7 @@ msgstr "Information générale"
#: src/views/config/ConfigEdit.vue:116 #: src/views/config/ConfigEdit.vue:116
#: src/views/domain/components/RightSettings.vue:76 #: src/views/domain/components/RightSettings.vue:76
#: src/views/preference/Preference.vue:93 #: src/views/preference/Preference.vue:94
#: src/views/stream/components/RightSettings.vue:76 #: src/views/stream/components/RightSettings.vue:76
msgid "Basic" msgid "Basic"
msgstr "Basique" msgstr "Basique"
@ -648,6 +648,10 @@ msgstr "Échec de l'activation"
msgid "Enable successfully" msgid "Enable successfully"
msgstr "Activé avec succès" msgstr "Activé avec succès"
#: src/views/preference/OpenAISettings.vue:67
msgid "Enable this option will significantly increase the token usage."
msgstr ""
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175
msgid "Enable TLS" msgid "Enable TLS"
msgstr "Activer TLS" msgstr "Activer TLS"
@ -966,7 +970,7 @@ msgstr "Connexion réussie"
msgid "Logout successful" msgid "Logout successful"
msgstr "Déconnexion réussie" msgstr "Déconnexion réussie"
#: src/views/preference/Preference.vue:111 #: src/views/preference/Preference.vue:112
msgid "Logrotate" msgid "Logrotate"
msgstr "" msgstr ""
@ -1094,7 +1098,7 @@ msgstr "Nouvelle version publiée"
msgid "Next" msgid "Next"
msgstr "Suivant" msgstr "Suivant"
#: src/views/preference/Preference.vue:99 #: src/views/preference/Preference.vue:100
#, fuzzy #, fuzzy
msgid "Nginx" msgid "Nginx"
msgstr "Journal Nginx" msgstr "Journal Nginx"
@ -1220,7 +1224,7 @@ msgstr ""
msgid "Online" msgid "Online"
msgstr "" msgstr ""
#: src/views/preference/Preference.vue:105 #: src/views/preference/Preference.vue:106
msgid "OpenAI" msgid "OpenAI"
msgstr "OpenAI" msgstr "OpenAI"
@ -1320,7 +1324,7 @@ msgstr ""
msgid "Pre-release" msgid "Pre-release"
msgstr "" msgstr ""
#: src/routes/index.ts:239 src/views/preference/Preference.vue:88 #: src/routes/index.ts:239 src/views/preference/Preference.vue:89
msgid "Preference" msgid "Preference"
msgstr "Préférence" msgstr "Préférence"
@ -1475,7 +1479,7 @@ msgstr "En cours d'éxécution"
#: src/views/certificate/CertificateEditor.vue:242 #: src/views/certificate/CertificateEditor.vue:242
#: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260 #: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120
#: src/views/preference/Preference.vue:122 src/views/stream/StreamEdit.vue:251 #: src/views/preference/Preference.vue:123 src/views/stream/StreamEdit.vue:251
msgid "Save" msgid "Save"
msgstr "Enregistrer" msgstr "Enregistrer"
@ -1491,7 +1495,7 @@ msgstr "Enregistrer l'erreur %{msg}"
#: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104
#: src/views/certificate/CertificateEditor.vue:45 #: src/views/certificate/CertificateEditor.vue:45
#: src/views/preference/Preference.vue:58 #: src/views/preference/Preference.vue:59
msgid "Save successfully" msgid "Save successfully"
msgstr "Sauvegarde réussie" msgstr "Sauvegarde réussie"
@ -1515,6 +1519,10 @@ msgstr "Sélecteur"
msgid "Send" msgid "Send"
msgstr "Envoyer" msgstr "Envoyer"
#: src/views/preference/OpenAISettings.vue:66
msgid "Send Include Context"
msgstr ""
#: src/components/NginxControl/NginxControl.vue:28 #: src/components/NginxControl/NginxControl.vue:28
#: src/components/NginxControl/NginxControl.vue:42 #: src/components/NginxControl/NginxControl.vue:42
#: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46 #: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46
@ -1523,7 +1531,7 @@ msgstr "Envoyer"
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:182 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:182
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:221 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:221
#: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81 #: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81
#: src/views/other/Install.vue:70 src/views/preference/Preference.vue:62 #: src/views/other/Install.vue:70 src/views/preference/Preference.vue:63
#: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
#: src/views/system/Upgrade.vue:42 #: src/views/system/Upgrade.vue:42
msgid "Server error" msgid "Server error"

View file

@ -172,7 +172,7 @@ msgstr "기본 정보"
#: src/views/config/ConfigEdit.vue:116 #: src/views/config/ConfigEdit.vue:116
#: src/views/domain/components/RightSettings.vue:76 #: src/views/domain/components/RightSettings.vue:76
#: src/views/preference/Preference.vue:93 #: src/views/preference/Preference.vue:94
#: src/views/stream/components/RightSettings.vue:76 #: src/views/stream/components/RightSettings.vue:76
msgid "Basic" msgid "Basic"
msgstr "기본" msgstr "기본"
@ -621,6 +621,10 @@ msgstr "활성화 실패"
msgid "Enable successfully" msgid "Enable successfully"
msgstr "성공적으로 활성화" msgstr "성공적으로 활성화"
#: src/views/preference/OpenAISettings.vue:67
msgid "Enable this option will significantly increase the token usage."
msgstr ""
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175
msgid "Enable TLS" msgid "Enable TLS"
msgstr "TLS 활성화" msgstr "TLS 활성화"
@ -937,7 +941,7 @@ msgstr "로그인 성공"
msgid "Logout successful" msgid "Logout successful"
msgstr "로그아웃 성공" msgstr "로그아웃 성공"
#: src/views/preference/Preference.vue:111 #: src/views/preference/Preference.vue:112
msgid "Logrotate" msgid "Logrotate"
msgstr "로그관리" msgstr "로그관리"
@ -1072,7 +1076,7 @@ msgstr "새 버전 출시"
msgid "Next" msgid "Next"
msgstr "다음" msgstr "다음"
#: src/views/preference/Preference.vue:99 #: src/views/preference/Preference.vue:100
msgid "Nginx" msgid "Nginx"
msgstr "Nginx" msgstr "Nginx"
@ -1200,7 +1204,7 @@ msgstr "검증이 완료되면, 레코드는 제거됩니다."
msgid "Online" msgid "Online"
msgstr "온라인" msgstr "온라인"
#: src/views/preference/Preference.vue:105 #: src/views/preference/Preference.vue:106
msgid "OpenAI" msgid "OpenAI"
msgstr "오픈AI" msgstr "오픈AI"
@ -1296,7 +1300,7 @@ msgstr "적어도 하나의 노드를 선택해주세요!"
msgid "Pre-release" msgid "Pre-release"
msgstr "사전 출시" msgstr "사전 출시"
#: src/routes/index.ts:239 src/views/preference/Preference.vue:88 #: src/routes/index.ts:239 src/views/preference/Preference.vue:89
msgid "Preference" msgid "Preference"
msgstr "환경설정" msgstr "환경설정"
@ -1451,7 +1455,7 @@ msgstr "실행 중"
#: src/views/certificate/CertificateEditor.vue:242 #: src/views/certificate/CertificateEditor.vue:242
#: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260 #: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120
#: src/views/preference/Preference.vue:122 src/views/stream/StreamEdit.vue:251 #: src/views/preference/Preference.vue:123 src/views/stream/StreamEdit.vue:251
msgid "Save" msgid "Save"
msgstr "저장" msgstr "저장"
@ -1467,7 +1471,7 @@ msgstr "저장 오류 %{msg}"
#: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104
#: src/views/certificate/CertificateEditor.vue:45 #: src/views/certificate/CertificateEditor.vue:45
#: src/views/preference/Preference.vue:58 #: src/views/preference/Preference.vue:59
#, fuzzy #, fuzzy
msgid "Save successfully" msgid "Save successfully"
msgstr "성공적으로 저장됨" msgstr "성공적으로 저장됨"
@ -1492,6 +1496,10 @@ msgstr "선택"
msgid "Send" msgid "Send"
msgstr "보내기" msgstr "보내기"
#: src/views/preference/OpenAISettings.vue:66
msgid "Send Include Context"
msgstr ""
#: src/components/NginxControl/NginxControl.vue:28 #: src/components/NginxControl/NginxControl.vue:28
#: src/components/NginxControl/NginxControl.vue:42 #: src/components/NginxControl/NginxControl.vue:42
#: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46 #: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46
@ -1500,7 +1508,7 @@ msgstr "보내기"
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:182 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:182
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:221 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:221
#: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81 #: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81
#: src/views/other/Install.vue:70 src/views/preference/Preference.vue:62 #: src/views/other/Install.vue:70 src/views/preference/Preference.vue:63
#: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
#: src/views/system/Upgrade.vue:42 #: src/views/system/Upgrade.vue:42
msgid "Server error" msgid "Server error"

View file

@ -167,7 +167,7 @@ msgstr ""
#: src/views/config/ConfigEdit.vue:116 #: src/views/config/ConfigEdit.vue:116
#: src/views/domain/components/RightSettings.vue:76 #: src/views/domain/components/RightSettings.vue:76
#: src/views/preference/Preference.vue:93 #: src/views/preference/Preference.vue:94
#: src/views/stream/components/RightSettings.vue:76 #: src/views/stream/components/RightSettings.vue:76
msgid "Basic" msgid "Basic"
msgstr "" msgstr ""
@ -621,6 +621,10 @@ msgstr ""
msgid "Enable successfully" msgid "Enable successfully"
msgstr "" msgstr ""
#: src/views/preference/OpenAISettings.vue:67
msgid "Enable this option will significantly increase the token usage."
msgstr ""
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175
msgid "Enable TLS" msgid "Enable TLS"
msgstr "" msgstr ""
@ -931,7 +935,7 @@ msgstr ""
msgid "Logout successful" msgid "Logout successful"
msgstr "" msgstr ""
#: src/views/preference/Preference.vue:111 #: src/views/preference/Preference.vue:112
msgid "Logrotate" msgid "Logrotate"
msgstr "" msgstr ""
@ -1049,7 +1053,7 @@ msgstr ""
msgid "Next" msgid "Next"
msgstr "" msgstr ""
#: src/views/preference/Preference.vue:99 #: src/views/preference/Preference.vue:100
msgid "Nginx" msgid "Nginx"
msgstr "" msgstr ""
@ -1174,7 +1178,7 @@ msgstr ""
msgid "Online" msgid "Online"
msgstr "" msgstr ""
#: src/views/preference/Preference.vue:105 #: src/views/preference/Preference.vue:106
msgid "OpenAI" msgid "OpenAI"
msgstr "" msgstr ""
@ -1265,7 +1269,7 @@ msgid "Pre-release"
msgstr "" msgstr ""
#: src/routes/index.ts:239 #: src/routes/index.ts:239
#: src/views/preference/Preference.vue:88 #: src/views/preference/Preference.vue:89
msgid "Preference" msgid "Preference"
msgstr "" msgstr ""
@ -1407,7 +1411,7 @@ msgstr ""
#: src/views/config/ConfigEdit.vue:97 #: src/views/config/ConfigEdit.vue:97
#: src/views/domain/DomainEdit.vue:260 #: src/views/domain/DomainEdit.vue:260
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120
#: src/views/preference/Preference.vue:122 #: src/views/preference/Preference.vue:123
#: src/views/stream/StreamEdit.vue:251 #: src/views/stream/StreamEdit.vue:251
msgid "Save" msgid "Save"
msgstr "" msgstr ""
@ -1425,7 +1429,7 @@ msgstr ""
#: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104
#: src/views/certificate/CertificateEditor.vue:45 #: src/views/certificate/CertificateEditor.vue:45
#: src/views/preference/Preference.vue:58 #: src/views/preference/Preference.vue:59
msgid "Save successfully" msgid "Save successfully"
msgstr "" msgstr ""
@ -1450,6 +1454,10 @@ msgstr ""
msgid "Send" msgid "Send"
msgstr "" msgstr ""
#: src/views/preference/OpenAISettings.vue:66
msgid "Send Include Context"
msgstr ""
#: src/components/NginxControl/NginxControl.vue:28 #: src/components/NginxControl/NginxControl.vue:28
#: src/components/NginxControl/NginxControl.vue:42 #: src/components/NginxControl/NginxControl.vue:42
#: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46 #: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46
@ -1460,7 +1468,7 @@ msgstr ""
#: src/views/config/ConfigEdit.vue:41 #: src/views/config/ConfigEdit.vue:41
#: src/views/domain/DomainList.vue:81 #: src/views/domain/DomainList.vue:81
#: src/views/other/Install.vue:70 #: src/views/other/Install.vue:70
#: src/views/preference/Preference.vue:62 #: src/views/preference/Preference.vue:63
#: src/views/stream/StreamList.vue:113 #: src/views/stream/StreamList.vue:113
#: src/views/stream/StreamList.vue:81 #: src/views/stream/StreamList.vue:81
#: src/views/system/Upgrade.vue:42 #: src/views/system/Upgrade.vue:42

View file

@ -175,7 +175,7 @@ msgstr "Основная информация"
#: src/views/config/ConfigEdit.vue:116 #: src/views/config/ConfigEdit.vue:116
#: src/views/domain/components/RightSettings.vue:76 #: src/views/domain/components/RightSettings.vue:76
#: src/views/preference/Preference.vue:93 #: src/views/preference/Preference.vue:94
#: src/views/stream/components/RightSettings.vue:76 #: src/views/stream/components/RightSettings.vue:76
#, fuzzy #, fuzzy
msgid "Basic" msgid "Basic"
@ -652,6 +652,10 @@ msgstr "Включить не удалось"
msgid "Enable successfully" msgid "Enable successfully"
msgstr "Активировано успешно" msgstr "Активировано успешно"
#: src/views/preference/OpenAISettings.vue:67
msgid "Enable this option will significantly increase the token usage."
msgstr ""
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175
msgid "Enable TLS" msgid "Enable TLS"
msgstr "Включить TLS" msgstr "Включить TLS"
@ -971,7 +975,7 @@ msgstr "Авторизация успешна"
msgid "Logout successful" msgid "Logout successful"
msgstr "Выход выполнен успешно" msgstr "Выход выполнен успешно"
#: src/views/preference/Preference.vue:111 #: src/views/preference/Preference.vue:112
msgid "Logrotate" msgid "Logrotate"
msgstr "" msgstr ""
@ -1101,7 +1105,7 @@ msgstr "Вышла новая версия"
msgid "Next" msgid "Next"
msgstr "Дальше" msgstr "Дальше"
#: src/views/preference/Preference.vue:99 #: src/views/preference/Preference.vue:100
#, fuzzy #, fuzzy
msgid "Nginx" msgid "Nginx"
msgstr "Журнал" msgstr "Журнал"
@ -1230,7 +1234,7 @@ msgstr ""
msgid "Online" msgid "Online"
msgstr "" msgstr ""
#: src/views/preference/Preference.vue:105 #: src/views/preference/Preference.vue:106
msgid "OpenAI" msgid "OpenAI"
msgstr "" msgstr ""
@ -1326,7 +1330,7 @@ msgstr ""
msgid "Pre-release" msgid "Pre-release"
msgstr "" msgstr ""
#: src/routes/index.ts:239 src/views/preference/Preference.vue:88 #: src/routes/index.ts:239 src/views/preference/Preference.vue:89
msgid "Preference" msgid "Preference"
msgstr "Настройки" msgstr "Настройки"
@ -1481,7 +1485,7 @@ msgstr "Выполняется"
#: src/views/certificate/CertificateEditor.vue:242 #: src/views/certificate/CertificateEditor.vue:242
#: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260 #: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120
#: src/views/preference/Preference.vue:122 src/views/stream/StreamEdit.vue:251 #: src/views/preference/Preference.vue:123 src/views/stream/StreamEdit.vue:251
msgid "Save" msgid "Save"
msgstr "Сохранить" msgstr "Сохранить"
@ -1497,7 +1501,7 @@ msgstr "Ошибка сохранения %{msg}"
#: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104
#: src/views/certificate/CertificateEditor.vue:45 #: src/views/certificate/CertificateEditor.vue:45
#: src/views/preference/Preference.vue:58 #: src/views/preference/Preference.vue:59
#, fuzzy #, fuzzy
msgid "Save successfully" msgid "Save successfully"
msgstr "Успешно сохранено" msgstr "Успешно сохранено"
@ -1522,6 +1526,10 @@ msgstr "Выбор"
msgid "Send" msgid "Send"
msgstr "Отправлено" msgstr "Отправлено"
#: src/views/preference/OpenAISettings.vue:66
msgid "Send Include Context"
msgstr ""
#: src/components/NginxControl/NginxControl.vue:28 #: src/components/NginxControl/NginxControl.vue:28
#: src/components/NginxControl/NginxControl.vue:42 #: src/components/NginxControl/NginxControl.vue:42
#: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46 #: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46
@ -1530,7 +1538,7 @@ msgstr "Отправлено"
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:182 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:182
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:221 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:221
#: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81 #: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81
#: src/views/other/Install.vue:70 src/views/preference/Preference.vue:62 #: src/views/other/Install.vue:70 src/views/preference/Preference.vue:63
#: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
#: src/views/system/Upgrade.vue:42 #: src/views/system/Upgrade.vue:42
msgid "Server error" msgid "Server error"

View file

@ -175,7 +175,7 @@ msgstr "Thông tin"
#: src/views/config/ConfigEdit.vue:116 #: src/views/config/ConfigEdit.vue:116
#: src/views/domain/components/RightSettings.vue:76 #: src/views/domain/components/RightSettings.vue:76
#: src/views/preference/Preference.vue:93 #: src/views/preference/Preference.vue:94
#: src/views/stream/components/RightSettings.vue:76 #: src/views/stream/components/RightSettings.vue:76
#, fuzzy #, fuzzy
msgid "Basic" msgid "Basic"
@ -653,6 +653,10 @@ msgstr "Bật không thành công"
msgid "Enable successfully" msgid "Enable successfully"
msgstr "Đã bật" msgstr "Đã bật"
#: src/views/preference/OpenAISettings.vue:67
msgid "Enable this option will significantly increase the token usage."
msgstr ""
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175
msgid "Enable TLS" msgid "Enable TLS"
msgstr "Bật TLS" msgstr "Bật TLS"
@ -973,7 +977,7 @@ msgstr "Đăng nhập thành công"
msgid "Logout successful" msgid "Logout successful"
msgstr "Đã đăng xuất" msgstr "Đã đăng xuất"
#: src/views/preference/Preference.vue:111 #: src/views/preference/Preference.vue:112
msgid "Logrotate" msgid "Logrotate"
msgstr "" msgstr ""
@ -1102,7 +1106,7 @@ msgstr "Đã có phiên bản mới"
msgid "Next" msgid "Next"
msgstr "Tiếp theo" msgstr "Tiếp theo"
#: src/views/preference/Preference.vue:99 #: src/views/preference/Preference.vue:100
msgid "Nginx" msgid "Nginx"
msgstr "" msgstr ""
@ -1230,7 +1234,7 @@ msgstr "Sau khi quá trình xác minh hoàn tất, bản ghi sẽ bị xóa."
msgid "Online" msgid "Online"
msgstr "Trực tuyến" msgstr "Trực tuyến"
#: src/views/preference/Preference.vue:105 #: src/views/preference/Preference.vue:106
msgid "OpenAI" msgid "OpenAI"
msgstr "" msgstr ""
@ -1328,7 +1332,7 @@ msgstr ""
msgid "Pre-release" msgid "Pre-release"
msgstr "" msgstr ""
#: src/routes/index.ts:239 src/views/preference/Preference.vue:88 #: src/routes/index.ts:239 src/views/preference/Preference.vue:89
msgid "Preference" msgid "Preference"
msgstr "Cài đặt" msgstr "Cài đặt"
@ -1483,7 +1487,7 @@ msgstr "Running"
#: src/views/certificate/CertificateEditor.vue:242 #: src/views/certificate/CertificateEditor.vue:242
#: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260 #: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120
#: src/views/preference/Preference.vue:122 src/views/stream/StreamEdit.vue:251 #: src/views/preference/Preference.vue:123 src/views/stream/StreamEdit.vue:251
msgid "Save" msgid "Save"
msgstr "Lưu" msgstr "Lưu"
@ -1499,7 +1503,7 @@ msgstr "Đã xảy ra lỗi khi lưu %{msg}"
#: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104
#: src/views/certificate/CertificateEditor.vue:45 #: src/views/certificate/CertificateEditor.vue:45
#: src/views/preference/Preference.vue:58 #: src/views/preference/Preference.vue:59
#, fuzzy #, fuzzy
msgid "Save successfully" msgid "Save successfully"
msgstr "Lưu thành công" msgstr "Lưu thành công"
@ -1524,6 +1528,10 @@ msgstr "Bộ chọn"
msgid "Send" msgid "Send"
msgstr "Gửi" msgstr "Gửi"
#: src/views/preference/OpenAISettings.vue:66
msgid "Send Include Context"
msgstr ""
#: src/components/NginxControl/NginxControl.vue:28 #: src/components/NginxControl/NginxControl.vue:28
#: src/components/NginxControl/NginxControl.vue:42 #: src/components/NginxControl/NginxControl.vue:42
#: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46 #: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46
@ -1532,7 +1540,7 @@ msgstr "Gửi"
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:182 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:182
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:221 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:221
#: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81 #: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81
#: src/views/other/Install.vue:70 src/views/preference/Preference.vue:62 #: src/views/other/Install.vue:70 src/views/preference/Preference.vue:63
#: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
#: src/views/system/Upgrade.vue:42 #: src/views/system/Upgrade.vue:42
msgid "Server error" msgid "Server error"

Binary file not shown.

View file

@ -168,7 +168,7 @@ msgstr "基本信息"
#: src/views/config/ConfigEdit.vue:116 #: src/views/config/ConfigEdit.vue:116
#: src/views/domain/components/RightSettings.vue:76 #: src/views/domain/components/RightSettings.vue:76
#: src/views/preference/Preference.vue:93 #: src/views/preference/Preference.vue:94
#: src/views/stream/components/RightSettings.vue:76 #: src/views/stream/components/RightSettings.vue:76
msgid "Basic" msgid "Basic"
msgstr "基本" msgstr "基本"
@ -612,6 +612,10 @@ msgstr "启用失败"
msgid "Enable successfully" msgid "Enable successfully"
msgstr "启用成功" msgstr "启用成功"
#: src/views/preference/OpenAISettings.vue:67
msgid "Enable this option will significantly increase the token usage."
msgstr "启用该选项将显著增加 token 的使用量。"
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175
msgid "Enable TLS" msgid "Enable TLS"
msgstr "启用 TLS" msgstr "启用 TLS"
@ -910,7 +914,7 @@ msgstr "登录成功"
msgid "Logout successful" msgid "Logout successful"
msgstr "登出成功" msgstr "登出成功"
#: src/views/preference/Preference.vue:111 #: src/views/preference/Preference.vue:112
msgid "Logrotate" msgid "Logrotate"
msgstr "Logrotate" msgstr "Logrotate"
@ -1036,7 +1040,7 @@ msgstr "新版本发布"
msgid "Next" msgid "Next"
msgstr "下一步" msgstr "下一步"
#: src/views/preference/Preference.vue:99 #: src/views/preference/Preference.vue:100
msgid "Nginx" msgid "Nginx"
msgstr "Nginx" msgstr "Nginx"
@ -1158,7 +1162,7 @@ msgstr "一旦验证完成,这些记录将被删除。"
msgid "Online" msgid "Online"
msgstr "在线" msgstr "在线"
#: src/views/preference/Preference.vue:105 #: src/views/preference/Preference.vue:106
msgid "OpenAI" msgid "OpenAI"
msgstr "OpenAI" msgstr "OpenAI"
@ -1253,7 +1257,7 @@ msgstr "请至少选择一个节点!"
msgid "Pre-release" msgid "Pre-release"
msgstr "预发布" msgstr "预发布"
#: src/routes/index.ts:239 src/views/preference/Preference.vue:88 #: src/routes/index.ts:239 src/views/preference/Preference.vue:89
msgid "Preference" msgid "Preference"
msgstr "偏好设置" msgstr "偏好设置"
@ -1394,7 +1398,7 @@ msgstr "运行中"
#: src/views/certificate/CertificateEditor.vue:242 #: src/views/certificate/CertificateEditor.vue:242
#: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260 #: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120
#: src/views/preference/Preference.vue:122 src/views/stream/StreamEdit.vue:251 #: src/views/preference/Preference.vue:123 src/views/stream/StreamEdit.vue:251
msgid "Save" msgid "Save"
msgstr "保存" msgstr "保存"
@ -1410,7 +1414,7 @@ msgstr "保存错误 %{msg}"
#: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104
#: src/views/certificate/CertificateEditor.vue:45 #: src/views/certificate/CertificateEditor.vue:45
#: src/views/preference/Preference.vue:58 #: src/views/preference/Preference.vue:59
msgid "Save successfully" msgid "Save successfully"
msgstr "保存成功" msgstr "保存成功"
@ -1434,6 +1438,10 @@ msgstr "选择器"
msgid "Send" msgid "Send"
msgstr "上传" msgstr "上传"
#: src/views/preference/OpenAISettings.vue:66
msgid "Send Include Context"
msgstr "发送 Include 内容"
#: src/components/NginxControl/NginxControl.vue:28 #: src/components/NginxControl/NginxControl.vue:28
#: src/components/NginxControl/NginxControl.vue:42 #: src/components/NginxControl/NginxControl.vue:42
#: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46 #: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46
@ -1442,7 +1450,7 @@ msgstr "上传"
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:182 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:182
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:221 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:221
#: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81 #: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81
#: src/views/other/Install.vue:70 src/views/preference/Preference.vue:62 #: src/views/other/Install.vue:70 src/views/preference/Preference.vue:63
#: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
#: src/views/system/Upgrade.vue:42 #: src/views/system/Upgrade.vue:42
msgid "Server error" msgid "Server error"

View file

@ -176,7 +176,7 @@ msgstr "基本資訊"
#: src/views/config/ConfigEdit.vue:116 #: src/views/config/ConfigEdit.vue:116
#: src/views/domain/components/RightSettings.vue:76 #: src/views/domain/components/RightSettings.vue:76
#: src/views/preference/Preference.vue:93 #: src/views/preference/Preference.vue:94
#: src/views/stream/components/RightSettings.vue:76 #: src/views/stream/components/RightSettings.vue:76
msgid "Basic" msgid "Basic"
msgstr "基本" msgstr "基本"
@ -635,6 +635,10 @@ msgstr "啟用失敗"
msgid "Enable successfully" msgid "Enable successfully"
msgstr "啟用成功" msgstr "啟用成功"
#: src/views/preference/OpenAISettings.vue:67
msgid "Enable this option will significantly increase the token usage."
msgstr ""
#: src/views/domain/ngx_conf/NgxConfigEditor.vue:175 #: src/views/domain/ngx_conf/NgxConfigEditor.vue:175
msgid "Enable TLS" msgid "Enable TLS"
msgstr "啟用 TLS" msgstr "啟用 TLS"
@ -948,7 +952,7 @@ msgstr "登入成功"
msgid "Logout successful" msgid "Logout successful"
msgstr "登出成功" msgstr "登出成功"
#: src/views/preference/Preference.vue:111 #: src/views/preference/Preference.vue:112
msgid "Logrotate" msgid "Logrotate"
msgstr "" msgstr ""
@ -1074,7 +1078,7 @@ msgstr "新版本發布"
msgid "Next" msgid "Next"
msgstr "下一步" msgstr "下一步"
#: src/views/preference/Preference.vue:99 #: src/views/preference/Preference.vue:100
msgid "Nginx" msgid "Nginx"
msgstr "Nginx" msgstr "Nginx"
@ -1198,7 +1202,7 @@ msgstr ""
msgid "Online" msgid "Online"
msgstr "線上" msgstr "線上"
#: src/views/preference/Preference.vue:105 #: src/views/preference/Preference.vue:106
msgid "OpenAI" msgid "OpenAI"
msgstr "OpenAI" msgstr "OpenAI"
@ -1294,7 +1298,7 @@ msgstr "請至少選擇一個節點!"
msgid "Pre-release" msgid "Pre-release"
msgstr "預先發布" msgstr "預先發布"
#: src/routes/index.ts:239 src/views/preference/Preference.vue:88 #: src/routes/index.ts:239 src/views/preference/Preference.vue:89
msgid "Preference" msgid "Preference"
msgstr "偏好設定" msgstr "偏好設定"
@ -1446,7 +1450,7 @@ msgstr "執行中"
#: src/views/certificate/CertificateEditor.vue:242 #: src/views/certificate/CertificateEditor.vue:242
#: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260 #: src/views/config/ConfigEdit.vue:97 src/views/domain/DomainEdit.vue:260
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120 #: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:120
#: src/views/preference/Preference.vue:122 src/views/stream/StreamEdit.vue:251 #: src/views/preference/Preference.vue:123 src/views/stream/StreamEdit.vue:251
msgid "Save" msgid "Save"
msgstr "儲存" msgstr "儲存"
@ -1462,7 +1466,7 @@ msgstr "儲存錯誤 %{msg}"
#: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
#: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:104
#: src/views/certificate/CertificateEditor.vue:45 #: src/views/certificate/CertificateEditor.vue:45
#: src/views/preference/Preference.vue:58 #: src/views/preference/Preference.vue:59
msgid "Save successfully" msgid "Save successfully"
msgstr "儲存成功" msgstr "儲存成功"
@ -1486,6 +1490,10 @@ msgstr "選擇器"
msgid "Send" msgid "Send"
msgstr "傳送" msgstr "傳送"
#: src/views/preference/OpenAISettings.vue:66
msgid "Send Include Context"
msgstr ""
#: src/components/NginxControl/NginxControl.vue:28 #: src/components/NginxControl/NginxControl.vue:28
#: src/components/NginxControl/NginxControl.vue:42 #: src/components/NginxControl/NginxControl.vue:42
#: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46 #: src/components/StdDesign/StdDataDisplay/methods/exportCsv.ts:46
@ -1494,7 +1502,7 @@ msgstr "傳送"
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:182 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:182
#: src/components/StdDesign/StdDataDisplay/StdTable.vue:221 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:221
#: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81 #: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainList.vue:81
#: src/views/other/Install.vue:70 src/views/preference/Preference.vue:62 #: src/views/other/Install.vue:70 src/views/preference/Preference.vue:63
#: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
#: src/views/system/Upgrade.vue:42 #: src/views/system/Upgrade.vue:42
msgid "Server error" msgid "Server error"

View file

@ -50,6 +50,7 @@ watch(route, () => {
:columns="configColumns" :columns="configColumns"
disable-delete disable-delete
disable_search disable_search
disabled-view
row-key="name" row-key="name"
:get_params="get_params" :get_params="get_params"
@click-edit="(r, row) => { @click-edit="(r, row) => {

View file

@ -4,7 +4,6 @@ import { message } from 'ant-design-vue'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { formatDateTime } from '@/lib/helper' import { formatDateTime } from '@/lib/helper'
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue' import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
import config from '@/api/config' import config from '@/api/config'
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue' import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
import ngx from '@/api/ngx' import ngx from '@/api/ngx'
@ -26,7 +25,7 @@ const name = computed(() => {
const configText = ref('') const configText = ref('')
const history_chatgpt_record = ref([]) as Ref<ChatComplicationMessage[]> const history_chatgpt_record = ref([]) as Ref<ChatComplicationMessage[]>
const file_path = ref('') const filepath = ref('')
const active_key = ref(['1', '2']) const active_key = ref(['1', '2'])
const modified_at = ref('') const modified_at = ref('')
@ -35,7 +34,7 @@ function init() {
config.get(name.value).then(r => { config.get(name.value).then(r => {
configText.value = r.content configText.value = r.content
history_chatgpt_record.value = r.chatgpt_messages history_chatgpt_record.value = r.chatgpt_messages
file_path.value = r.file_path filepath.value = r.filepath
modified_at.value = r.modified_at modified_at.value = r.modified_at
}).catch(r => { }).catch(r => {
message.error(r.message ?? $gettext('Server error')) message.error(r.message ?? $gettext('Server error'))
@ -44,7 +43,7 @@ function init() {
else { else {
configText.value = '' configText.value = ''
history_chatgpt_record.value = [] history_chatgpt_record.value = []
file_path.value = '' filepath.value = ''
} }
} }
@ -117,7 +116,7 @@ function format_code() {
> >
<AForm layout="vertical"> <AForm layout="vertical">
<AFormItem :label="$gettext('Path')"> <AFormItem :label="$gettext('Path')">
{{ file_path }} {{ filepath }}
</AFormItem> </AFormItem>
<AFormItem :label="$gettext('Updated at')"> <AFormItem :label="$gettext('Updated at')">
{{ formatDateTime(modified_at) }} {{ formatDateTime(modified_at) }}
@ -131,7 +130,7 @@ function format_code() {
<ChatGPT <ChatGPT
v-model:history-messages="history_chatgpt_record" v-model:history-messages="history_chatgpt_record"
:content="configText" :content="configText"
:path="file_path" :path="filepath"
/> />
</ACollapsePanel> </ACollapsePanel>
</ACollapse> </ACollapse>

View file

@ -33,6 +33,7 @@ const cert_info_map: Record<string, CertificateInfo> = reactive({})
const auto_cert = ref(false) const auto_cert = ref(false)
const enabled = ref(false) const enabled = ref(false)
const filepath = ref('')
const configText = ref('') const configText = ref('')
const advance_mode_ref = ref(false) const advance_mode_ref = ref(false)
const saving = ref(false) const saving = ref(false)
@ -67,6 +68,7 @@ function handle_response(r: Site) {
parse_error_status.value = false parse_error_status.value = false
parse_error_message.value = '' parse_error_message.value = ''
filename.value = r.name filename.value = r.name
filepath.value = r.filepath
configText.value = r.config configText.value = r.config
enabled.value = r.enabled enabled.value = r.enabled
auto_cert.value = r.auto_cert auto_cert.value = r.auto_cert
@ -156,6 +158,7 @@ provide('history_chatgpt_record', history_chatgpt_record)
provide('enabled', enabled) provide('enabled', enabled)
provide('name', name) provide('name', name)
provide('filename', filename) provide('filename', filename)
provide('filepath', filepath)
provide('data', data) provide('data', data)
</script> </script>

View file

@ -108,11 +108,13 @@ watch(route, () => {
:columns="columns" :columns="columns"
row-key="name" row-key="name"
disable-delete disable-delete
disabled-view
@click-edit="r => $router.push({ @click-edit="r => $router.push({
path: `/domain/${r}`, path: `/domain/${r}`,
})" })"
> >
<template #actions="{ record }"> <template #actions="{ record }">
<ADivider type="vertical" />
<AButton <AButton
v-if="record.enabled" v-if="record.enabled"
type="link" type="link"

View file

@ -8,15 +8,14 @@ import { formatDateTime } from '@/lib/helper'
import Deploy from '@/views/domain/components/Deploy.vue' import Deploy from '@/views/domain/components/Deploy.vue'
import { useSettingsStore } from '@/pinia' import { useSettingsStore } from '@/pinia'
import type { ChatComplicationMessage } from '@/api/openai' import type { ChatComplicationMessage } from '@/api/openai'
import type { NgxConfig } from '@/api/ngx'
import type { CheckedType } from '@/types' import type { CheckedType } from '@/types'
const settings = useSettingsStore() const settings = useSettingsStore()
const configText = inject('configText') as Ref<string> const configText = inject('configText') as Ref<string>
const ngx_config = inject('ngx_config') as Ref<NgxConfig>
const enabled = inject('enabled') as Ref<boolean> const enabled = inject('enabled') as Ref<boolean>
const name = inject('name') as Ref<string> const name = inject('name') as Ref<string>
const filepath = inject('filepath') as Ref<string>
const history_chatgpt_record = inject('history_chatgpt_record') as Ref<ChatComplicationMessage[]> const history_chatgpt_record = inject('history_chatgpt_record') as Ref<ChatComplicationMessage[]>
const filename = inject('filename') as Ref<string | number | undefined> const filename = inject('filename') as Ref<string | number | undefined>
const data = inject('data') as Ref<Site> const data = inject('data') as Ref<Site>
@ -102,7 +101,7 @@ function on_change_enabled(checked: CheckedType) {
<ChatGPT <ChatGPT
v-model:history-messages="history_chatgpt_record" v-model:history-messages="history_chatgpt_record"
:content="configText" :content="configText"
:path="ngx_config.file_name" :path="filepath"
/> />
</ACollapsePanel> </ACollapsePanel>
</ACollapse> </ACollapse>

View file

@ -34,6 +34,7 @@ const configText = ref('')
const advance_mode_ref = ref(false) const advance_mode_ref = ref(false)
const saving = ref(false) const saving = ref(false)
const filename = ref('') const filename = ref('')
const filepath = ref('')
const parse_error_status = ref(false) const parse_error_status = ref(false)
const parse_error_message = ref('') const parse_error_message = ref('')
const data = ref({}) const data = ref({})
@ -61,6 +62,7 @@ function handle_response(r: Stream) {
parse_error_status.value = false parse_error_status.value = false
parse_error_message.value = '' parse_error_message.value = ''
filename.value = r.name filename.value = r.name
filepath.value = r.filepath
configText.value = r.config configText.value = r.config
enabled.value = r.enabled enabled.value = r.enabled
history_chatgpt_record.value = r.chatgpt_messages history_chatgpt_record.value = r.chatgpt_messages
@ -148,6 +150,7 @@ provide('history_chatgpt_record', history_chatgpt_record)
provide('enabled', enabled) provide('enabled', enabled)
provide('name', name) provide('name', name)
provide('filename', filename) provide('filename', filename)
provide('filepath', filepath)
provide('data', data) provide('data', data)
</script> </script>

View file

@ -129,11 +129,13 @@ function handleAddStream() {
:columns="columns" :columns="columns"
row-key="name" row-key="name"
disable-delete disable-delete
disabled-view
@click-edit="r => $router.push({ @click-edit="r => $router.push({
path: `/stream/${r}`, path: `/stream/${r}`,
})" })"
> >
<template #actions="{ record }"> <template #actions="{ record }">
<ADivider type="vertical" />
<AButton <AButton
v-if="record.enabled" v-if="record.enabled"
type="link" type="link"

View file

@ -8,17 +8,16 @@ import { formatDateTime } from '@/lib/helper'
import Deploy from '@/views/stream/components/Deploy.vue' import Deploy from '@/views/stream/components/Deploy.vue'
import { useSettingsStore } from '@/pinia' import { useSettingsStore } from '@/pinia'
import type { ChatComplicationMessage } from '@/api/openai' import type { ChatComplicationMessage } from '@/api/openai'
import type { NgxConfig } from '@/api/ngx'
import type { CheckedType } from '@/types' import type { CheckedType } from '@/types'
const settings = useSettingsStore() const settings = useSettingsStore()
const configText = inject('configText') as Ref<string> const configText = inject('configText') as Ref<string>
const ngx_config = inject('ngx_config') as Ref<NgxConfig>
const enabled = inject('enabled') as Ref<boolean> const enabled = inject('enabled') as Ref<boolean>
const name = inject('name') as Ref<string> const name = inject('name') as Ref<string>
const history_chatgpt_record = inject('history_chatgpt_record') as Ref<ChatComplicationMessage[]> const history_chatgpt_record = inject('history_chatgpt_record') as Ref<ChatComplicationMessage[]>
const filename = inject('filename') as Ref<string | number | undefined> const filename = inject('filename') as Ref<string>
const filepath = inject('filepath') as Ref<string>
const data = inject('data') as Ref<Stream> const data = inject('data') as Ref<Stream>
const [modal, ContextHolder] = Modal.useModal() const [modal, ContextHolder] = Modal.useModal()
@ -58,7 +57,6 @@ function on_change_enabled(checked: CheckedType) {
}, },
}) })
} }
</script> </script>
<template> <template>
@ -102,7 +100,7 @@ function on_change_enabled(checked: CheckedType) {
<ChatGPT <ChatGPT
v-model:history-messages="history_chatgpt_record" v-model:history-messages="history_chatgpt_record"
:content="configText" :content="configText"
:path="ngx_config.file_name" :path="filepath"
/> />
</ACollapsePanel> </ACollapsePanel>
</ACollapse> </ACollapse>

102
internal/chatbot/context.go Normal file
View file

@ -0,0 +1,102 @@
package chatbot
import (
"github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/logger"
"github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/sashabaranov/go-openai"
"os"
"regexp"
"strings"
)
type includeContext struct {
Paths []string
PathsMap map[string]bool
}
func IncludeContext(filename string) (includes []string) {
c := &includeContext{
Paths: make([]string, 0),
PathsMap: make(map[string]bool),
}
c.extractIncludes(filename)
return c.Paths
}
// extractIncludes extracts all include statements from the given nginx configuration file.
func (c *includeContext) extractIncludes(filename string) {
if !helper.FileExists(filename) {
logger.Error("File does not exist: ", filename)
return
}
// Read the file content
content, err := os.ReadFile(filename)
if err != nil {
logger.Error(err)
return
}
// Find all include statements
pattern := regexp.MustCompile(`(?m)^\s*include\s+([^;]+);`)
matches := pattern.FindAllStringSubmatch(string(content), -1)
for _, match := range matches {
if len(match) > 1 {
// Resolve the path of the included file
includePath := match[1]
// to avoid infinite loop
if c.PathsMap[includePath] {
continue
}
c.push(includePath)
// Recursively extract includes from the included file
c.extractIncludes(includePath)
}
}
return
}
func (c *includeContext) push(path string) {
c.Paths = append(c.Paths, path)
c.PathsMap[path] = true
}
// getConfigIncludeContext returns the context of the given filename.
func getConfigIncludeContext(filename string) (multiContent []openai.ChatMessagePart) {
multiContent = make([]openai.ChatMessagePart, 0)
if !helper.IsUnderDirectory(filename, nginx.GetConfPath()) {
return
}
includes := IncludeContext(filename)
logger.Debug(includes)
var sb strings.Builder
for _, include := range includes {
text, _ := os.ReadFile(nginx.GetConfPath(include))
if len(text) == 0 {
continue
}
sb.WriteString("The Content of ")
sb.WriteString(include)
sb.WriteString(",")
sb.WriteString(string(text))
multiContent = append(multiContent, openai.ChatMessagePart{
Type: openai.ChatMessagePartTypeText,
Text: sb.String(),
})
sb.Reset()
}
return
}

View file

@ -0,0 +1,23 @@
package chatbot
import (
"github.com/stretchr/testify/assert"
"regexp"
"testing"
)
func TestRegex(t *testing.T) {
content := `
server {
listen 80;
listen [::]:80;
server_name _;
include error_json;
}
`
pattern := regexp.MustCompile(`(?m)^\s*include\s+([^;]+);`)
matches := pattern.FindAllStringSubmatch(content, -1)
assert.Equal(t, 1, len(matches))
assert.Equal(t, "error_json", matches[0][1])
}

View file

@ -0,0 +1,22 @@
package chatbot
import (
"github.com/sashabaranov/go-openai"
)
func ChatCompletionWithContext(filename string, messages []openai.ChatCompletionMessage) []openai.ChatCompletionMessage {
for i := len(messages) - 1; i >= 0; i-- {
if messages[i].Role == openai.ChatMessageRoleUser {
// openai.ChatCompletionMessage: can't use both Content and MultiContent properties simultaneously
multiContent := getConfigIncludeContext(filename)
multiContent = append(multiContent, openai.ChatMessagePart{
Type: openai.ChatMessagePartTypeText,
Text: messages[i].Content,
})
messages[i].Content = ""
messages[i].MultiContent = multiContent
}
}
return messages
}

View file

@ -0,0 +1,26 @@
package chatbot
import (
"github.com/sashabaranov/go-openai"
"github.com/stretchr/testify/assert"
"testing"
)
func TestChatCompletionWithContext(t *testing.T) {
filename := "test"
messages := []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleSystem,
},
{
Role: openai.ChatMessageRoleUser,
},
{
Role: openai.ChatMessageRoleAssistant,
},
}
messages = ChatCompletionWithContext(filename, messages)
assert.NotNil(t, messages[1].MultiContent)
}

View file

@ -9,7 +9,7 @@ type Config struct {
Name string `json:"name"` Name string `json:"name"`
Content string `json:"content,omitempty"` Content string `json:"content,omitempty"`
ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"` ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"`
FilePath string `json:"file_path,omitempty"` FilePath string `json:"filepath,omitempty"`
ModifiedAt time.Time `json:"modified_at"` ModifiedAt time.Time `json:"modified_at"`
Size int64 `json:"size,omitempty"` Size int64 `json:"size,omitempty"`
IsDir bool `json:"is_dir"` IsDir bool `json:"is_dir"`

View file

@ -0,0 +1,25 @@
package helper
import (
"github.com/0xJacky/Nginx-UI/internal/logger"
"path/filepath"
"strings"
)
func IsUnderDirectory(path, directory string) bool {
absPath, err := filepath.Abs(path)
if err != nil {
logger.Error(err)
return false
}
absDirectory, err := filepath.Abs(directory)
if err != nil {
logger.Error(err)
return false
}
absDirectory = filepath.Clean(absDirectory) + string(filepath.Separator)
return strings.HasPrefix(absPath, absDirectory)
}

View file

@ -0,0 +1,11 @@
package helper
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestIsUnderDirectory(t *testing.T) {
assert.Equal(t, true, IsUnderDirectory("/etc/nginx/nginx.conf", "/etc/nginx"))
assert.Equal(t, false, IsUnderDirectory("../../root/nginx.conf", "/etc/nginx"))
}

View file

@ -10,7 +10,7 @@ type ConfigBackup struct {
Model Model
Name string `json:"name"` Name string `json:"name"`
FilePath string `json:"file_path"` FilePath string `json:"filepath"`
Content string `json:"content" gorm:"type:text"` Content string `json:"content" gorm:"type:text"`
} }
@ -18,7 +18,7 @@ type ConfigBackupListItem struct {
Model Model
Name string `json:"name"` Name string `json:"name"`
FilePath string `json:"file_path"` FilePath string `json:"filepath"`
} }
func GetBackupList(path string) (configs []ConfigBackupListItem) { func GetBackupList(path string) (configs []ConfigBackupListItem) {

View file

@ -33,7 +33,7 @@ func newConfigBackup(db *gorm.DB, opts ...gen.DOOption) configBackup {
_configBackup.UpdatedAt = field.NewTime(tableName, "updated_at") _configBackup.UpdatedAt = field.NewTime(tableName, "updated_at")
_configBackup.DeletedAt = field.NewField(tableName, "deleted_at") _configBackup.DeletedAt = field.NewField(tableName, "deleted_at")
_configBackup.Name = field.NewString(tableName, "name") _configBackup.Name = field.NewString(tableName, "name")
_configBackup.FilePath = field.NewString(tableName, "file_path") _configBackup.FilePath = field.NewString(tableName, "filepath")
_configBackup.Content = field.NewString(tableName, "content") _configBackup.Content = field.NewString(tableName, "content")
_configBackup.fillFieldMap() _configBackup.fillFieldMap()
@ -73,7 +73,7 @@ func (c *configBackup) updateTableName(table string) *configBackup {
c.UpdatedAt = field.NewTime(table, "updated_at") c.UpdatedAt = field.NewTime(table, "updated_at")
c.DeletedAt = field.NewField(table, "deleted_at") c.DeletedAt = field.NewField(table, "deleted_at")
c.Name = field.NewString(table, "name") c.Name = field.NewString(table, "name")
c.FilePath = field.NewString(table, "file_path") c.FilePath = field.NewString(table, "filepath")
c.Content = field.NewString(table, "content") c.Content = field.NewString(table, "content")
c.fillFieldMap() c.fillFieldMap()
@ -97,7 +97,7 @@ func (c *configBackup) fillFieldMap() {
c.fieldMap["updated_at"] = c.UpdatedAt c.fieldMap["updated_at"] = c.UpdatedAt
c.fieldMap["deleted_at"] = c.DeletedAt c.fieldMap["deleted_at"] = c.DeletedAt
c.fieldMap["name"] = c.Name c.fieldMap["name"] = c.Name
c.fieldMap["file_path"] = c.FilePath c.fieldMap["filepath"] = c.FilePath
c.fieldMap["content"] = c.Content c.fieldMap["content"] = c.Content
} }