Просмотр исходного кода

feat: 记录流模式首字时间 (close #323)

CalciumIon 1 год назад
Родитель
Сommit
79010dbfc5

+ 1 - 1
relay/channel/ollama/adaptor.go

@@ -52,7 +52,7 @@ func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, request
 func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage *dto.Usage, err *dto.OpenAIErrorWithStatusCode) {
 	if info.IsStream {
 		var responseText string
-		err, responseText, _ = openai.OpenaiStreamHandler(c, resp, info.RelayMode)
+		err, responseText, _ = openai.OpenaiStreamHandler(c, resp, info)
 		usage, _ = service.ResponseText2Usage(responseText, info.UpstreamModelName, info.PromptTokens)
 	} else {
 		if info.RelayMode == relayconstant.RelayModeEmbeddings {

+ 1 - 1
relay/channel/openai/adaptor.go

@@ -82,7 +82,7 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycom
 	if info.IsStream {
 		var responseText string
 		var toolCount int
-		err, responseText, toolCount = OpenaiStreamHandler(c, resp, info.RelayMode)
+		err, responseText, toolCount = OpenaiStreamHandler(c, resp, info)
 		usage, _ = service.ResponseText2Usage(responseText, info.UpstreamModelName, info.PromptTokens)
 		usage.CompletionTokens += toolCount * 7
 	} else {

+ 8 - 2
relay/channel/openai/relay-openai.go

@@ -9,6 +9,7 @@ import (
 	"net/http"
 	"one-api/common"
 	"one-api/dto"
+	relaycommon "one-api/relay/common"
 	relayconstant "one-api/relay/constant"
 	"one-api/service"
 	"strings"
@@ -16,7 +17,7 @@ import (
 	"time"
 )
 
-func OpenaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*dto.OpenAIErrorWithStatusCode, string, int) {
+func OpenaiStreamHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (*dto.OpenAIErrorWithStatusCode, string, int) {
 	//checkSensitive := constant.ShouldCheckCompletionSensitive()
 	var responseTextBuilder strings.Builder
 	toolCount := 0
@@ -57,7 +58,7 @@ func OpenaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*d
 			}
 		}
 		streamResp := "[" + strings.Join(streamItems, ",") + "]"
-		switch relayMode {
+		switch info.RelayMode {
 		case relayconstant.RelayModeChatCompletions:
 			var streamResponses []dto.ChatCompletionsStreamResponseSimple
 			err := json.Unmarshal(common.StringToByteSlice(streamResp), &streamResponses)
@@ -126,9 +127,14 @@ func OpenaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*d
 		common.SafeSendBool(stopChan, true)
 	}()
 	service.SetEventStreamHeaders(c)
+	isFirst := true
 	c.Stream(func(w io.Writer) bool {
 		select {
 		case data := <-dataChan:
+			if isFirst {
+				isFirst = false
+				info.FirstResponseTime = time.Now()
+			}
 			if strings.HasPrefix(data, "data: [DONE]") {
 				data = data[:12]
 			}

+ 1 - 1
relay/channel/perplexity/adaptor.go

@@ -46,7 +46,7 @@ func (a *Adaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, request
 func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (usage *dto.Usage, err *dto.OpenAIErrorWithStatusCode) {
 	if info.IsStream {
 		var responseText string
-		err, responseText, _ = openai.OpenaiStreamHandler(c, resp, info.RelayMode)
+		err, responseText, _ = openai.OpenaiStreamHandler(c, resp, info)
 		usage, _ = service.ResponseText2Usage(responseText, info.UpstreamModelName, info.PromptTokens)
 	} else {
 		err, usage = openai.OpenaiHandler(c, resp, info.PromptTokens, info.UpstreamModelName)

+ 1 - 1
relay/channel/zhipu_4v/adaptor.go

@@ -48,7 +48,7 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycom
 	if info.IsStream {
 		var responseText string
 		var toolCount int
-		err, responseText, toolCount = openai.OpenaiStreamHandler(c, resp, info.RelayMode)
+		err, responseText, toolCount = openai.OpenaiStreamHandler(c, resp, info)
 		usage, _ = service.ResponseText2Usage(responseText, info.UpstreamModelName, info.PromptTokens)
 		usage.CompletionTokens += toolCount * 7
 	} else {

+ 1 - 0
relay/common/relay_info.go

@@ -16,6 +16,7 @@ type RelayInfo struct {
 	Group             string
 	TokenUnlimited    bool
 	StartTime         time.Time
+	FirstResponseTime time.Time
 	ApiType           int
 	IsStream          bool
 	RelayMode         int

+ 1 - 8
relay/relay-text.go

@@ -332,14 +332,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, textRe
 		logModel = "gpt-4-gizmo-*"
 		logContent += fmt.Sprintf(",模型 %s", textRequest.Model)
 	}
-	other := make(map[string]interface{})
-	other["model_ratio"] = modelRatio
-	other["group_ratio"] = groupRatio
-	other["completion_ratio"] = completionRatio
-	other["model_price"] = modelPrice
-	adminInfo := make(map[string]interface{})
-	adminInfo["use_channel"] = ctx.GetStringSlice("use_channel")
-	other["admin_info"] = adminInfo
+	other := service.GenerateTextOtherInfo(ctx, relayInfo, modelRatio, groupRatio, completionRatio, modelPrice)
 	model.RecordConsumeLog(ctx, relayInfo.UserId, relayInfo.ChannelId, promptTokens, completionTokens, logModel, tokenName, quota, logContent, relayInfo.TokenId, userQuota, int(useTimeSeconds), relayInfo.IsStream, other)
 
 	//if quota != 0 {

+ 19 - 0
service/log.go

@@ -0,0 +1,19 @@
+package service
+
+import (
+	"github.com/gin-gonic/gin"
+	relaycommon "one-api/relay/common"
+)
+
+func GenerateTextOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, modelRatio, groupRatio, completionRatio, modelPrice float64) map[string]interface{} {
+	other := make(map[string]interface{})
+	other["model_ratio"] = modelRatio
+	other["group_ratio"] = groupRatio
+	other["completion_ratio"] = completionRatio
+	other["model_price"] = modelPrice
+	other["frt"] = float64(relayInfo.FirstResponseTime.UnixMilli() - relayInfo.StartTime.UnixMilli())
+	adminInfo := make(map[string]interface{})
+	adminInfo["use_channel"] = ctx.GetStringSlice("use_channel")
+	other["admin_info"] = adminInfo
+	return other
+}

+ 51 - 13
web/src/components/LogsTable.js

@@ -29,6 +29,7 @@ import {
   stringToColor,
 } from '../helpers/render';
 import Paragraph from '@douyinfe/semi-ui/lib/es/typography/paragraph';
+import {getLogOther} from "../helpers/other.js";
 
 const { Header } = Layout;
 
@@ -141,6 +142,33 @@ function renderUseTime(type) {
   }
 }
 
+function renderFirstUseTime(type) {
+  let time = parseFloat(type) / 1000.0;
+  time = time.toFixed(1)
+  if (time < 3) {
+    return (
+        <Tag color='green' size='large'>
+          {' '}
+          {time} s{' '}
+        </Tag>
+    );
+  } else if (time < 10) {
+    return (
+        <Tag color='orange' size='large'>
+          {' '}
+          {time} s{' '}
+        </Tag>
+    );
+  } else {
+    return (
+        <Tag color='red' size='large'>
+          {' '}
+          {time} s{' '}
+        </Tag>
+    );
+  }
+}
+
 const LogsTable = () => {
   const columns = [
     {
@@ -247,17 +275,30 @@ const LogsTable = () => {
       },
     },
     {
-      title: '用时',
+      title: '用时/首字',
       dataIndex: 'use_time',
       render: (text, record, index) => {
-        return (
-          <div>
-            <Space>
-              {renderUseTime(text)}
-              {renderIsStream(record.is_stream)}
-            </Space>
-          </div>
-        );
+        if (record.is_stream) {
+          let other = getLogOther(record.other);
+          return (
+              <div>
+                <Space>
+                  {renderUseTime(text)}
+                  {renderFirstUseTime(other.frt)}
+                  {renderIsStream(record.is_stream)}
+                </Space>
+              </div>
+          );
+        } else {
+          return (
+              <div>
+                <Space>
+                  {renderUseTime(text)}
+                  {renderIsStream(record.is_stream)}
+                </Space>
+              </div>
+          );
+        }
       },
     },
     {
@@ -325,10 +366,7 @@ const LogsTable = () => {
       title: '详情',
       dataIndex: 'content',
       render: (text, record, index) => {
-        if (record.other === '') {
-          record.other = '{}'
-        }
-        let other = JSON.parse(record.other);
+        let other = getLogOther(record.other);
         if (other == null) {
           return (
             <Paragraph

+ 7 - 0
web/src/helpers/other.js

@@ -0,0 +1,7 @@
+export function getLogOther(otherStr) {
+    if (otherStr === undefined || otherStr === '') {
+        otherStr = '{}'
+    }
+    let other = JSON.parse(otherStr)
+    return other
+}