fix: 优化同步上游模型的写回载荷,克隆并保留远端返回的所有非敏感 credentials,避免丢失 compact_model_mapping 等其它配置

This commit is contained in:
liumangmang
2026-07-02 17:02:37 +08:00
parent 4645460ff9
commit 316ef24188
2 changed files with 23 additions and 18 deletions
+9 -6
View File
@@ -1391,8 +1391,12 @@ def sync_website_accounts_upstream_models(
continue continue
# 1. 先安全修复 base_url (不依赖同步模型结果) # 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: try:
c.update_account(aid, {"credentials": {"base_url": upstream_base_url}}) c.update_account(aid, {"credentials": current_creds})
except Exception as e: except Exception as e:
items.append(SyncUpstreamModelsItem( items.append(SyncUpstreamModelsItem(
account_id=aid, account_id=aid,
@@ -1421,11 +1425,10 @@ def sync_website_accounts_upstream_models(
)) ))
continue continue
# 3. 模型同步成功后,写回 base_url 和 model_mapping # 3. 模型同步成功后,在 current_creds 基础上替换 model_mapping 并写回
c.update_account(aid, {"credentials": { updated_creds = dict(current_creds)
"base_url": upstream_base_url, updated_creds["model_mapping"] = {m: m for m in valid_models}
"model_mapping": {m: m for m in valid_models} c.update_account(aid, {"credentials": updated_creds})
}})
items.append(SyncUpstreamModelsItem( items.append(SyncUpstreamModelsItem(
account_id=aid, account_id=aid,
+12 -10
View File
@@ -145,7 +145,7 @@ def test_sync_upstream_models_workflow(db_session, monkeypatch):
def list_accounts(self): def list_accounts(self):
return [ 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": "abc", "name": "acc-abc", "credentials": {}},
{"id": 1005, "name": "acc-1005", "credentials": {"api_key": "k5"}}, {"id": 1005, "name": "acc-1005", "credentials": {"api_key": "k5"}},
{"id": 1006, "name": "acc-1006", "credentials": {"api_key": "k6"}}, {"id": 1006, "name": "acc-1006", "credentials": {"api_key": "k6"}},
@@ -191,16 +191,18 @@ def test_sync_upstream_models_workflow(db_session, monkeypatch):
# 1001 的两次 update 调用检测 # 1001 的两次 update 调用检测
calls_1001 = [call for call in update_calls if call[0] == "1001"] calls_1001 = [call for call in update_calls if call[0] == "1001"]
assert len(calls_1001) == 2 assert len(calls_1001) == 2
# 第一次安全修复:只传递 base_url # 第一次安全修复:应当在保留其他非敏感 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"]["base_url"] == "http://upstream-a"
# 第二次同步成功写入:传递 base_url + model_mapping assert calls_1001[0][1]["credentials"]["compact_model_mapping"] == {"compact": "compact"}
assert calls_1001[1][1]["credentials"] == { assert calls_1001[0][1]["credentials"]["openai_capabilities"] == "caps"
"base_url": "http://upstream-a", # 第二次同步成功写入:同样保留其他非敏感 credentials,但将 model_mapping 也更新进去
"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-3.5-turbo": "gpt-3.5-turbo",
"gpt-4": "gpt-4" "gpt-4": "gpt-4"
} }
}
# abc 跳过 # abc 跳过
item_abc = next(i for i in items if i.account_id == "abc") item_abc = next(i for i in items if i.account_id == "abc")
@@ -219,7 +221,7 @@ def test_sync_upstream_models_workflow(db_session, monkeypatch):
assert "为空" in item_1005.message assert "为空" in item_1005.message
calls_1005 = [call for call in update_calls if call[0] == "1005"] calls_1005 = [call for call in update_calls if call[0] == "1005"]
assert len(calls_1005) == 1 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) # 1006 失败 (抛错,但应当执行了第一次安全修复的 update_account)
item_1006 = next(i for i in items if i.account_id == "1006") 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 assert "Network Error" in item_1006.message
calls_1006 = [call for call in update_calls if call[0] == "1006"] calls_1006 = [call for call in update_calls if call[0] == "1006"]
assert len(calls_1006) == 1 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 且不调用同步模型) # 1007 失败 (上游 base_url 为空,不应当调用 update_account 且不调用同步模型)
item_1007 = next(i for i in items if i.account_id == "1007") item_1007 = next(i for i in items if i.account_id == "1007")