From 316ef2418866cbb44ff3d753bceeb4e97c7f724d Mon Sep 17 00:00:00 2001 From: liumangmang Date: Thu, 2 Jul 2026 17:02:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E4=B8=8A=E6=B8=B8=E6=A8=A1=E5=9E=8B=E7=9A=84=E5=86=99=E5=9B=9E?= =?UTF-8?q?=E8=BD=BD=E8=8D=B7=EF=BC=8C=E5=85=8B=E9=9A=86=E5=B9=B6=E4=BF=9D?= =?UTF-8?q?=E7=95=99=E8=BF=9C=E7=AB=AF=E8=BF=94=E5=9B=9E=E7=9A=84=E6=89=80?= =?UTF-8?q?=E6=9C=89=E9=9D=9E=E6=95=8F=E6=84=9F=20credentials=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E4=B8=A2=E5=A4=B1=20compact=5Fmodel=5Fmappin?= =?UTF-8?q?g=20=E7=AD=89=E5=85=B6=E5=AE=83=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/routers/websites.py | 15 +++++++++------ backend/test_sync_upstream_models.py | 26 ++++++++++++++------------ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/backend/app/routers/websites.py b/backend/app/routers/websites.py index b539193..b6981d2 100644 --- a/backend/app/routers/websites.py +++ b/backend/app/routers/websites.py @@ -1391,8 +1391,12 @@ def sync_website_accounts_upstream_models( continue # 1. 先安全修复 base_url (不依赖同步模型结果) + # 在 remote_acc.get("credentials") 基础上进行修改,保留其他非敏感 credentials (例如 compact_model_mapping) + current_creds = dict(remote_acc.get("credentials") or {}) + current_creds["base_url"] = upstream_base_url + try: - c.update_account(aid, {"credentials": {"base_url": upstream_base_url}}) + c.update_account(aid, {"credentials": current_creds}) except Exception as e: items.append(SyncUpstreamModelsItem( account_id=aid, @@ -1421,11 +1425,10 @@ def sync_website_accounts_upstream_models( )) continue - # 3. 模型同步成功后,写回 base_url 和 model_mapping - c.update_account(aid, {"credentials": { - "base_url": upstream_base_url, - "model_mapping": {m: m for m in valid_models} - }}) + # 3. 模型同步成功后,在 current_creds 基础上替换 model_mapping 并写回 + updated_creds = dict(current_creds) + updated_creds["model_mapping"] = {m: m for m in valid_models} + c.update_account(aid, {"credentials": updated_creds}) items.append(SyncUpstreamModelsItem( account_id=aid, diff --git a/backend/test_sync_upstream_models.py b/backend/test_sync_upstream_models.py index 4de9377..7230a23 100644 --- a/backend/test_sync_upstream_models.py +++ b/backend/test_sync_upstream_models.py @@ -145,7 +145,7 @@ def test_sync_upstream_models_workflow(db_session, monkeypatch): def list_accounts(self): return [ - {"id": 1001, "name": "acc-1001", "credentials": {"api_key": "k1", "model_mapping": {"old": "old"}, "base_url": "http://default-base-url"}}, + {"id": 1001, "name": "acc-1001", "credentials": {"api_key": "k1", "model_mapping": {"old": "old"}, "base_url": "http://default-base-url", "compact_model_mapping": {"compact": "compact"}, "openai_capabilities": "caps"}}, {"id": "abc", "name": "acc-abc", "credentials": {}}, {"id": 1005, "name": "acc-1005", "credentials": {"api_key": "k5"}}, {"id": 1006, "name": "acc-1006", "credentials": {"api_key": "k6"}}, @@ -191,15 +191,17 @@ def test_sync_upstream_models_workflow(db_session, monkeypatch): # 1001 的两次 update 调用检测 calls_1001 = [call for call in update_calls if call[0] == "1001"] assert len(calls_1001) == 2 - # 第一次安全修复:只传递 base_url - assert calls_1001[0][1]["credentials"] == {"base_url": "http://upstream-a"} - # 第二次同步成功写入:传递 base_url + model_mapping - assert calls_1001[1][1]["credentials"] == { - "base_url": "http://upstream-a", - "model_mapping": { - "gpt-3.5-turbo": "gpt-3.5-turbo", - "gpt-4": "gpt-4" - } + # 第一次安全修复:应当在保留其他非敏感 credentials (如 compact_model_mapping) 的基础上,只将 base_url 变更为 http://upstream-a + assert calls_1001[0][1]["credentials"]["base_url"] == "http://upstream-a" + assert calls_1001[0][1]["credentials"]["compact_model_mapping"] == {"compact": "compact"} + assert calls_1001[0][1]["credentials"]["openai_capabilities"] == "caps" + # 第二次同步成功写入:同样保留其他非敏感 credentials,但将 model_mapping 也更新进去 + assert calls_1001[1][1]["credentials"]["base_url"] == "http://upstream-a" + assert calls_1001[1][1]["credentials"]["compact_model_mapping"] == {"compact": "compact"} + assert calls_1001[1][1]["credentials"]["openai_capabilities"] == "caps" + assert calls_1001[1][1]["credentials"]["model_mapping"] == { + "gpt-3.5-turbo": "gpt-3.5-turbo", + "gpt-4": "gpt-4" } # abc 跳过 @@ -219,7 +221,7 @@ def test_sync_upstream_models_workflow(db_session, monkeypatch): assert "为空" in item_1005.message calls_1005 = [call for call in update_calls if call[0] == "1005"] assert len(calls_1005) == 1 - assert calls_1005[0][1]["credentials"] == {"base_url": "http://upstream-a"} + assert calls_1005[0][1]["credentials"]["base_url"] == "http://upstream-a" # 1006 失败 (抛错,但应当执行了第一次安全修复的 update_account) item_1006 = next(i for i in items if i.account_id == "1006") @@ -228,7 +230,7 @@ def test_sync_upstream_models_workflow(db_session, monkeypatch): assert "Network Error" in item_1006.message calls_1006 = [call for call in update_calls if call[0] == "1006"] assert len(calls_1006) == 1 - assert calls_1006[0][1]["credentials"] == {"base_url": "http://upstream-a"} + assert calls_1006[0][1]["credentials"]["base_url"] == "http://upstream-a" # 1007 失败 (上游 base_url 为空,不应当调用 update_account 且不调用同步模型) item_1007 = next(i for i in items if i.account_id == "1007")