mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-27 21:56:39 +08:00
feat: 支持火山引擎的云雀大模型
This commit is contained in:
parent
be8a0ec184
commit
62ef79e345
@ -1,15 +1,18 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
// ApiRequest API 请求实体
|
// ApiRequest API 请求实体
|
||||||
type ApiRequest struct {
|
type ApiRequest struct {
|
||||||
Model string `json:"model,omitempty"` // 兼容百度文心一言
|
Model string `json:"-"`
|
||||||
Temperature float32 `json:"temperature"`
|
ModelRaw json.RawMessage `json:"model,omitempty"` // 兼容 model 字段不是字符串的接口
|
||||||
MaxTokens int `json:"max_tokens,omitempty"` // 兼容百度文心一言
|
Temperature float32 `json:"temperature"`
|
||||||
Stream bool `json:"stream"`
|
MaxTokens int `json:"max_tokens,omitempty"` // 兼容百度文心一言
|
||||||
Messages []interface{} `json:"messages,omitempty"`
|
Stream bool `json:"stream"`
|
||||||
Prompt []interface{} `json:"prompt,omitempty"` // 兼容 ChatGLM
|
Messages []interface{} `json:"messages,omitempty"`
|
||||||
Tools []interface{} `json:"tools,omitempty"`
|
Prompt []interface{} `json:"prompt,omitempty"` // 兼容 ChatGLM
|
||||||
Functions []interface{} `json:"functions,omitempty"` // 兼容中转平台
|
Tools []interface{} `json:"tools,omitempty"`
|
||||||
|
Functions []interface{} `json:"functions,omitempty"` // 兼容中转平台
|
||||||
|
|
||||||
ToolChoice string `json:"tool_choice,omitempty"`
|
ToolChoice string `json:"tool_choice,omitempty"`
|
||||||
|
|
||||||
|
@ -135,6 +135,7 @@ type ChatConfig struct {
|
|||||||
ChatGML ModelAPIConfig `json:"chat_gml"`
|
ChatGML ModelAPIConfig `json:"chat_gml"`
|
||||||
Baidu ModelAPIConfig `json:"baidu"`
|
Baidu ModelAPIConfig `json:"baidu"`
|
||||||
XunFei ModelAPIConfig `json:"xun_fei"`
|
XunFei ModelAPIConfig `json:"xun_fei"`
|
||||||
|
Skylark ModelAPIConfig `json:"skylark"`
|
||||||
|
|
||||||
EnableContext bool `json:"enable_context"` // 是否开启聊天上下文
|
EnableContext bool `json:"enable_context"` // 是否开启聊天上下文
|
||||||
EnableHistory bool `json:"enable_history"` // 是否允许保存聊天记录
|
EnableHistory bool `json:"enable_history"` // 是否允许保存聊天记录
|
||||||
@ -150,6 +151,7 @@ const ChatGLM = Platform("ChatGLM")
|
|||||||
const Baidu = Platform("Baidu")
|
const Baidu = Platform("Baidu")
|
||||||
const XunFei = Platform("XunFei")
|
const XunFei = Platform("XunFei")
|
||||||
const QWen = Platform("QWen")
|
const QWen = Platform("QWen")
|
||||||
|
const Skylark = Platform("Skylark")
|
||||||
|
|
||||||
// UserChatConfig 用户的聊天配置
|
// UserChatConfig 用户的聊天配置
|
||||||
type UserChatConfig struct {
|
type UserChatConfig struct {
|
||||||
|
@ -293,6 +293,17 @@ func (h *ChatHandler) sendMessage(ctx context.Context, session *types.ChatSessio
|
|||||||
req.Input = map[string]interface{}{"messages": []map[string]string{{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt}}}
|
req.Input = map[string]interface{}{"messages": []map[string]string{{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt}}}
|
||||||
req.Parameters = map[string]interface{}{}
|
req.Parameters = map[string]interface{}{}
|
||||||
break
|
break
|
||||||
|
case types.Skylark:
|
||||||
|
modelStr, err := json.Marshal(map[string]interface{}{"name": req.Model})
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
req.Model = string(modelStr)
|
||||||
|
req.Parameters = map[string]interface{}{
|
||||||
|
"temperature": h.App.ChatConfig.Skylark.Temperature,
|
||||||
|
"max_new_tokens": h.App.ChatConfig.Skylark.MaxTokens,
|
||||||
|
}
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
utils.ReplyMessage(ws, "不支持的平台:"+session.Model.Platform+",请联系管理员!")
|
utils.ReplyMessage(ws, "不支持的平台:"+session.Model.Platform+",请联系管理员!")
|
||||||
utils.ReplyMessage(ws, ErrImg)
|
utils.ReplyMessage(ws, ErrImg)
|
||||||
@ -368,6 +379,8 @@ func (h *ChatHandler) sendMessage(ctx context.Context, session *types.ChatSessio
|
|||||||
return h.sendXunFeiMessage(chatCtx, req, userVo, ctx, session, role, prompt, ws)
|
return h.sendXunFeiMessage(chatCtx, req, userVo, ctx, session, role, prompt, ws)
|
||||||
case types.QWen:
|
case types.QWen:
|
||||||
return h.sendQWenMessage(chatCtx, req, userVo, ctx, session, role, prompt, ws)
|
return h.sendQWenMessage(chatCtx, req, userVo, ctx, session, role, prompt, ws)
|
||||||
|
case types.Skylark:
|
||||||
|
return h.sendSkylarkMessage(chatCtx, req, userVo, ctx, session, role, prompt, ws)
|
||||||
}
|
}
|
||||||
utils.ReplyChunkMessage(ws, types.WsMessage{
|
utils.ReplyChunkMessage(ws, types.WsMessage{
|
||||||
Type: types.WsMiddle,
|
Type: types.WsMiddle,
|
||||||
@ -465,6 +478,10 @@ func (h *ChatHandler) doRequest(ctx context.Context, req types.ApiRequest, platf
|
|||||||
apiURL = apiKey.ApiURL
|
apiURL = apiKey.ApiURL
|
||||||
req.Messages = nil
|
req.Messages = nil
|
||||||
break
|
break
|
||||||
|
case types.Skylark:
|
||||||
|
apiURL = apiKey.ApiURL
|
||||||
|
req.Input = nil
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
apiURL = apiKey.ApiURL
|
apiURL = apiKey.ApiURL
|
||||||
}
|
}
|
||||||
@ -484,6 +501,7 @@ func (h *ChatHandler) doRequest(ctx context.Context, req types.ApiRequest, platf
|
|||||||
|
|
||||||
// 创建 HttpClient 请求对象
|
// 创建 HttpClient 请求对象
|
||||||
var client *http.Client
|
var client *http.Client
|
||||||
|
req.ModelRaw = json.RawMessage(req.Model)
|
||||||
requestBody, err := json.Marshal(req)
|
requestBody, err := json.Marshal(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -528,6 +546,25 @@ func (h *ChatHandler) doRequest(ctx context.Context, req types.ApiRequest, platf
|
|||||||
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey.Value))
|
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey.Value))
|
||||||
request.Header.Set("X-DashScope-SSE", "enable")
|
request.Header.Set("X-DashScope-SSE", "enable")
|
||||||
break
|
break
|
||||||
|
case types.Skylark:
|
||||||
|
key := strings.Split(apiKey.Value, "|")
|
||||||
|
if len(key) != 2 {
|
||||||
|
return nil, errors.New("非法的 API KEY!")
|
||||||
|
}
|
||||||
|
header, err := h.makeSkylarkRequestUrl(SkylarkRequest{
|
||||||
|
Method: "POST",
|
||||||
|
Url: apiKey.ApiURL,
|
||||||
|
Body: requestBody,
|
||||||
|
AccessKeyID: key[0],
|
||||||
|
SecretAccessKey: key[1],
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for hn, hv := range header {
|
||||||
|
request.Header.Set(hn, hv[0])
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
return client.Do(request)
|
return client.Do(request)
|
||||||
}
|
}
|
||||||
|
328
api/handler/chatimpl/skylark_handler.go
Normal file
328
api/handler/chatimpl/skylark_handler.go
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
package chatimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"chatplus/core/types"
|
||||||
|
"chatplus/store/model"
|
||||||
|
"chatplus/store/vo"
|
||||||
|
"chatplus/utils"
|
||||||
|
"context"
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
Region = "cn-beijing"
|
||||||
|
Service = "ml_maas"
|
||||||
|
)
|
||||||
|
|
||||||
|
type skylarkResp struct {
|
||||||
|
Id string `json:"req_id"`
|
||||||
|
Choice struct {
|
||||||
|
Message struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
} `json:"message"`
|
||||||
|
} `json:"choice"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skylark 消息发送实现
|
||||||
|
func (h *ChatHandler) sendSkylarkMessage(
|
||||||
|
chatCtx []interface{},
|
||||||
|
req types.ApiRequest,
|
||||||
|
userVo vo.User,
|
||||||
|
ctx context.Context,
|
||||||
|
session *types.ChatSession,
|
||||||
|
role model.ChatRole,
|
||||||
|
prompt string,
|
||||||
|
ws *types.WsClient) error {
|
||||||
|
promptCreatedAt := time.Now() // 记录提问时间
|
||||||
|
start := time.Now()
|
||||||
|
var apiKey model.ApiKey
|
||||||
|
response, err := h.doRequest(ctx, req, session.Model.Platform, &apiKey)
|
||||||
|
logger.Info("HTTP请求完成,耗时:", time.Since(start))
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "context canceled") {
|
||||||
|
logger.Info("用户取消了请求:", prompt)
|
||||||
|
return nil
|
||||||
|
} else if strings.Contains(err.Error(), "no available key") {
|
||||||
|
utils.ReplyMessage(ws, "抱歉😔😔😔,系统已经没有可用的 API KEY,请联系管理员!")
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
logger.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.ReplyMessage(ws, ErrorMsg)
|
||||||
|
utils.ReplyMessage(ws, ErrImg)
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
defer response.Body.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
contentType := response.Header.Get("Content-Type")
|
||||||
|
if strings.Contains(contentType, "text/event-stream") {
|
||||||
|
replyCreatedAt := time.Now() // 记录回复时间
|
||||||
|
// 循环读取 Chunk 消息
|
||||||
|
var message = types.Message{}
|
||||||
|
var contents = make([]string, 0)
|
||||||
|
var content string
|
||||||
|
scanner := bufio.NewScanner(response.Body)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if len(line) < 5 || strings.HasPrefix(line, "id:") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(line, "data:") {
|
||||||
|
content = line[5:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if content == "[DONE]" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理代码换行
|
||||||
|
if len(content) == 0 {
|
||||||
|
content = "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp skylarkResp
|
||||||
|
err := utils.JsonDecode(content, &resp)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("error with parse data line: ", err)
|
||||||
|
utils.ReplyMessage(ws, fmt.Sprintf("**解析数据行失败:%s**", err))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(contents) == 0 {
|
||||||
|
utils.ReplyChunkMessage(ws, types.WsMessage{Type: types.WsStart})
|
||||||
|
}
|
||||||
|
utils.ReplyChunkMessage(ws, types.WsMessage{
|
||||||
|
Type: types.WsMiddle,
|
||||||
|
Content: utils.InterfaceToString(resp.Choice.Message.Content),
|
||||||
|
})
|
||||||
|
contents = append(contents, resp.Choice.Message.Content)
|
||||||
|
|
||||||
|
} // end for
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
if strings.Contains(err.Error(), "context canceled") {
|
||||||
|
logger.Info("用户取消了请求:", prompt)
|
||||||
|
} else {
|
||||||
|
logger.Error("信息读取出错:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 消息发送成功
|
||||||
|
if len(contents) > 0 {
|
||||||
|
// 更新用户的对话次数
|
||||||
|
h.subUserCalls(userVo, session)
|
||||||
|
|
||||||
|
if message.Role == "" {
|
||||||
|
message.Role = "assistant"
|
||||||
|
}
|
||||||
|
message.Content = strings.Join(contents, "")
|
||||||
|
useMsg := types.Message{Role: "user", Content: prompt}
|
||||||
|
|
||||||
|
// 更新上下文消息,如果是调用函数则不需要更新上下文
|
||||||
|
if h.App.ChatConfig.EnableContext {
|
||||||
|
chatCtx = append(chatCtx, useMsg) // 提问消息
|
||||||
|
chatCtx = append(chatCtx, message) // 回复消息
|
||||||
|
h.App.ChatContexts.Put(session.ChatId, chatCtx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 追加聊天记录
|
||||||
|
if h.App.ChatConfig.EnableHistory {
|
||||||
|
// for prompt
|
||||||
|
promptToken, err := utils.CalcTokens(prompt, req.Model)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
}
|
||||||
|
historyUserMsg := model.ChatMessage{
|
||||||
|
UserId: userVo.Id,
|
||||||
|
ChatId: session.ChatId,
|
||||||
|
RoleId: role.Id,
|
||||||
|
Type: types.PromptMsg,
|
||||||
|
Icon: userVo.Avatar,
|
||||||
|
Content: template.HTMLEscapeString(prompt),
|
||||||
|
Tokens: promptToken,
|
||||||
|
UseContext: true,
|
||||||
|
Model: req.Model,
|
||||||
|
}
|
||||||
|
historyUserMsg.CreatedAt = promptCreatedAt
|
||||||
|
historyUserMsg.UpdatedAt = promptCreatedAt
|
||||||
|
res := h.db.Save(&historyUserMsg)
|
||||||
|
if res.Error != nil {
|
||||||
|
logger.Error("failed to save prompt history message: ", res.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// for reply
|
||||||
|
// 计算本次对话消耗的总 token 数量
|
||||||
|
replyToken, _ := utils.CalcTokens(message.Content, req.Model)
|
||||||
|
totalTokens := replyToken + getTotalTokens(req)
|
||||||
|
historyReplyMsg := model.ChatMessage{
|
||||||
|
UserId: userVo.Id,
|
||||||
|
ChatId: session.ChatId,
|
||||||
|
RoleId: role.Id,
|
||||||
|
Type: types.ReplyMsg,
|
||||||
|
Icon: role.Icon,
|
||||||
|
Content: message.Content,
|
||||||
|
Tokens: totalTokens,
|
||||||
|
UseContext: true,
|
||||||
|
Model: req.Model,
|
||||||
|
}
|
||||||
|
historyReplyMsg.CreatedAt = replyCreatedAt
|
||||||
|
historyReplyMsg.UpdatedAt = replyCreatedAt
|
||||||
|
res = h.db.Create(&historyReplyMsg)
|
||||||
|
if res.Error != nil {
|
||||||
|
logger.Error("failed to save reply history message: ", res.Error)
|
||||||
|
}
|
||||||
|
// 更新用户信息
|
||||||
|
h.incUserTokenFee(userVo.Id, totalTokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存当前会话
|
||||||
|
var chatItem model.ChatItem
|
||||||
|
res := h.db.Where("chat_id = ?", session.ChatId).First(&chatItem)
|
||||||
|
if res.Error != nil {
|
||||||
|
chatItem.ChatId = session.ChatId
|
||||||
|
chatItem.UserId = session.UserId
|
||||||
|
chatItem.RoleId = role.Id
|
||||||
|
chatItem.ModelId = session.Model.Id
|
||||||
|
if utf8.RuneCountInString(prompt) > 30 {
|
||||||
|
chatItem.Title = string([]rune(prompt)[:30]) + "..."
|
||||||
|
} else {
|
||||||
|
chatItem.Title = prompt
|
||||||
|
}
|
||||||
|
chatItem.Model = req.Model
|
||||||
|
h.db.Create(&chatItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
body, err := io.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error with reading response: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var res struct {
|
||||||
|
Code int `json:"error_code"`
|
||||||
|
Msg string `json:"error_msg"`
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(body, &res)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error with decode response: %v", err)
|
||||||
|
}
|
||||||
|
utils.ReplyMessage(ws, "请求 Skylark API 失败:"+res.Msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func hmacSHA256(key []byte, content string) []byte {
|
||||||
|
mac := hmac.New(sha256.New, key)
|
||||||
|
mac.Write([]byte(content))
|
||||||
|
return mac.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSignedKey(secretKey, date, region, service string) []byte {
|
||||||
|
kDate := hmacSHA256([]byte(secretKey), date)
|
||||||
|
kRegion := hmacSHA256(kDate, region)
|
||||||
|
kService := hmacSHA256(kRegion, service)
|
||||||
|
kSigning := hmacSHA256(kService, "request")
|
||||||
|
|
||||||
|
return kSigning
|
||||||
|
}
|
||||||
|
|
||||||
|
func hashSHA256(data []byte) []byte {
|
||||||
|
hash := sha256.New()
|
||||||
|
if _, err := hash.Write(data); err != nil {
|
||||||
|
logger.Debugf("input hash err:%s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
type SkylarkRequest struct {
|
||||||
|
Method string
|
||||||
|
Url string
|
||||||
|
Body []byte
|
||||||
|
AccessKeyID string
|
||||||
|
SecretAccessKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *ChatHandler) makeSkylarkRequestUrl(params SkylarkRequest) (http.Header, error) {
|
||||||
|
ul, err := url.Parse(params.Url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
requestAddr := fmt.Sprintf("%s%s?%s", ul.Host, ul.Path, ul.Query().Encode())
|
||||||
|
logger.Debugf("request addr: %s\n", requestAddr)
|
||||||
|
|
||||||
|
var reqHeaders = http.Header{}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
date := now.UTC().Format("20060102T150405Z")
|
||||||
|
authDate := date[:8]
|
||||||
|
reqHeaders.Set("X-Date", date)
|
||||||
|
payload := hex.EncodeToString(hashSHA256(params.Body))
|
||||||
|
reqHeaders.Set("X-Content-Sha256", payload)
|
||||||
|
reqHeaders.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
queryString := strings.Replace(ul.Query().Encode(), "+", "%20", -1)
|
||||||
|
signedHeaders := []string{"content-type", "host", "x-content-sha256", "x-date"}
|
||||||
|
var headerList []string
|
||||||
|
for _, header := range signedHeaders {
|
||||||
|
if header == "host" {
|
||||||
|
headerList = append(headerList, header+":"+ul.Host)
|
||||||
|
} else {
|
||||||
|
v := reqHeaders.Get(header)
|
||||||
|
headerList = append(headerList, header+":"+strings.TrimSpace(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
headerString := strings.Join(headerList, "\n")
|
||||||
|
|
||||||
|
canonicalString := strings.Join([]string{
|
||||||
|
params.Method,
|
||||||
|
ul.Path,
|
||||||
|
queryString,
|
||||||
|
headerString + "\n",
|
||||||
|
strings.Join(signedHeaders, ";"),
|
||||||
|
payload,
|
||||||
|
}, "\n")
|
||||||
|
logger.Debugf("canonical string:\n%s\n", canonicalString)
|
||||||
|
|
||||||
|
hashedCanonicalString := hex.EncodeToString(hashSHA256([]byte(canonicalString)))
|
||||||
|
logger.Debugf("hashed canonical string: %s\n", hashedCanonicalString)
|
||||||
|
|
||||||
|
credentialScope := authDate + "/" + Region + "/" + Service + "/request"
|
||||||
|
signString := strings.Join([]string{
|
||||||
|
"HMAC-SHA256",
|
||||||
|
date,
|
||||||
|
credentialScope,
|
||||||
|
hashedCanonicalString,
|
||||||
|
}, "\n")
|
||||||
|
logger.Debugf("sign string:\n%s\n", signString)
|
||||||
|
|
||||||
|
// 3. 构建认证请求头
|
||||||
|
signedKey := getSignedKey(params.SecretAccessKey, authDate, Region, Service)
|
||||||
|
signature := hex.EncodeToString(hmacSHA256(signedKey, signString))
|
||||||
|
logger.Debugf("signature: %s\n", signature)
|
||||||
|
|
||||||
|
authorization := "HMAC-SHA256" +
|
||||||
|
" Credential=" + params.AccessKeyID + "/" + credentialScope +
|
||||||
|
", SignedHeaders=" + strings.Join(signedHeaders, ";") +
|
||||||
|
", Signature=" + signature
|
||||||
|
reqHeaders.Set("Authorization", authorization)
|
||||||
|
logger.Debugf("authorization: %s\n", authorization)
|
||||||
|
|
||||||
|
return reqHeaders, nil
|
||||||
|
}
|
@ -127,7 +127,11 @@ INSERT INTO `chatgpt_chat_models` (`id`, `platform`, `name`, `value`, `sort_num`
|
|||||||
(16, 'OpenAI', 'MJ Prompt Generator (V6)', 'gpt-4-gizmo-g-tc0eHXdgb', 0, 1, 1, 1, '2024-01-15 14:46:35', '2024-01-15 14:53:16'),
|
(16, 'OpenAI', 'MJ Prompt Generator (V6)', 'gpt-4-gizmo-g-tc0eHXdgb', 0, 1, 1, 1, '2024-01-15 14:46:35', '2024-01-15 14:53:16'),
|
||||||
(17, 'QWen', '通义千问-Turbo', 'qwen-turbo', 0, 1, 1, 1, '2024-01-19 10:42:24', '2024-01-19 10:45:16'),
|
(17, 'QWen', '通义千问-Turbo', 'qwen-turbo', 0, 1, 1, 1, '2024-01-19 10:42:24', '2024-01-19 10:45:16'),
|
||||||
(18, 'QWen', '通义千问-Plus', 'qwen-plus', 0, 1, 1, 1, '2024-01-19 10:42:49', '2024-01-19 10:51:09'),
|
(18, 'QWen', '通义千问-Plus', 'qwen-plus', 0, 1, 1, 1, '2024-01-19 10:42:49', '2024-01-19 10:51:09'),
|
||||||
(19, 'QWen', '通义千问-Max', 'qwen-max-1201', 0, 1, 1, 1, '2024-01-19 10:51:03', '2024-01-19 10:51:03');
|
(19, 'QWen', '通义千问-Max', 'qwen-max-1201', 0, 1, 1, 1, '2024-01-19 10:51:03', '2024-01-19 10:51:03')
|
||||||
|
(20, 'Skylark', 'Skylark-Lite', 'skylark-lite-public', 0, 1, 1, 1, '2024-03-11 17:07:24', '2024-03-11 17:07:26'),
|
||||||
|
(21, 'Skylark', 'Skylark-Plus', 'skylark-plus-public', 0, 1, 1, 1, '2024-03-11 17:07:24', '2024-03-11 17:07:26'),
|
||||||
|
(22, 'Skylark', 'Skylark-Pro', 'skylark-pro-public', 0, 1, 1, 1, '2024-03-11 17:07:24', '2024-03-11 17:07:26'),
|
||||||
|
(23, 'Skylark', 'Skylark-Chat', 'skylark-chat', 0, 1, 1, 1, '2024-03-11 17:07:24', '2024-03-11 17:07:26');
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
@ -191,7 +195,7 @@ CREATE TABLE `chatgpt_configs` (
|
|||||||
|
|
||||||
INSERT INTO `chatgpt_configs` (`id`, `marker`, `config_json`) VALUES
|
INSERT INTO `chatgpt_configs` (`id`, `marker`, `config_json`) VALUES
|
||||||
(1, 'system', '{\"admin_title\":\"ChatPlus 控制台\",\"chat_call_price\":0.1,\"default_models\":[\"eb-instant\",\"completions_pro\",\"generalv2\",\"general\",\"chatglm_pro\",\"gpt-3.5-turbo-16k\",\"chatglm_lite\",\"chatglm_std\",\"generalv3\",\"qwen-max-1201\"],\"enabled_alipay\":true,\"enabled_draw\":true,\"enabled_function\":true,\"enabled_msg\":true,\"enabled_msg_service\":false,\"enabled_register\":true,\"enabled_reward\":true,\"force_invite\":false,\"img_call_price\":0.2,\"init_calls\":1000,\"init_chat_calls\":10,\"init_img_calls\":5,\"invite_calls\":10,\"invite_chat_calls\":100,\"invite_img_calls\":50,\"models\":[\"gpt-3.5-turbo-16k\",\"gpt-3.5-turbo\",\"gpt-4\",\"gpt-4-32k\"],\"order_pay_info_text\":\"成为本站会员后每月有500次对话额度,50次 AI 绘画额度,限制下月1号解除,若在期间超过次数后可单独购买点卡。当月充值的点卡有效期可以延期到下个月底。\",\"order_pay_timeout\":1800,\"register_ways\":[],\"reward_img\":\"https://img.r9it.com/chatgpt-plus/1696824231905289.png\",\"show_demo_notice\":true,\"title\":\"ChatPlus AI 智能助手\",\"user_init_calls\":10,\"vip_month_calls\":500,\"vip_month_img_calls\":50,\"wechat_card_url\":\"/images/wx.png\"}'),
|
(1, 'system', '{\"admin_title\":\"ChatPlus 控制台\",\"chat_call_price\":0.1,\"default_models\":[\"eb-instant\",\"completions_pro\",\"generalv2\",\"general\",\"chatglm_pro\",\"gpt-3.5-turbo-16k\",\"chatglm_lite\",\"chatglm_std\",\"generalv3\",\"qwen-max-1201\"],\"enabled_alipay\":true,\"enabled_draw\":true,\"enabled_function\":true,\"enabled_msg\":true,\"enabled_msg_service\":false,\"enabled_register\":true,\"enabled_reward\":true,\"force_invite\":false,\"img_call_price\":0.2,\"init_calls\":1000,\"init_chat_calls\":10,\"init_img_calls\":5,\"invite_calls\":10,\"invite_chat_calls\":100,\"invite_img_calls\":50,\"models\":[\"gpt-3.5-turbo-16k\",\"gpt-3.5-turbo\",\"gpt-4\",\"gpt-4-32k\"],\"order_pay_info_text\":\"成为本站会员后每月有500次对话额度,50次 AI 绘画额度,限制下月1号解除,若在期间超过次数后可单独购买点卡。当月充值的点卡有效期可以延期到下个月底。\",\"order_pay_timeout\":1800,\"register_ways\":[],\"reward_img\":\"https://img.r9it.com/chatgpt-plus/1696824231905289.png\",\"show_demo_notice\":true,\"title\":\"ChatPlus AI 智能助手\",\"user_init_calls\":10,\"vip_month_calls\":500,\"vip_month_img_calls\":50,\"wechat_card_url\":\"/images/wx.png\"}'),
|
||||||
(2, 'chat', '{\"azure\":{\"api_url\":\"https://chat-bot-api.openai.azure.com/openai/deployments/{model}/chat/completions?api-version=2023-05-15\",\"max_tokens\":1024,\"temperature\":1},\"baidu\":{\"api_url\":\"https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/{model}\",\"max_tokens\":1024,\"temperature\":0.95},\"chat_gml\":{\"api_url\":\"https://open.bigmodel.cn/api/paas/v3/model-api/{model}/sse-invoke\",\"max_tokens\":1024,\"temperature\":0.95},\"context_deep\":4,\"dall_api_url\":\"http://89.117.18.9:8001/v1/images/generations\",\"dall_img_num\":1,\"enable_context\":true,\"enable_history\":true,\"open_ai\":{\"api_url\":\"https://api.fast-tunnel.one/v1/chat/completions\",\"max_tokens\":2048,\"temperature\":1},\"xun_fei\":{\"api_url\":\"wss://spark-api.xf-yun.com/{version}/chat\",\"max_tokens\":1024,\"temperature\":0.5}}'),
|
(2, 'chat', '{\"azure\":{\"api_url\":\"https://chat-bot-api.openai.azure.com/openai/deployments/{model}/chat/completions?api-version=2023-05-15\",\"max_tokens\":1024,\"temperature\":1},\"baidu\":{\"api_url\":\"https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/{model}\",\"max_tokens\":1024,\"temperature\":0.95},\"chat_gml\":{\"api_url\":\"https://open.bigmodel.cn/api/paas/v3/model-api/{model}/sse-invoke\",\"max_tokens\":1024,\"temperature\":0.95},\"context_deep\":4,\"dall_api_url\":\"http://89.117.18.9:8001/v1/images/generations\",\"dall_img_num\":1,\"enable_context\":true,\"enable_history\":true,\"open_ai\":{\"api_url\":\"https://api.fast-tunnel.one/v1/chat/completions\",\"max_tokens\":2048,\"temperature\":1},\"xun_fei\":{\"api_url\":\"wss://spark-api.xf-yun.com/{version}/chat\",\"max_tokens\":1024,\"temperature\":0.5},"skylark":{"api_url":"https://maas-api.ml-platform-cn-beijing.volces.com/api/v1/chat","max_tokens":1024,"temperature":0.7}}'),
|
||||||
(3, 'notice', '{\"content\":\"注意:当前站点仅为开源项目 \\u003ca style=\\\"color: #F56C6C\\\" href=\\\"https://github.com/yangjian102621/chatgpt-plus\\\" target=\\\"_blank\\\"\\u003eChatPlus\\u003c/a\\u003e 的演示项目,本项目单纯就是给大家体验项目功能使用。\\n体验额度用完之后请不要在当前站点进行任何充值操作!!!\\n体验额度用完之后请不要在当前站点进行任何充值操作!!!\\n体验额度用完之后请不要在当前站点进行任何充值操作!!!\\n 如果觉得好用你就花几分钟自己部署一套,没有API KEY 的同学可以去 \\u003ca href=\\\"https://gpt.bemore.lol\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://gpt.bemore.lol\\u003c/a\\u003e 购买,现在有超级优惠,价格远低于 OpenAI 官方。\\nGPT-3.5,GPT-4,DALL-E3 绘图......你都可以随意使用,无需魔法。\\nMidJourney API 购买地址:\\u003ca href=\\\"https://api.chat-plus.net\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://api.chat-plus.net\\u003c/a\\u003e\\n接入教程: \\u003ca href=\\\"https://ai.r9it.com/docs/install/\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://ai.r9it.com/docs/install/\\u003c/a\\u003e\\n本项目源码地址:\\u003ca href=\\\"https://github.com/yangjian102621/chatgpt-plus\\\" target=\\\"_blank\\\"\\u003ehttps://github.com/yangjian102621/chatgpt-plus\\u003c/a\\u003e\",\"updated\":true}');
|
(3, 'notice', '{\"content\":\"注意:当前站点仅为开源项目 \\u003ca style=\\\"color: #F56C6C\\\" href=\\\"https://github.com/yangjian102621/chatgpt-plus\\\" target=\\\"_blank\\\"\\u003eChatPlus\\u003c/a\\u003e 的演示项目,本项目单纯就是给大家体验项目功能使用。\\n体验额度用完之后请不要在当前站点进行任何充值操作!!!\\n体验额度用完之后请不要在当前站点进行任何充值操作!!!\\n体验额度用完之后请不要在当前站点进行任何充值操作!!!\\n 如果觉得好用你就花几分钟自己部署一套,没有API KEY 的同学可以去 \\u003ca href=\\\"https://gpt.bemore.lol\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://gpt.bemore.lol\\u003c/a\\u003e 购买,现在有超级优惠,价格远低于 OpenAI 官方。\\nGPT-3.5,GPT-4,DALL-E3 绘图......你都可以随意使用,无需魔法。\\nMidJourney API 购买地址:\\u003ca href=\\\"https://api.chat-plus.net\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://api.chat-plus.net\\u003c/a\\u003e\\n接入教程: \\u003ca href=\\\"https://ai.r9it.com/docs/install/\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://ai.r9it.com/docs/install/\\u003c/a\\u003e\\n本项目源码地址:\\u003ca href=\\\"https://github.com/yangjian102621/chatgpt-plus\\\" target=\\\"_blank\\\"\\u003ehttps://github.com/yangjian102621/chatgpt-plus\\u003c/a\\u003e\",\"updated\":true}');
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
@ -180,6 +180,11 @@ const platforms = ref([
|
|||||||
value: "QWen",
|
value: "QWen",
|
||||||
api_url: "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"
|
api_url: "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "【火山引擎】Skylark",
|
||||||
|
value: "Skylark",
|
||||||
|
api_url: "https://maas-api.ml-platform-cn-beijing.volces.com/api/v1/chat"
|
||||||
|
},
|
||||||
])
|
])
|
||||||
const types = ref([
|
const types = ref([
|
||||||
{name: "聊天", value: "chat"},
|
{name: "聊天", value: "chat"},
|
||||||
|
@ -135,6 +135,7 @@ const platforms = ref([
|
|||||||
{name: "【百度】文心一言", value: "Baidu"},
|
{name: "【百度】文心一言", value: "Baidu"},
|
||||||
{name: "【微软】Azure", value: "Azure"},
|
{name: "【微软】Azure", value: "Azure"},
|
||||||
{name: "【阿里】通义千问", value: "QWen"},
|
{name: "【阿里】通义千问", value: "QWen"},
|
||||||
|
{name: "【火山引擎】Skylark", value: "Skylark"},
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user