فهرست منبع

feat: endpoint type log

Seefs 4 ماه پیش
والد
کامیت
2624c48113

+ 1 - 0
constant/context_key.go

@@ -8,6 +8,7 @@ const (
 
 	ContextKeyOriginalModel    ContextKey = "original_model"
 	ContextKeyRequestStartTime ContextKey = "request_start_time"
+	ContextKeyRelayFormat      ContextKey = "relay_format"
 
 	/* token related keys */
 	ContextKeyTokenUnlimited         ContextKey = "token_unlimited_quota"

+ 4 - 0
controller/relay.go

@@ -299,6 +299,10 @@ func processChannelError(c *gin.Context, channelError types.ChannelError, err *t
 		userGroup := c.GetString("group")
 		channelId := c.GetInt("channel_id")
 		other := make(map[string]interface{})
+		relayFormat := common.GetContextKeyString(c, constant.ContextKeyRelayFormat)
+		if relayFormat != "" {
+			other["relay_format"] = relayFormat
+		}
 		other["error_type"] = err.GetErrorType()
 		other["error_code"] = err.GetErrorCode()
 		other["status_code"] = err.StatusCode

+ 27 - 15
relay/common/relay_info.go

@@ -426,38 +426,50 @@ func genBaseRelayInfo(c *gin.Context, request dto.Request) *RelayInfo {
 }
 
 func GenRelayInfo(c *gin.Context, relayFormat types.RelayFormat, request dto.Request, ws *websocket.Conn) (*RelayInfo, error) {
+	var info *RelayInfo
+
 	switch relayFormat {
 	case types.RelayFormatOpenAI:
-		return GenRelayInfoOpenAI(c, request), nil
+		info = GenRelayInfoOpenAI(c, request)
 	case types.RelayFormatOpenAIAudio:
-		return GenRelayInfoOpenAIAudio(c, request), nil
+		info = GenRelayInfoOpenAIAudio(c, request)
 	case types.RelayFormatOpenAIImage:
-		return GenRelayInfoImage(c, request), nil
+		info = GenRelayInfoImage(c, request)
 	case types.RelayFormatOpenAIRealtime:
-		return GenRelayInfoWs(c, ws), nil
+		info = GenRelayInfoWs(c, ws)
 	case types.RelayFormatClaude:
-		return GenRelayInfoClaude(c, request), nil
+		info = GenRelayInfoClaude(c, request)
 	case types.RelayFormatRerank:
-		if request, ok := request.(*dto.RerankRequest); ok {
-			return GenRelayInfoRerank(c, request), nil
+		rerankReq, ok := request.(*dto.RerankRequest)
+		if !ok {
+			return nil, errors.New("request is not a RerankRequest")
 		}
-		return nil, errors.New("request is not a RerankRequest")
+		info = GenRelayInfoRerank(c, rerankReq)
 	case types.RelayFormatGemini:
-		return GenRelayInfoGemini(c, request), nil
+		info = GenRelayInfoGemini(c, request)
 	case types.RelayFormatEmbedding:
-		return GenRelayInfoEmbedding(c, request), nil
+		info = GenRelayInfoEmbedding(c, request)
 	case types.RelayFormatOpenAIResponses:
-		if request, ok := request.(*dto.OpenAIResponsesRequest); ok {
-			return GenRelayInfoResponses(c, request), nil
+		responsesReq, ok := request.(*dto.OpenAIResponsesRequest)
+		if !ok {
+			return nil, errors.New("request is not a OpenAIResponsesRequest")
 		}
-		return nil, errors.New("request is not a OpenAIResponsesRequest")
+		info = GenRelayInfoResponses(c, responsesReq)
 	case types.RelayFormatTask:
-		return genBaseRelayInfo(c, nil), nil
+		info = genBaseRelayInfo(c, nil)
+		info.RelayFormat = types.RelayFormatTask
 	case types.RelayFormatMjProxy:
-		return genBaseRelayInfo(c, nil), nil
+		info = genBaseRelayInfo(c, nil)
+		info.RelayFormat = types.RelayFormatMjProxy
 	default:
 		return nil, errors.New("invalid relay format")
 	}
+
+	if info != nil {
+		common.SetContextKey(c, constant.ContextKeyRelayFormat, string(info.RelayFormat))
+	}
+
+	return info, nil
 }
 
 func (info *RelayInfo) SetPromptTokens(promptTokens int) {

+ 2 - 2
relay/mjproxy_handler.go

@@ -218,7 +218,7 @@ func RelaySwapFace(c *gin.Context, info *relaycommon.RelayInfo) *dto.MidjourneyR
 
 			tokenName := c.GetString("token_name")
 			logContent := fmt.Sprintf("模型固定价格 %.2f,分组倍率 %.2f,操作 %s", priceData.ModelPrice, priceData.GroupRatioInfo.GroupRatio, constant.MjActionSwapFace)
-			other := service.GenerateMjOtherInfo(priceData)
+			other := service.GenerateMjOtherInfo(info, priceData)
 			model.RecordConsumeLog(c, info.UserId, model.RecordConsumeLogParams{
 				ChannelId: info.ChannelId,
 				ModelName: modelName,
@@ -518,7 +518,7 @@ func RelayMidjourneySubmit(c *gin.Context, relayInfo *relaycommon.RelayInfo) *dt
 			}
 			tokenName := c.GetString("token_name")
 			logContent := fmt.Sprintf("模型固定价格 %.2f,分组倍率 %.2f,操作 %s,ID %s", priceData.ModelPrice, priceData.GroupRatioInfo.GroupRatio, midjRequest.Action, midjResponse.Result)
-			other := service.GenerateMjOtherInfo(priceData)
+			other := service.GenerateMjOtherInfo(relayInfo, priceData)
 			model.RecordConsumeLog(c, relayInfo.UserId, model.RecordConsumeLogParams{
 				ChannelId: relayInfo.ChannelId,
 				ModelName: modelName,

+ 3 - 0
relay/relay_task.go

@@ -165,6 +165,9 @@ func RelayTaskSubmit(c *gin.Context, info *relaycommon.RelayInfo) (taskErr *dto.
 					}
 				}
 				other := make(map[string]interface{})
+				if info.RelayFormat != "" {
+					other["relay_format"] = string(info.RelayFormat)
+				}
 				other["model_price"] = modelPrice
 				other["group_ratio"] = groupRatio
 				if hasUserGroupRatio {

+ 7 - 1
service/log_info_generate.go

@@ -13,6 +13,9 @@ import (
 func GenerateTextOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, modelRatio, groupRatio, completionRatio float64,
 	cacheTokens int, cacheRatio float64, modelPrice float64, userGroupRatio float64) map[string]interface{} {
 	other := make(map[string]interface{})
+	if relayInfo != nil && relayInfo.RelayFormat != "" {
+		other["relay_format"] = string(relayInfo.RelayFormat)
+	}
 	other["model_ratio"] = modelRatio
 	other["group_ratio"] = groupRatio
 	other["completion_ratio"] = completionRatio
@@ -78,8 +81,11 @@ func GenerateClaudeOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo,
 	return info
 }
 
-func GenerateMjOtherInfo(priceData types.PerCallPriceData) map[string]interface{} {
+func GenerateMjOtherInfo(relayInfo *relaycommon.RelayInfo, priceData types.PerCallPriceData) map[string]interface{} {
 	other := make(map[string]interface{})
+	if relayInfo != nil && relayInfo.RelayFormat != "" {
+		other["relay_format"] = string(relayInfo.RelayFormat)
+	}
 	other["model_price"] = priceData.ModelPrice
 	other["group_ratio"] = priceData.GroupRatioInfo.GroupRatio
 	if priceData.GroupRatioInfo.HasSpecialRatio {

+ 39 - 1
web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx

@@ -103,6 +103,38 @@ function renderType(type, t) {
   }
 }
 
+const relayFormatMeta = {
+  openai: { color: 'blue', label: 'OpenAI' },
+  claude: { color: 'purple', label: 'Claude' },
+  gemini: { color: 'orange', label: 'Gemini' },
+  openai_responses: { color: 'violet', label: 'Responses' },
+  openai_audio: { color: 'teal', label: 'Audio' },
+  openai_image: { color: 'pink', label: 'Image' },
+  openai_realtime: { color: 'indigo', label: 'Realtime' },
+  rerank: { color: 'cyan', label: 'Rerank' },
+  embedding: { color: 'green', label: 'Embedding' },
+  task: { color: 'amber', label: 'Task' },
+  mj_proxy: { color: 'red', label: 'Midjourney' },
+};
+
+function renderRelayFormat(relayFormat) {
+  if (!relayFormat) {
+    return null;
+  }
+  const meta = relayFormatMeta[relayFormat] || {
+    color: 'grey',
+    label: relayFormat
+      .replace(/_/g, ' ')
+      .replace(/\b\w/g, (c) => c.toUpperCase()),
+  };
+
+  return (
+    <Tag color={meta.color} type='light' shape='circle' size='small'>
+      {meta.label}
+    </Tag>
+  );
+}
+
 function renderIsStream(bool, t) {
   if (bool) {
     return (
@@ -371,7 +403,13 @@ export const getLogsColumns = ({
       title: t('类型'),
       dataIndex: 'type',
       render: (text, record, index) => {
-        return <>{renderType(text, t)}</>;
+        const relayFormat = getLogOther(record.other)?.relay_format;
+        return (
+          <Space size='small' wrap>
+            {renderType(text, t)}
+            {renderRelayFormat(relayFormat)}
+          </Space>
+        );
       },
     },
     {