feat(server): add workbench API, DSH planner worker and RAG pipeline

This commit is contained in:
yi
2026-09-16 19:06:20 +08:00
parent 72fc5b47c7
commit d4b5b3f43a
122 changed files with 31906 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
"""多 Provider failover 单元测试(mock 数据,不依赖网络)。"""
from types import SimpleNamespace
from unittest.mock import patch
from app.failover import (FAILOVER_KINDS, failover_candidates, failover_target,
should_failover)
def _provider(pid, name, models, default_model="", enabled=True):
return SimpleNamespace(id=pid, name=name, models=list(models),
default_model=default_model or (models[0] if models else ""),
enabled=enabled)
def _session(providers):
return SimpleNamespace(exec=lambda *a, **k: SimpleNamespace(all=lambda: providers))
def test_should_failover_kinds():
assert should_failover("auth")
assert should_failover("rate_limit")
assert should_failover("connection")
assert should_failover("model_not_found")
assert not should_failover("other")
assert not should_failover("rejected")
def test_candidates_excludes_current_and_disabled():
providers = [
_provider(1, "主", ["m1"]),
_provider(2, "备一", ["m1"]),
_provider(3, "备二", ["m2"], enabled=False),
]
session = _session(providers)
ids = [p.id for p in failover_candidates(session, 1)]
assert ids == [2]
def test_target_prefers_same_model():
providers = [
_provider(1, "主", ["deepseek-chat"]),
_provider(2, "备一", ["deepseek-chat", "mimo"], default_model="mimo"),
_provider(3, "备二", ["glm-4"], default_model="glm-4"),
]
session = _session(providers)
target = failover_target(session, 1, "deepseek-chat")
assert target is not None
assert target[0].id == 2 and target[1] == "deepseek-chat"
def test_target_falls_back_to_default_model():
providers = [
_provider(1, "主", ["deepseek-chat"]),
_provider(2, "备一", ["glm-4"], default_model="glm-4"),
]
session = _session(providers)
target = failover_target(session, 1, "deepseek-chat")
assert target is not None
assert target[0].id == 2 and target[1] == "glm-4"
def test_target_none_when_no_alternatives():
providers = [_provider(1, "主", ["deepseek-chat"])]
session = _session(providers)
assert failover_target(session, 1, "deepseek-chat") is None