|
@@ -2,14 +2,8 @@ package chat
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
- "encoding/json"
|
|
|
"errors"
|
|
|
- "fmt"
|
|
|
- "net"
|
|
|
- "net/url"
|
|
|
- "regexp"
|
|
|
"strconv"
|
|
|
- "strings"
|
|
|
|
|
|
"wechat-api/ent"
|
|
|
"wechat-api/internal/svc"
|
|
@@ -31,21 +25,6 @@ type ChatCompletionsLogic struct {
|
|
|
svcCtx *svc.ServiceContext
|
|
|
}
|
|
|
|
|
|
-type FastgptChatLogic struct {
|
|
|
- ChatCompletionsLogic
|
|
|
-}
|
|
|
-
|
|
|
-type MismatchChatLogic struct {
|
|
|
- ChatCompletionsLogic
|
|
|
-}
|
|
|
-
|
|
|
-type baseLogicWorkflow interface {
|
|
|
- AppendAsyncRequest(apiKeyObj *ent.ApiKey, req *types.CompApiReq) error
|
|
|
- DoSyncRequest(apiKeyObj *ent.ApiKey, req *types.CompApiReq) (*types.CompOpenApiResp, error)
|
|
|
- AppendUsageDetailLog(authToken string, req *types.CompApiReq, resp *types.CompOpenApiResp) error
|
|
|
- AdjustRequest(req *types.CompApiReq, apiKeyObj *ent.ApiKey)
|
|
|
-}
|
|
|
-
|
|
|
func NewChatCompletionsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChatCompletionsLogic {
|
|
|
return &ChatCompletionsLogic{
|
|
|
Logger: logx.WithContext(ctx),
|
|
@@ -53,237 +32,68 @@ func NewChatCompletionsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *C
|
|
|
svcCtx: svcCtx}
|
|
|
}
|
|
|
|
|
|
-func (l *FastgptChatLogic) AdjustRequest(req *types.CompApiReq, apiKeyObj *ent.ApiKey) {
|
|
|
-
|
|
|
- l.ChatCompletionsLogic.AdjustRequest(req, apiKeyObj) //先父类的参数调整
|
|
|
-
|
|
|
- if req.EventType != "fastgpt" {
|
|
|
- return
|
|
|
- }
|
|
|
- if len(req.Model) > 0 {
|
|
|
- if req.Variables == nil {
|
|
|
- req.Variables = make(map[string]string)
|
|
|
- }
|
|
|
- req.Variables["model"] = req.Model
|
|
|
- }
|
|
|
-
|
|
|
- if len(req.ChatId) > 0 && len(req.FastgptChatId) == 0 {
|
|
|
- req.FastgptChatId = req.ChatId
|
|
|
- } else if len(req.ChatId) == 0 && len(req.FastgptChatId) > 0 {
|
|
|
- req.ChatId = req.FastgptChatId
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func (l *ChatCompletionsLogic) ChatCompletions(req *types.CompApiReq) (asyncMode bool, resp *types.CompOpenApiResp, err error) {
|
|
|
+func (l *ChatCompletionsLogic) ChatCompletions(req *types.CompApiReq) (resp *types.CompOpenApiResp, err error) {
|
|
|
// todo: add your logic here and delete this line
|
|
|
|
|
|
+ /*
|
|
|
+ 1.鉴权获得token
|
|
|
+ 2.必要参数检测及转换
|
|
|
+ 3. 根据event_type选择不同处理路由
|
|
|
+ */
|
|
|
var (
|
|
|
apiKeyObj *ent.ApiKey
|
|
|
ok bool
|
|
|
)
|
|
|
- asyncMode = false
|
|
|
-
|
|
|
- //从上下文中获取鉴权中间件埋下的apiAuthInfo
|
|
|
+ workToken := compapi.GetWorkTokenByID(req.EventType, req.WorkId)
|
|
|
apiKeyObj, ok = contextkey.AuthTokenInfoKey.GetValue(l.ctx)
|
|
|
if !ok {
|
|
|
- return asyncMode, nil, errors.New("content get auth info err")
|
|
|
+ return nil, errors.New("content get token err")
|
|
|
+ }
|
|
|
+ if req.WorkId == "TEST_DOUYIN" || req.WorkId == "TEST_DOUYIN_CN" || req.WorkId == "travel" || req.WorkId == "loreal" || req.WorkId == "xiulike-dc" || req.WorkId == "wuhanzhongxin" { //临时加
|
|
|
+ apiKeyObj.OpenaiBase = "http://cn-agent.gkscrm.com/api/v1/"
|
|
|
+ if req.WorkId == "TEST_DOUYIN" || req.WorkId == "TEST_DOUYIN_CN" {
|
|
|
+ workToken = "fastgpt-jsMmQKEM5uX7tDimT1zHlZHkBhMHRT2k61YaxyDJRZTUHehID7sG8BKXADNIU"
|
|
|
+ } else if req.WorkId == "travel" {
|
|
|
+ workToken = "fastgpt-bcnfFtw1lXWdmYGOv165UVD5R1kY28tyXX8SJv8MHhrSMOgVJsuU"
|
|
|
+ } else if req.WorkId == "loreal" {
|
|
|
+ workToken = "fastgpt-qqJeBEkwhgx7wR9fvGToQygmOb7FVjAbGBTFjOAMbd95InEtndke"
|
|
|
+ } else if req.WorkId == "xiulike-dc" {
|
|
|
+ workToken = "fastgpt-ir9RgnKHMT9HIOnPsUCFChN15ZbW9kt1lbd5Y0ohfLw9gOz3KcPrfaZWHRB"
|
|
|
+ } else if req.WorkId == "wuhanzhongxin" {
|
|
|
+ workToken = "fastgpt-jX6Gl50Ivrc7vzyD4xNlahG11cgmJ4N63QHKrntt2gQ78g31haxuAsA"
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
- //微调apiKeyObj的openaikey
|
|
|
- //apiKeyObjAdjust(req.EventType, req.WorkId, apiKeyObj)
|
|
|
+
|
|
|
/*
|
|
|
fmt.Println("=========================================")
|
|
|
fmt.Printf("In ChatCompletion Get Token Info:\nKey:'%s'\n", apiKeyObj.Key)
|
|
|
- fmt.Printf("Auth Token:'%s'\n", apiKeyObj.Key)
|
|
|
- fmt.Printf("ApiKey AgentID:%d\n", apiKeyObj.AgentID)
|
|
|
- fmt.Printf("ApiKey APIBase:'%s'\n", apiKeyObj.Edges.Agent.APIBase)
|
|
|
- fmt.Printf("ApiKey APIKey:'%s'\n", apiKeyObj.Edges.Agent.APIKey)
|
|
|
- fmt.Printf("ApiKey Type:%d\n", apiKeyObj.Edges.Agent.Type)
|
|
|
- fmt.Printf("ApiKey Model:'%s'\n", apiKeyObj.Edges.Agent.Model)
|
|
|
- fmt.Printf("EventType:'%s'\n", req.EventType)
|
|
|
- fmt.Printf("req.ChatId:'%s VS req.FastgptChatId:'%s'\n", req.ChatId, req.FastgptChatId)
|
|
|
+ fmt.Printf("Title:'%s'\n", apiKeyObj.Title)
|
|
|
+ fmt.Printf("OpenaiBase:'%s'\n", apiKeyObj.OpenaiBase)
|
|
|
+ fmt.Printf("OpenaiKey:'%s'\n", apiKeyObj.OpenaiKey)
|
|
|
+ fmt.Printf("workToken:'%s' because %s/%s\n", workToken, req.EventType, req.WorkId)
|
|
|
fmt.Println("=========================================")
|
|
|
*/
|
|
|
|
|
|
- //根据请求产生相关的工作流接口集
|
|
|
- wf, err := l.getLogicWorkflow(apiKeyObj, req)
|
|
|
- if err != nil {
|
|
|
- return false, nil, err
|
|
|
+ if len(apiKeyObj.OpenaiBase) == 0 || len(workToken) == 0 {
|
|
|
+ return nil, errors.New("not auth info")
|
|
|
}
|
|
|
- /*
|
|
|
- switch wf.(type) {
|
|
|
- case *MismatchChatLogic:
|
|
|
- fmt.Println("MismatchChatLogic Flow.....")
|
|
|
- case *FastgptChatLogic:
|
|
|
- fmt.Println("FastgptChatLogic Flow.....")
|
|
|
- default:
|
|
|
- fmt.Println("Other Flow.....")
|
|
|
- }
|
|
|
- */
|
|
|
|
|
|
- //微调部分请求参数
|
|
|
- wf.AdjustRequest(req, apiKeyObj)
|
|
|
-
|
|
|
- if isAsyncReqest(req) { //异步请求处理模式
|
|
|
- asyncMode = true
|
|
|
- err = wf.AppendAsyncRequest(apiKeyObj, req)
|
|
|
- } else { //同步请求处理模式
|
|
|
- resp, err = wf.DoSyncRequest(apiKeyObj, req)
|
|
|
- if err == nil && resp != nil && len(resp.Choices) > 0 {
|
|
|
- wf.AppendUsageDetailLog(apiKeyObj.Key, req, resp) //请求记录
|
|
|
- } else if resp != nil && len(resp.Choices) == 0 {
|
|
|
- err = errors.New("返回结果缺失,请检查访问地址及权限")
|
|
|
- }
|
|
|
+ apiResp, err := l.workForFastgpt(req, workToken, apiKeyObj.OpenaiBase)
|
|
|
+ if err == nil && apiResp != nil {
|
|
|
+ l.doRequestLog(req, apiResp) //请求记录
|
|
|
}
|
|
|
- return asyncMode, resp, err
|
|
|
-}
|
|
|
|
|
|
-func (l *ChatCompletionsLogic) getLogicWorkflow(apiKeyObj *ent.ApiKey, req *types.CompApiReq) (baseLogicWorkflow, error) {
|
|
|
- var (
|
|
|
- err error
|
|
|
- wf baseLogicWorkflow
|
|
|
- )
|
|
|
-
|
|
|
- if apiKeyObj.Edges.Agent.Type != 2 {
|
|
|
- err = fmt.Errorf("api agent type not support(%d)", apiKeyObj.Edges.Agent.Type)
|
|
|
- } else if req.EventType == "mismatch" {
|
|
|
- wf = &MismatchChatLogic{ChatCompletionsLogic: *l}
|
|
|
- } else {
|
|
|
- wf = &FastgptChatLogic{ChatCompletionsLogic: *l}
|
|
|
- }
|
|
|
- return wf, err
|
|
|
+ return apiResp, err
|
|
|
}
|
|
|
|
|
|
-func (l *ChatCompletionsLogic) AdjustRequest(req *types.CompApiReq, apiKeyObj *ent.ApiKey) {
|
|
|
-
|
|
|
- if len(req.EventType) == 0 {
|
|
|
- req.EventType = "fastgpt"
|
|
|
- }
|
|
|
-
|
|
|
- if len(req.Model) == 0 && len(apiKeyObj.Edges.Agent.Model) > 0 {
|
|
|
- req.Model = apiKeyObj.Edges.Agent.Model
|
|
|
- }
|
|
|
-
|
|
|
- //异步任务相关参数调整
|
|
|
- if req.IsBatch {
|
|
|
- //流模式暂时不支持异步模式
|
|
|
- //Callback格式非法则取消批量模式
|
|
|
- if req.Stream || !IsValidURL(&req.Callback, true) {
|
|
|
- req.IsBatch = false
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func (l *ChatCompletionsLogic) DoSyncRequest(apiKeyObj *ent.ApiKey, req *types.CompApiReq) (*types.CompOpenApiResp, error) {
|
|
|
- //return compapi.NewFastgptChatCompletions(l.ctx, apiKeyObj.Edges.Agent.APIKey, apiKeyObj.Edges.Agent.APIBase, req)
|
|
|
- resp, err := compapi.NewClient(l.ctx, compapi.WithApiBase(apiKeyObj.Edges.Agent.APIBase),
|
|
|
- compapi.WithApiKey(apiKeyObj.Edges.Agent.APIKey)).
|
|
|
- Chat(req)
|
|
|
-
|
|
|
- /*
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- if req.EventType == "mismatch" {
|
|
|
-
|
|
|
- client := compapi.MismatchClient{}
|
|
|
- taskData := ent.CompapiAsynctask{}
|
|
|
- taskData.ID = 1234
|
|
|
- taskData.ResponseChatItemID = req.ResponseChatItemId
|
|
|
- taskData.EventType = req.EventType
|
|
|
- taskData.ChatID = req.ChatId
|
|
|
- var err error
|
|
|
- taskData.ResponseRaw, err = resp.ToString()
|
|
|
- if err != nil {
|
|
|
- fmt.Println(err)
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- var bs []byte
|
|
|
- bs, err = client.CallbackPrepare(&taskData)
|
|
|
- if err != nil {
|
|
|
- fmt.Println(err)
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- fmt.Println(string(bs))
|
|
|
- nres := map[string]string{}
|
|
|
- err = json.Unmarshal(bs, &nres)
|
|
|
- if err != nil {
|
|
|
- fmt.Println(err)
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- fmt.Println(typekit.PrettyPrint(nres))
|
|
|
-
|
|
|
- res := compapi.MismatchResponse{}
|
|
|
- err = compapi.NewChatResult(resp).ParseContentAs(&res)
|
|
|
- fmt.Println(err)
|
|
|
- fmt.Println(typekit.PrettyPrint(res))
|
|
|
- }
|
|
|
- */
|
|
|
- return resp, err
|
|
|
-}
|
|
|
-
|
|
|
-func (l *ChatCompletionsLogic) AppendAsyncRequest(apiKeyObj *ent.ApiKey, req *types.CompApiReq) error {
|
|
|
-
|
|
|
- rawReqBs, err := json.Marshal(*req)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
+func (l *ChatCompletionsLogic) doRequestLog(req *types.CompApiReq, resp *types.CompOpenApiResp) error {
|
|
|
+ authToken, ok := contextkey.OpenapiTokenKey.GetValue(l.ctx)
|
|
|
+ if !ok {
|
|
|
+ return errors.New("content get auth token err")
|
|
|
}
|
|
|
- rawReqStr := string(rawReqBs)
|
|
|
- res, err := l.svcCtx.DB.CompapiAsynctask.Create().
|
|
|
- SetNotNilAuthToken(&apiKeyObj.Key).
|
|
|
- SetNotNilOpenaiBase(&apiKeyObj.Edges.Agent.APIBase).
|
|
|
- SetNotNilOpenaiKey(&apiKeyObj.Edges.Agent.APIKey).
|
|
|
- SetNotNilOrganizationID(&apiKeyObj.OrganizationID).
|
|
|
- SetNotNilEventType(&req.EventType).
|
|
|
- SetNillableModel(&req.Model).
|
|
|
- SetNillableChatID(&req.ChatId).
|
|
|
- SetNillableResponseChatItemID(&req.ResponseChatItemId).
|
|
|
- SetNotNilRequestRaw(&rawReqStr).
|
|
|
- SetNotNilCallbackURL(&req.Callback).
|
|
|
- Save(l.ctx)
|
|
|
|
|
|
- if err == nil {
|
|
|
- logx.Infof("appendAsyncRequest succ,get id:%d", res.ID)
|
|
|
- }
|
|
|
- return err
|
|
|
-}
|
|
|
-
|
|
|
-func (l *ChatCompletionsLogic) AppendUsageDetailLog(authToken string, req *types.CompApiReq, resp *types.CompOpenApiResp) error {
|
|
|
-
|
|
|
- logType := 5
|
|
|
- rawReqResp := custom_types.OriginalData{Request: req, Response: resp}
|
|
|
- tmpId := 0
|
|
|
- tmpId, _ = strconv.Atoi(resp.ID)
|
|
|
- sessionId := uint64(tmpId)
|
|
|
- orgId := uint64(0)
|
|
|
- apiKeyObj, ok := contextkey.AuthTokenInfoKey.GetValue(l.ctx)
|
|
|
- if ok {
|
|
|
- orgId = apiKeyObj.OrganizationID
|
|
|
- }
|
|
|
- promptTokens := uint64(resp.Usage.PromptTokens)
|
|
|
- completionToken := uint64(resp.Usage.CompletionTokens)
|
|
|
- totalTokens := promptTokens + completionToken
|
|
|
-
|
|
|
- msgContent := getMessageContentStr(req.Messages[0].Content)
|
|
|
-
|
|
|
- _, _, _ = logType, sessionId, totalTokens
|
|
|
- res, err := l.svcCtx.DB.UsageDetail.Create().
|
|
|
- SetNotNilType(&logType).
|
|
|
- SetNotNilBotID(&authToken).
|
|
|
- SetNotNilReceiverID(&req.EventType).
|
|
|
- SetNotNilSessionID(&sessionId).
|
|
|
- SetNillableRequest(&msgContent).
|
|
|
- SetNillableResponse(&resp.Choices[0].Message.Content).
|
|
|
- SetNillableOrganizationID(&orgId).
|
|
|
- SetOriginalData(rawReqResp).
|
|
|
- SetNillablePromptTokens(&promptTokens).
|
|
|
- SetNillableCompletionTokens(&completionToken).
|
|
|
- SetNillableTotalTokens(&totalTokens).
|
|
|
- Save(l.ctx)
|
|
|
-
|
|
|
- if err == nil { //插入UsageDetai之后再统计UsageTotal
|
|
|
- l.updateUsageTotal(authToken, res.ID, orgId)
|
|
|
- }
|
|
|
- return err
|
|
|
+ return l.appendUsageDetailLog(authToken, req, resp)
|
|
|
}
|
|
|
|
|
|
func (l *ChatCompletionsLogic) getUsagetotalIdByToken(authToken string) (uint64, error) {
|
|
@@ -351,105 +161,72 @@ func (l *ChatCompletionsLogic) sumTotalTokensByAuthToken(authToken string) (uint
|
|
|
return totalTokens, err
|
|
|
}
|
|
|
|
|
|
-func apiKeyObjAdjust(eventType string, workId string, obj *ent.ApiKey) {
|
|
|
- if eventType != "fastgpt" {
|
|
|
- return
|
|
|
- }
|
|
|
- obj.OpenaiKey, _ = compapi.GetWorkInfoByID(eventType, workId)
|
|
|
-}
|
|
|
-
|
|
|
-// 合法域名正则(支持通配符、中文域名等场景按需调整)
|
|
|
-var domainRegex = regexp.MustCompile(
|
|
|
- // 多级域名(如 example.com)
|
|
|
- `^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,63}$` +
|
|
|
- `|` +
|
|
|
- // 单级域名(如 localhost 或 mytest-svc)
|
|
|
- `^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$`,
|
|
|
-)
|
|
|
-
|
|
|
-func IsValidURL(input *string, adjust bool) bool {
|
|
|
- // 空值直接返回
|
|
|
- if *input == "" {
|
|
|
- return false
|
|
|
- }
|
|
|
- inputStr := *input
|
|
|
-
|
|
|
- // --- 预处理输入:自动补全协议 ---
|
|
|
- // 若输入不包含协议头,默认添加 http://
|
|
|
- if !strings.Contains(*input, "://") {
|
|
|
- inputStr = "http://" + *input
|
|
|
- }
|
|
|
-
|
|
|
- // --- 解析 URL ---
|
|
|
- u, err := url.Parse(inputStr)
|
|
|
- if err != nil {
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- // --- 校验协议 ---
|
|
|
- // 只允许常见协议(按需扩展)
|
|
|
- switch u.Scheme {
|
|
|
- case "http", "https", "ftp", "ftps":
|
|
|
- default:
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- // --- 拆分 Host 和 Port ---
|
|
|
- host, port, err := net.SplitHostPort(u.Host)
|
|
|
- if err != nil {
|
|
|
- // 无端口时,整个 Host 作为主机名
|
|
|
- host = u.Host
|
|
|
- port = ""
|
|
|
- }
|
|
|
+func (l *ChatCompletionsLogic) appendUsageDetailLog(authToken string, req *types.CompApiReq, resp *types.CompOpenApiResp) error {
|
|
|
|
|
|
- // --- 校验主机名 ---
|
|
|
- // 场景1:IPv4 或 IPv6
|
|
|
- if ip := net.ParseIP(host); ip != nil {
|
|
|
- // 允许私有或保留 IP(按需调整)
|
|
|
- // 示例中允许所有合法 IP
|
|
|
- } else {
|
|
|
- // 场景2:域名(包括 localhost)
|
|
|
- if !domainRegex.MatchString(host) {
|
|
|
- return false
|
|
|
- }
|
|
|
- }
|
|
|
+ logType := 5
|
|
|
+ workIdx := compapi.GetWorkIdxByID(req.EventType, req.WorkId)
|
|
|
+ rawReqResp := custom_types.OriginalData{Request: req, Response: resp}
|
|
|
|
|
|
- // --- 校验端口 ---
|
|
|
- if port != "" {
|
|
|
- p, err := net.LookupPort("tcp", port) // 动态获取端口(如 "http" 对应 80)
|
|
|
- if err != nil {
|
|
|
- // 直接尝试解析为数字端口
|
|
|
- numPort, err := strconv.Atoi(port)
|
|
|
- if err != nil || numPort < 1 || numPort > 65535 {
|
|
|
- return false
|
|
|
- }
|
|
|
- } else if p == 0 { // 动态端口为 0 时无效
|
|
|
- return false
|
|
|
- }
|
|
|
- }
|
|
|
- if adjust {
|
|
|
- *input = inputStr
|
|
|
+ tmpId := 0
|
|
|
+ tmpId, _ = strconv.Atoi(resp.ID)
|
|
|
+ sessionId := uint64(tmpId)
|
|
|
+ orgId := uint64(0)
|
|
|
+ apiKeyObj, ok := contextkey.AuthTokenInfoKey.GetValue(l.ctx)
|
|
|
+ if ok {
|
|
|
+ orgId = apiKeyObj.OrganizationID
|
|
|
}
|
|
|
- return true
|
|
|
-}
|
|
|
+ promptTokens := uint64(resp.Usage.PromptTokens)
|
|
|
+ completionToken := uint64(resp.Usage.CompletionTokens)
|
|
|
+ totalTokens := promptTokens + completionToken
|
|
|
|
|
|
-func getMessageContentStr(input any) string {
|
|
|
- str := ""
|
|
|
- switch val := input.(type) {
|
|
|
+ msgContent := ""
|
|
|
+ switch val := req.Messages[0].Content.(type) {
|
|
|
case string:
|
|
|
- str = val
|
|
|
+ msgContent = val
|
|
|
case []interface{}:
|
|
|
if len(val) > 0 {
|
|
|
if valc, ok := val[0].(map[string]interface{}); ok {
|
|
|
if valcc, ok := valc["text"]; ok {
|
|
|
- str, _ = valcc.(string)
|
|
|
+ msgContent, _ = valcc.(string)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- return str
|
|
|
+
|
|
|
+ res, err := l.svcCtx.DB.UsageDetail.Create().
|
|
|
+ SetNotNilType(&logType).
|
|
|
+ SetNotNilBotID(&authToken).
|
|
|
+ SetNotNilReceiverID(&req.EventType).
|
|
|
+ SetNotNilSessionID(&sessionId).
|
|
|
+ SetNillableApp(&workIdx).
|
|
|
+ //SetNillableRequest(&req.Messages[0].Content).
|
|
|
+ SetNillableRequest(&msgContent).
|
|
|
+ SetNillableResponse(&resp.Choices[0].Message.Content).
|
|
|
+ SetNillableOrganizationID(&orgId).
|
|
|
+ SetOriginalData(rawReqResp).
|
|
|
+ SetNillablePromptTokens(&promptTokens).
|
|
|
+ SetNillableCompletionTokens(&completionToken).
|
|
|
+ SetNillableTotalTokens(&totalTokens).
|
|
|
+ Save(l.ctx)
|
|
|
+
|
|
|
+ if err == nil { //插入UsageDetai之后再统计UsageTotal
|
|
|
+ l.updateUsageTotal(authToken, res.ID, orgId)
|
|
|
+ }
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
-func isAsyncReqest(req *types.CompApiReq) bool {
|
|
|
- return req.IsBatch
|
|
|
+func (l *ChatCompletionsLogic) workForFastgpt(req *types.CompApiReq, apiKey string, apiBase string) (resp *types.CompOpenApiResp, err error) {
|
|
|
+
|
|
|
+ //apiKey := "fastgpt-d2uehCb2T40h9chNGjf4bpFrVKmMkCFPbrjfVLZ6DAL2zzqzOFJWP"
|
|
|
+ if len(req.ChatId) > 0 && len(req.FastgptChatId) == 0 {
|
|
|
+ req.FastgptChatId = req.ChatId
|
|
|
+ }
|
|
|
+ if len(req.Model) > 0 {
|
|
|
+ if req.Variables == nil {
|
|
|
+ req.Variables = make(map[string]string)
|
|
|
+ }
|
|
|
+ req.Variables["model"] = req.Model
|
|
|
+ }
|
|
|
+ return compapi.NewFastgptChatCompletions(l.ctx, apiKey, apiBase, req)
|
|
|
+
|
|
|
}
|