From 2624c4811380c61b4382bcd2ac4780b3a4666a04 Mon Sep 17 00:00:00 2001 From: Seefs Date: Mon, 13 Oct 2025 22:25:39 +0800 Subject: [PATCH 1/4] feat: endpoint type log --- constant/context_key.go | 1 + controller/relay.go | 4 ++ relay/common/relay_info.go | 42 ++++++++++++------- relay/mjproxy_handler.go | 4 +- relay/relay_task.go | 3 ++ service/log_info_generate.go | 8 +++- .../table/usage-logs/UsageLogsColumnDefs.jsx | 40 +++++++++++++++++- 7 files changed, 83 insertions(+), 19 deletions(-) diff --git a/constant/context_key.go b/constant/context_key.go index f7640272c..87995fd6c 100644 --- a/constant/context_key.go +++ b/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" diff --git a/controller/relay.go b/controller/relay.go index e8ea1998e..a9bb16c8f 100644 --- a/controller/relay.go +++ b/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 diff --git a/relay/common/relay_info.go b/relay/common/relay_info.go index c7c73980f..5ae0f4481 100644 --- a/relay/common/relay_info.go +++ b/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) { diff --git a/relay/mjproxy_handler.go b/relay/mjproxy_handler.go index ad42dfecc..8916ab181 100644 --- a/relay/mjproxy_handler.go +++ b/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, diff --git a/relay/relay_task.go b/relay/relay_task.go index 4a30fb68b..83879c342 100644 --- a/relay/relay_task.go +++ b/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 { diff --git a/service/log_info_generate.go b/service/log_info_generate.go index 5b737692e..58b36ced0 100644 --- a/service/log_info_generate.go +++ b/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 { diff --git a/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx b/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx index 9af30226a..d41c35ccf 100644 --- a/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx +++ b/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 ( + + {meta.label} + + ); +} + 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 ( + + {renderType(text, t)} + {renderRelayFormat(relayFormat)} + + ); }, }, { From 86c63ea4a7f6befc7b1051813a62530f58e497e1 Mon Sep 17 00:00:00 2001 From: Seefs Date: Mon, 13 Oct 2025 22:44:40 +0800 Subject: [PATCH 2/4] feat: endpoint type log --- constant/context_key.go | 1 - controller/relay.go | 5 +- relay/common/relay_info.go | 4 - relay/relay_task.go | 4 +- service/log_info_generate.go | 29 ++++- .../table/usage-logs/UsageLogsColumnDefs.jsx | 109 ++++++++++++++---- 6 files changed, 113 insertions(+), 39 deletions(-) diff --git a/constant/context_key.go b/constant/context_key.go index 87995fd6c..f7640272c 100644 --- a/constant/context_key.go +++ b/constant/context_key.go @@ -8,7 +8,6 @@ const ( ContextKeyOriginalModel ContextKey = "original_model" ContextKeyRequestStartTime ContextKey = "request_start_time" - ContextKeyRelayFormat ContextKey = "relay_format" /* token related keys */ ContextKeyTokenUnlimited ContextKey = "token_unlimited_quota" diff --git a/controller/relay.go b/controller/relay.go index a9bb16c8f..4a81e3565 100644 --- a/controller/relay.go +++ b/controller/relay.go @@ -299,9 +299,8 @@ 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 + if c.Request != nil && c.Request.URL != nil { + other["request_path"] = c.Request.URL.Path } other["error_type"] = err.GetErrorType() other["error_code"] = err.GetErrorCode() diff --git a/relay/common/relay_info.go b/relay/common/relay_info.go index 5ae0f4481..02cc9d99a 100644 --- a/relay/common/relay_info.go +++ b/relay/common/relay_info.go @@ -465,10 +465,6 @@ func GenRelayInfo(c *gin.Context, relayFormat types.RelayFormat, request dto.Req return nil, errors.New("invalid relay format") } - if info != nil { - common.SetContextKey(c, constant.ContextKeyRelayFormat, string(info.RelayFormat)) - } - return info, nil } diff --git a/relay/relay_task.go b/relay/relay_task.go index 83879c342..bf20f5bbd 100644 --- a/relay/relay_task.go +++ b/relay/relay_task.go @@ -165,8 +165,8 @@ func RelayTaskSubmit(c *gin.Context, info *relaycommon.RelayInfo) (taskErr *dto. } } other := make(map[string]interface{}) - if info.RelayFormat != "" { - other["relay_format"] = string(info.RelayFormat) + if c != nil && c.Request != nil && c.Request.URL != nil { + other["request_path"] = c.Request.URL.Path } other["model_price"] = modelPrice other["group_ratio"] = groupRatio diff --git a/service/log_info_generate.go b/service/log_info_generate.go index 58b36ced0..95a88dfbc 100644 --- a/service/log_info_generate.go +++ b/service/log_info_generate.go @@ -1,6 +1,8 @@ package service import ( + "strings" + "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/constant" "github.com/QuantumNous/new-api/dto" @@ -10,12 +12,28 @@ import ( "github.com/gin-gonic/gin" ) +func appendRequestPath(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, other map[string]interface{}) { + if other == nil { + return + } + if ctx != nil && ctx.Request != nil && ctx.Request.URL != nil { + if path := ctx.Request.URL.Path; path != "" { + other["request_path"] = path + return + } + } + if relayInfo != nil && relayInfo.RequestURLPath != "" { + path := relayInfo.RequestURLPath + if idx := strings.Index(path, "?"); idx != -1 { + path = path[:idx] + } + other["request_path"] = path + } +} + 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 @@ -45,6 +63,7 @@ func GenerateTextOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, m adminInfo["multi_key_index"] = common.GetContextKeyInt(ctx, constant.ContextKeyChannelMultiKeyIndex) } other["admin_info"] = adminInfo + appendRequestPath(ctx, relayInfo, other) return other } @@ -83,13 +102,11 @@ func GenerateClaudeOtherInfo(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, 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 { other["user_group_ratio"] = priceData.GroupRatioInfo.GroupSpecialRatio } + appendRequestPath(nil, relayInfo, other) return other } diff --git a/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx b/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx index d41c35ccf..5e9ec073c 100644 --- a/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx +++ b/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx @@ -103,36 +103,98 @@ 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' }, +const endpointColorMap = { + chat: 'blue', + completions: 'blue', + messages: 'purple', + responses: 'violet', + images: 'pink', + image: 'pink', + embeddings: 'green', + embedding: 'green', + audio: 'teal', + speech: 'teal', + translations: 'teal', + transcriptions: 'teal', + rerank: 'cyan', + moderations: 'red', + models: 'orange', + engines: 'orange', + mj: 'red', + submit: 'red', + suno: 'amber', + realtime: 'indigo', + notifications: 'violet', }; -function renderRelayFormat(relayFormat) { - if (!relayFormat) { +function formatPathSegment(segment) { + if (!segment) { + return ''; + } + const normalized = segment.replace(/^:/, '').replace(/[_-]/g, ' '); + return normalized + .split(' ') + .filter(Boolean) + .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) + .join(' '); +} + +function deriveEndpointMeta(path) { + if (!path) { return null; } - const meta = relayFormatMeta[relayFormat] || { - color: 'grey', - label: relayFormat - .replace(/_/g, ' ') - .replace(/\b\w/g, (c) => c.toUpperCase()), - }; + const cleanPath = path.split('?')[0]; + const segments = cleanPath.split('/').filter(Boolean); + if (segments.length === 0) { + return null; + } + let startIndex = 0; + if (/^v\d/i.test(segments[0])) { + startIndex = 1; + } - return ( + const primary = segments[startIndex] || segments[segments.length - 1]; + const tailSegments = segments + .slice(startIndex + 1) + .filter((segment) => segment && !segment.startsWith(':')); + const secondary = tailSegments[tailSegments.length - 1]; + + const labelParts = []; + const formattedPrimary = formatPathSegment(primary); + if (formattedPrimary) { + labelParts.push(formattedPrimary); + } + const formattedSecondary = formatPathSegment(secondary); + if (formattedSecondary && formattedSecondary !== formattedPrimary) { + labelParts.push(formattedSecondary); + } + const label = labelParts.join(' · '); + + const color = + endpointColorMap[primary] || + (secondary ? endpointColorMap[secondary] : undefined) || + 'grey'; + + return { + label: label || formatPathSegment(primary), + color, + }; +} + +function renderEndpointTag(requestPath) { + const meta = deriveEndpointMeta(requestPath); + if (!meta) { + return null; + } + const tag = ( {meta.label} ); + if (requestPath) { + return {tag}; + } + return tag; } function renderIsStream(bool, t) { @@ -403,11 +465,12 @@ export const getLogsColumns = ({ title: t('类型'), dataIndex: 'type', render: (text, record, index) => { - const relayFormat = getLogOther(record.other)?.relay_format; + const other = getLogOther(record.other) || {}; + const requestPath = other.request_path; return ( {renderType(text, t)} - {renderRelayFormat(relayFormat)} + {renderEndpointTag(requestPath)} ); }, From 7d480d5ff3545370efac6582964ae9a8a8854ab6 Mon Sep 17 00:00:00 2001 From: Seefs Date: Tue, 14 Oct 2025 00:06:52 +0800 Subject: [PATCH 3/4] feat: endpoint type log --- .../table/usage-logs/UsageLogsColumnDefs.jsx | 103 +----------------- web/src/hooks/usage-logs/useUsageLogsData.jsx | 6 + web/src/i18n/locales/en.json | 1 + web/src/i18n/locales/fr.json | 3 +- web/src/i18n/locales/ru.json | 1 + web/src/i18n/locales/zh.json | 1 + 6 files changed, 12 insertions(+), 103 deletions(-) diff --git a/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx b/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx index 5e9ec073c..9af30226a 100644 --- a/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx +++ b/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx @@ -103,100 +103,6 @@ function renderType(type, t) { } } -const endpointColorMap = { - chat: 'blue', - completions: 'blue', - messages: 'purple', - responses: 'violet', - images: 'pink', - image: 'pink', - embeddings: 'green', - embedding: 'green', - audio: 'teal', - speech: 'teal', - translations: 'teal', - transcriptions: 'teal', - rerank: 'cyan', - moderations: 'red', - models: 'orange', - engines: 'orange', - mj: 'red', - submit: 'red', - suno: 'amber', - realtime: 'indigo', - notifications: 'violet', -}; - -function formatPathSegment(segment) { - if (!segment) { - return ''; - } - const normalized = segment.replace(/^:/, '').replace(/[_-]/g, ' '); - return normalized - .split(' ') - .filter(Boolean) - .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) - .join(' '); -} - -function deriveEndpointMeta(path) { - if (!path) { - return null; - } - const cleanPath = path.split('?')[0]; - const segments = cleanPath.split('/').filter(Boolean); - if (segments.length === 0) { - return null; - } - let startIndex = 0; - if (/^v\d/i.test(segments[0])) { - startIndex = 1; - } - - const primary = segments[startIndex] || segments[segments.length - 1]; - const tailSegments = segments - .slice(startIndex + 1) - .filter((segment) => segment && !segment.startsWith(':')); - const secondary = tailSegments[tailSegments.length - 1]; - - const labelParts = []; - const formattedPrimary = formatPathSegment(primary); - if (formattedPrimary) { - labelParts.push(formattedPrimary); - } - const formattedSecondary = formatPathSegment(secondary); - if (formattedSecondary && formattedSecondary !== formattedPrimary) { - labelParts.push(formattedSecondary); - } - const label = labelParts.join(' · '); - - const color = - endpointColorMap[primary] || - (secondary ? endpointColorMap[secondary] : undefined) || - 'grey'; - - return { - label: label || formatPathSegment(primary), - color, - }; -} - -function renderEndpointTag(requestPath) { - const meta = deriveEndpointMeta(requestPath); - if (!meta) { - return null; - } - const tag = ( - - {meta.label} - - ); - if (requestPath) { - return {tag}; - } - return tag; -} - function renderIsStream(bool, t) { if (bool) { return ( @@ -465,14 +371,7 @@ export const getLogsColumns = ({ title: t('类型'), dataIndex: 'type', render: (text, record, index) => { - const other = getLogOther(record.other) || {}; - const requestPath = other.request_path; - return ( - - {renderType(text, t)} - {renderEndpointTag(requestPath)} - - ); + return <>{renderType(text, t)}; }, }, { diff --git a/web/src/hooks/usage-logs/useUsageLogsData.jsx b/web/src/hooks/usage-logs/useUsageLogsData.jsx index 36684c2c5..6041d7427 100644 --- a/web/src/hooks/usage-logs/useUsageLogsData.jsx +++ b/web/src/hooks/usage-logs/useUsageLogsData.jsx @@ -468,6 +468,12 @@ export const useLogsData = () => { }); } } + if (other?.request_path) { + expandDataLocal.push({ + key: t('请求路径'), + value: other.request_path, + }); + } expandDatesLocal[logs[i].key] = expandDataLocal; } diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json index 7ec941281..db62d5f59 100644 --- a/web/src/i18n/locales/en.json +++ b/web/src/i18n/locales/en.json @@ -1675,6 +1675,7 @@ "请求失败": "Request failed", "请求头覆盖": "Request header override", "请求并计费模型": "Request and charge model", + "请求路径": "Request path", "请求时长: ${time}s": "Request time: ${time}s", "请求次数": "Number of Requests", "请求结束后多退少补": "Adjust after request completion", diff --git a/web/src/i18n/locales/fr.json b/web/src/i18n/locales/fr.json index bafe945c0..27789a191 100644 --- a/web/src/i18n/locales/fr.json +++ b/web/src/i18n/locales/fr.json @@ -1684,6 +1684,7 @@ "请求失败": "Échec de la demande", "请求头覆盖": "Remplacement des en-têtes de demande", "请求并计费模型": "Modèle de demande et de facturation", + "请求路径": "Chemin de requête", "请求时长: ${time}s": "Durée de la requête : ${time}s", "请求次数": "Nombre de demandes", "请求结束后多退少补": "Ajuster après la fin de la demande", @@ -2081,4 +2082,4 @@ "默认测试模型": "Modèle de test par défaut", "默认补全倍率": "Taux de complétion par défaut" } -} \ No newline at end of file +} diff --git a/web/src/i18n/locales/ru.json b/web/src/i18n/locales/ru.json index 7f031dccb..db0a47626 100644 --- a/web/src/i18n/locales/ru.json +++ b/web/src/i18n/locales/ru.json @@ -1693,6 +1693,7 @@ "请求失败": "Запрос не удался", "请求头覆盖": "Переопределение заголовков запроса", "请求并计费模型": "Запрос и выставление счёта модели", + "请求路径": "Путь запроса", "请求时长: ${time}s": "Время запроса: ${time}s", "请求次数": "Количество запросов", "请求结束后多退少补": "После вывода запроса возврат излишков и доплата недостатка", diff --git a/web/src/i18n/locales/zh.json b/web/src/i18n/locales/zh.json index fe085af12..62c8836be 100644 --- a/web/src/i18n/locales/zh.json +++ b/web/src/i18n/locales/zh.json @@ -1666,6 +1666,7 @@ "请求失败": "请求失败", "请求头覆盖": "请求头覆盖", "请求并计费模型": "请求并计费模型", + "请求路径": "请求路径", "请求时长: ${time}s": "请求时长: ${time}s", "请求次数": "请求次数", "请求结束后多退少补": "请求结束后多退少补", From e6c42bfbdae63a701094a0baf397b03ee0fdd612 Mon Sep 17 00:00:00 2001 From: Seefs Date: Tue, 14 Oct 2025 00:16:08 +0800 Subject: [PATCH 4/4] clean --- relay/common/relay_info.go | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/relay/common/relay_info.go b/relay/common/relay_info.go index 02cc9d99a..c7c73980f 100644 --- a/relay/common/relay_info.go +++ b/relay/common/relay_info.go @@ -426,46 +426,38 @@ 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: - info = GenRelayInfoOpenAI(c, request) + return GenRelayInfoOpenAI(c, request), nil case types.RelayFormatOpenAIAudio: - info = GenRelayInfoOpenAIAudio(c, request) + return GenRelayInfoOpenAIAudio(c, request), nil case types.RelayFormatOpenAIImage: - info = GenRelayInfoImage(c, request) + return GenRelayInfoImage(c, request), nil case types.RelayFormatOpenAIRealtime: - info = GenRelayInfoWs(c, ws) + return GenRelayInfoWs(c, ws), nil case types.RelayFormatClaude: - info = GenRelayInfoClaude(c, request) + return GenRelayInfoClaude(c, request), nil case types.RelayFormatRerank: - rerankReq, ok := request.(*dto.RerankRequest) - if !ok { - return nil, errors.New("request is not a RerankRequest") + if request, ok := request.(*dto.RerankRequest); ok { + return GenRelayInfoRerank(c, request), nil } - info = GenRelayInfoRerank(c, rerankReq) + return nil, errors.New("request is not a RerankRequest") case types.RelayFormatGemini: - info = GenRelayInfoGemini(c, request) + return GenRelayInfoGemini(c, request), nil case types.RelayFormatEmbedding: - info = GenRelayInfoEmbedding(c, request) + return GenRelayInfoEmbedding(c, request), nil case types.RelayFormatOpenAIResponses: - responsesReq, ok := request.(*dto.OpenAIResponsesRequest) - if !ok { - return nil, errors.New("request is not a OpenAIResponsesRequest") + if request, ok := request.(*dto.OpenAIResponsesRequest); ok { + return GenRelayInfoResponses(c, request), nil } - info = GenRelayInfoResponses(c, responsesReq) + return nil, errors.New("request is not a OpenAIResponsesRequest") case types.RelayFormatTask: - info = genBaseRelayInfo(c, nil) - info.RelayFormat = types.RelayFormatTask + return genBaseRelayInfo(c, nil), nil case types.RelayFormatMjProxy: - info = genBaseRelayInfo(c, nil) - info.RelayFormat = types.RelayFormatMjProxy + return genBaseRelayInfo(c, nil), nil default: return nil, errors.New("invalid relay format") } - - return info, nil } func (info *RelayInfo) SetPromptTokens(promptTokens int) {