From 83fbaba76836b8bf64fed992c8d4d5f7f8650c6d Mon Sep 17 00:00:00 2001 From: t0ng7u Date: Thu, 25 Dec 2025 23:01:09 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20fix(model-sync):=20avoid=20unnec?= =?UTF-8?q?essary=20upstream=20fetch=20while=20keeping=20overwrite=20updat?= =?UTF-8?q?es=20working?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Only short-circuit when there are no missing models AND no overwrite fields requested - Preserve overwrite behavior even when the missing-model list is empty - Always return empty arrays (not null) for list fields to keep API responses stable - Clarify SyncUpstreamModels behavior in comments (create missing models + optional overwrite updates) --- controller/model_sync.go | 32 ++++++++++++++++++++++++++++---- service/convert.go | 2 +- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/controller/model_sync.go b/controller/model_sync.go index 38eace06e..b2ac99da8 100644 --- a/controller/model_sync.go +++ b/controller/model_sync.go @@ -249,7 +249,9 @@ func ensureVendorID(vendorName string, vendorByName map[string]upstreamVendor, v return 0 } -// SyncUpstreamModels 同步上游模型与供应商,仅对「未配置模型」生效 +// SyncUpstreamModels 同步上游模型与供应商: +// - 默认仅创建「未配置模型」 +// - 可通过 overwrite 选择性覆盖更新本地已有模型的字段(前提:sync_official <> 0) func SyncUpstreamModels(c *gin.Context) { var req syncRequest // 允许空体 @@ -261,6 +263,28 @@ func SyncUpstreamModels(c *gin.Context) { return } + // 若既无缺失模型需要创建,也未指定覆盖更新字段,则无需请求上游数据,直接返回 + if len(missing) == 0 && len(req.Overwrite) == 0 { + modelsURL, vendorsURL := getUpstreamURLs(req.Locale) + c.JSON(http.StatusOK, gin.H{ + "success": true, + "data": gin.H{ + "created_models": 0, + "created_vendors": 0, + "updated_models": 0, + "skipped_models": []string{}, + "created_list": []string{}, + "updated_list": []string{}, + "source": gin.H{ + "locale": req.Locale, + "models_url": modelsURL, + "vendors_url": vendorsURL, + }, + }, + }) + return + } + // 2) 拉取上游 vendors 与 models timeoutSec := common.GetEnvOrDefault("SYNC_HTTP_TIMEOUT_SECONDS", 15) ctx, cancel := context.WithTimeout(c.Request.Context(), time.Duration(timeoutSec)*time.Second) @@ -307,9 +331,9 @@ func SyncUpstreamModels(c *gin.Context) { createdModels := 0 createdVendors := 0 updatedModels := 0 - var skipped []string - var createdList []string - var updatedList []string + skipped := make([]string, 0) + createdList := make([]string, 0) + updatedList := make([]string, 0) // 本地缓存:vendorName -> id vendorIDCache := make(map[string]int) diff --git a/service/convert.go b/service/convert.go index 7549b569d..7228db9a9 100644 --- a/service/convert.go +++ b/service/convert.go @@ -401,7 +401,7 @@ func StreamResponseOpenAI2Claude(openAIResponse *dto.ChatCompletionsStreamRespon }, }) } - + if len(toolCall.Function.Arguments) > 0 { claudeResponses = append(claudeResponses, &dto.ClaudeResponse{ Index: &idx,