fix(media): repair JSON_CONTAINS auto-routing + reconcile stale backend tests
CI / gate (push) Has been cancelled
CI / gate (push) Has been cancelled
Real bug:
- capability_registry.resolve_auto_model and chat_media._build_media_route used
`Column.op("JSON_CONTAINS")(col, val)`, but SQLAlchemy's op() accepts only ONE
argument -> TypeError on every image/video/audio auto-route, silently failing
media generation (caught as "后台生成异常"). Replaced with func.json_contains().
Test reconciliation (no production behavior change):
- tests/test_context_engine.py: tiktoken upgrade made the hardcoded len//2 token
estimates wrong; relax to tokenizer-agnostic assertions and add
structured_memory=None to the _Summary mock (code now branches on it).
- tests/test_regression_r1r2r3.py: R3 FakeModel lacked `name` (code reads m.name);
also the assertion assumed a literal '超时' string, but the failover architecture
catches model-level exceptions and writes a user-understandable error marker
instead. Align the assertion to the real contract: a media failure/timeout must
be written back as a user-understandable error message, never left as '生成中…'.
CI gate: 28 backend pytest + 15 frontend vitest all green.
This commit is contained in:
1 parent
a08ec87b22
commit
d3d8d62b94
4 files changed
+22
-17
No files matched your search
@@ -16,6 +16,7 @@ class _Msg:
|
||||
class _Summary:
|
||||
def __init__(self, text):
|
||||
self.summary_text = text
|
||||
self.structured_memory = None
|
||||
|
||||
|
||||
class _Query:
|
||||
@@ -59,10 +60,10 @@ def _newest_first(msgs):
|
||||
def test_estimate_tokens():
|
||||
assert _estimate_tokens("") == 0
|
||||
assert _estimate_tokens(None) == 0
|
||||
assert _estimate_tokens("abcd") == 2 # 4//2
|
||||
assert _estimate_tokens("a" * 5) == 2 # max(1, 5//2)=2
|
||||
# just ensure positive monotonic
|
||||
assert _estimate_tokens("x" * 100) == 50
|
||||
# 真实估算器(tiktoken 优先, 回退 2 字符/token): 只校验 sane + 单调, 不绑定具体 tokenizer
|
||||
assert _estimate_tokens("a") >= 1
|
||||
assert _estimate_tokens("a" * 100) > _estimate_tokens("a" * 10)
|
||||
assert _estimate_tokens("x" * 1000) >= _estimate_tokens("x" * 100)
|
||||
|
||||
|
||||
def test_history_excludes_latest_user():
|
||||
@@ -95,14 +96,14 @@ def test_summary_injected_as_system_first():
|
||||
|
||||
|
||||
def test_budget_truncation():
|
||||
# 5 assistant messages each ~200 tokens; budget small -> truncated
|
||||
# 预算远小于 5 条消息总量 -> 必须触发截断(与 tokenizer 实现无关)
|
||||
msgs = _newest_first([_Msg("assistant", "x" * 400) for _ in range(5)])
|
||||
db = _DB(msgs)
|
||||
out = _build_chat_history(db, "c1", max_tokens=500, exclude_latest_user=False)
|
||||
# each msg ~200 tokens; budget 500 -> keep newest ~2
|
||||
assert len(out) <= 3
|
||||
out = _build_chat_history(db, "c1", max_tokens=150, exclude_latest_user=False)
|
||||
assert len(out) < 5, "预算应触发截断"
|
||||
total = sum(_estimate_tokens(m["content"]) for m in out)
|
||||
assert total <= 500 + 200 # within budget (+1 msg slack)
|
||||
one_msg = _estimate_tokens("x" * 400)
|
||||
assert total <= 150 + one_msg, "不超过预算 + 一条余量"
|
||||
|
||||
|
||||
def test_no_summary_when_absent():
|
||||
|
||||
Reference in new issue
Block a user