forked from speauty/anto
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
…todo: 翻译不完整;
- Loading branch information
Showing
8 changed files
with
259 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
tidy: | ||
go mod tidy | ||
|
||
BinName=anto-v3.5.0-windows.exe | ||
BinName=anto-v3.6.0-windows.exe | ||
|
||
deploy: rs build | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,16 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"github.com/OwO-Network/gdeeplx" | ||
"github.com/imroc/req/v3" | ||
) | ||
|
||
func main() { | ||
result, err := gdeeplx.Translate("Hello World!", "EN", "ZH", 0) | ||
testClient := req.C() | ||
testClient.SetProxyURL("sock5://hello:[email protected]:4532") | ||
|
||
res, err := testClient.R().Get("https://www.google.com") | ||
if err != nil { | ||
fmt.Printf("Error: %v\n", err) | ||
return | ||
panic(err) | ||
} | ||
fmt.Println(result) | ||
print(res.Status) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package openai_sweet | ||
|
||
import ( | ||
"anto/domain/service/translator" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
type Config struct { | ||
*translator.DefaultConfig | ||
AppKey string `mapstructure:"app_key"` | ||
ProjectKey string `mapstructure:"project_key"` | ||
QPS int `mapstructure:"qps"` | ||
MaxCharNum int `mapstructure:"max_single_text_length"` | ||
MaxCoroutineNum int `mapstructure:"max_coroutine_num"` | ||
} | ||
|
||
func (config *Config) Default() translator.ImplConfig { | ||
return &Config{ | ||
AppKey: "", ProjectKey: "gpt-3.5-turbo", | ||
MaxCharNum: 2000, QPS: 1, MaxCoroutineNum: 1, | ||
} | ||
} | ||
|
||
func (config *Config) SyncDisk(currentViper *viper.Viper) error { | ||
tagAndVal := config.JoinAllTagAndValue(API(), config, "mapstructure") | ||
|
||
for tag, val := range tagAndVal { | ||
currentViper.Set(tag, val) | ||
} | ||
return nil | ||
} | ||
|
||
func (config *Config) GetAK() string { return config.AppKey } | ||
func (config *Config) GetProjectKey() string { return config.ProjectKey } | ||
func (config *Config) GetQPS() int { return config.QPS } | ||
func (config *Config) GetMaxCharNum() int { return config.MaxCharNum } | ||
func (config *Config) GetMaxCoroutineNum() int { return config.MaxCoroutineNum } | ||
|
||
func (config *Config) SetAK(str string) error { | ||
if err := config.ValidatorStr(str); err != nil { | ||
return err | ||
} | ||
config.AppKey = str | ||
return nil | ||
} | ||
|
||
func (config *Config) SetProjectKey(projectKey string) error { | ||
if projectKey == "" { | ||
projectKey = "gpt-3.5-turbo" | ||
} | ||
config.ProjectKey = projectKey | ||
return nil | ||
} | ||
|
||
func (config *Config) SetQPS(num int) error { | ||
config.QPS = 1 | ||
return nil | ||
} | ||
|
||
func (config *Config) SetMaxCharNum(num int) error { | ||
if err := config.ValidatorNum(num); err != nil { | ||
return err | ||
} | ||
if num > 2000 { | ||
num = 2000 | ||
} | ||
config.MaxCharNum = num | ||
return nil | ||
} | ||
|
||
func (config *Config) SetMaxCoroutineNum(num int) error { | ||
config.MaxCoroutineNum = 1 | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package openai_sweet | ||
|
||
import ( | ||
"anto/domain/service/translator" | ||
) | ||
|
||
var langSupported = []translator.LangPair{ | ||
{"Chinese", "中文"}, | ||
{"English", "英语"}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package openai_sweet | ||
|
||
import ( | ||
"anto/domain/service/translator" | ||
"anto/lib/log" | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"github.com/golang-module/carbon" | ||
"strings" | ||
"sync" | ||
) | ||
|
||
const apiTranslate = "https://api.sweetyun.com/v1/chat/completions" | ||
|
||
var ( | ||
apiSingleton *Translator | ||
onceSingleton sync.Once | ||
) | ||
|
||
func API() *Translator { | ||
onceSingleton.Do(func() { | ||
apiSingleton = New() | ||
}) | ||
return apiSingleton | ||
} | ||
|
||
func New() *Translator { | ||
return &Translator{ | ||
id: "openai_sweet", | ||
name: "OpenAI_Sweet", | ||
sep: "\n", | ||
langSupported: langSupported, | ||
} | ||
} | ||
|
||
type Translator struct { | ||
id string | ||
name string | ||
cfg translator.ImplConfig | ||
langSupported []translator.LangPair | ||
sep string | ||
currentFromLang string | ||
currentToLang string | ||
currentMessages *translateRequest | ||
} | ||
|
||
func (customT *Translator) Init(cfg translator.ImplConfig) { customT.cfg = cfg } | ||
|
||
func (customT *Translator) GetId() string { return customT.id } | ||
func (customT *Translator) GetShortId() string { return "oas" } | ||
func (customT *Translator) GetName() string { return customT.name } | ||
func (customT *Translator) GetCfg() translator.ImplConfig { return customT.cfg } | ||
func (customT *Translator) GetLangSupported() []translator.LangPair { return customT.langSupported } | ||
func (customT *Translator) GetSep() string { return customT.sep } | ||
func (customT *Translator) IsValid() bool { return customT.cfg != nil && customT.cfg.GetAK() != "" } | ||
|
||
func (customT *Translator) Translate(ctx context.Context, args *translator.TranslateArgs) (*translator.TranslateRes, error) { | ||
timeStart := carbon.Now() | ||
prompt := fmt.Sprintf( | ||
"You are an excellent simultaneous translator in both %s and %s. I will provide you with %s line by line, and you will translate it into %s line by line. The number of lines in both %s and %s is the same. Do you understand?", | ||
customT.currentFromLang, args.ToLang, customT.currentFromLang, args.ToLang, customT.currentFromLang, args.ToLang, | ||
) | ||
// 初始化 | ||
if customT.currentMessages == nil || customT.currentMessages.Model == "" { | ||
customT.currentMessages = new(translateRequest) | ||
customT.currentMessages.Model = customT.cfg.GetProjectKey() | ||
customT.currentMessages.Messages = []MessageItem{} | ||
} | ||
// 预置条件, 语种必须保持一致, 否则就视为新开 | ||
if customT.currentFromLang == "" || customT.currentToLang == "" || customT.currentFromLang != args.FromLang || customT.currentToLang != args.ToLang { | ||
if len(customT.currentMessages.Messages) > 0 { | ||
customT.currentMessages.Messages = []MessageItem{} | ||
} | ||
customT.currentMessages.Messages = append(customT.currentMessages.Messages, MessageItem{ | ||
Role: "system", Content: prompt, | ||
}) | ||
} | ||
customT.currentMessages.Messages = append(customT.currentMessages.Messages, MessageItem{ | ||
Role: "user", Content: args.TextContent, | ||
}) | ||
cntTokens := 0 | ||
for _, message := range customT.currentMessages.Messages { | ||
cntTokens += len(message.Content) | ||
} | ||
|
||
if cntTokens < 2048 { | ||
|
||
} else { | ||
customT.currentMessages.Messages = []MessageItem{} | ||
customT.currentMessages.Messages = append(customT.currentMessages.Messages, MessageItem{ | ||
Role: "system", Content: prompt, | ||
}, MessageItem{ | ||
Role: "user", Content: args.TextContent, | ||
}) | ||
} | ||
|
||
reqBytes, _ := json.Marshal(customT.currentMessages) | ||
headers := map[string]string{ | ||
"Authorization": fmt.Sprintf("Bearer %s", customT.cfg.GetAK()), | ||
} | ||
respBytes, err := translator.RequestSimpleHttp(ctx, customT, apiTranslate, true, reqBytes, headers) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
resp := new(translateResponse) | ||
if err = json.Unmarshal(respBytes, resp); err != nil { | ||
log.Singleton().ErrorF("解析报文异常, 引擎: %s, 错误: %s", customT.GetName(), err) | ||
return nil, fmt.Errorf("解析报文出现异常, 错误: %s", err.Error()) | ||
} | ||
if resp.Usage.CompletionTokens <= 0 { | ||
log.Singleton().ErrorF("接口响应异常, 引擎: %s, 错误: 无响应, 数据: %s", customT.GetName(), string(respBytes)) | ||
return nil, fmt.Errorf("接口响应异常, 引擎: %s, 错误: %s", customT.GetName(), "无响应") | ||
} | ||
|
||
srcTexts := strings.Split(args.TextContent, customT.GetSep()) | ||
tgtTexts := strings.Split(resp.Choices[0].Message.Content, customT.GetSep()) | ||
ret := new(translator.TranslateRes) | ||
if len(srcTexts) != len(tgtTexts) { | ||
ret.TimeUsed = int(carbon.Now().DiffAbsInSeconds(timeStart)) | ||
return ret, nil | ||
} | ||
|
||
for textIdx, textTarget := range tgtTexts { | ||
ret.Results = append(ret.Results, &translator.TranslateResBlock{ | ||
Id: srcTexts[textIdx], TextTranslated: textTarget, | ||
}) | ||
} | ||
|
||
ret.TimeUsed = int(carbon.Now().DiffAbsInSeconds(timeStart)) | ||
return ret, nil | ||
} | ||
|
||
type translateRequest struct { | ||
Model string `json:"model"` | ||
Messages []MessageItem `json:"messages"` | ||
} | ||
|
||
type MessageItem struct { | ||
Role string `json:"role"` | ||
Content string `json:"content"` | ||
} | ||
|
||
type translateResponse struct { | ||
Id string `json:"id"` | ||
Object string `json:"object"` | ||
Created int `json:"created"` | ||
Model string `json:"model"` | ||
Choices []struct { | ||
Index int `json:"index"` | ||
Message MessageItem `json:"message"` | ||
FinishReason string `json:"finish_reason"` | ||
} `json:"choices"` | ||
Usage struct { | ||
PromptTokens int `json:"prompt_tokens"` | ||
CompletionTokens int `json:"completion_tokens"` | ||
TotalTokens int `json:"total_tokens"` | ||
} `json:"usage"` | ||
} |