反方审稿、审批质询、门控模型的接入不存在和已停用两种都钉住;自动修复后只剩接入问题时交给助手的说明有测试

自动修复之后门禁不再拦、只剩点名接入的问题时,不说「已没有阻止发布的错误」,说清助手处理不了、去哪里改;
没有接入问题时说法照旧。
This commit is contained in:
ThearchyHelios
2026-10-06 13:09:57 +08:00
parent 0230dde9ea
commit a722d9b9cf
2 changed files with 29 additions and 10 deletions
+16
View File
@@ -275,6 +275,22 @@ async def test_publish_check_reads_the_unsaved_canvas_and_autofix_keeps_the_prob
assert provider_issues(r.json()) == [] and r.json()["ok"] is True
async def test_handing_only_a_provider_problem_to_the_assistant_says_it_cannot_help(client):
"""修复之后门禁不再拦、只剩点名接入的问题:不说「已没有阻止发布的错误」,说清助手处理不了、该去哪里改。"""
from app.api.workflows import PROVIDER_LEFT
wf = await _workflow(writer(None))
r = await client.post(f"/api/workflows/{wf}/autofix", json={"level": "published", "graph": writer(GONE),
"assist": True})
out = r.json()
assert out["assist"] == {"ok": False, "summary": PROVIDER_LEFT, "questions": []}
assert out["ok"] is False and [i["code"] for i in provider_issues({"issues": out["remaining"]})] == [
"provider.missing"]
r = await client.post(f"/api/workflows/{wf}/autofix", json={"level": "published", "graph": writer(LIVE),
"assist": True})
assert r.json()["assist"]["summary"] == "修复后已没有阻止发布的错误,未再交给助手" and r.json()["ok"] is True
async def test_publishing_a_clean_graph_is_unaffected(client):
wf = await _workflow(writer(LIVE))
r = await client.post(f"/api/workflows/{wf}/publish", json={"level": "published"})
+13 -10
View File
@@ -281,9 +281,10 @@ def report_graph(source: str, *between) -> dict:
)
async def test_challenge_with_a_broken_verify_provider_reviews_no_claim_and_says_why(monkeypatch, sales):
@pytest.mark.parametrize("ref", [MISSING, DISABLED])
async def test_challenge_with_a_broken_verify_provider_reviews_no_claim_and_says_why(monkeypatch, sales, ref):
called = script(monkeypatch, writer=TEXT)
await put_setting("verify", {"provider": MISSING})
await put_setting("verify", {"provider": ref})
run = await start(report_graph(sales, node("chal", "challenge", "审稿", report="write")), run_class="formal")
assert run.status == "succeeded", run.error
evs = await events(run.id)
@@ -291,17 +292,18 @@ async def test_challenge_with_a_broken_verify_provider_reviews_no_claim_and_says
assert out["counts"]["inconclusive"] == out["unreviewed"] == 2
assert out["counts"]["refuted"] == out["counts"]["stands"] == 0
[said] = logs(evs, "challenge_unreviewed")
assert said["reason"].startswith("核查模型不可用") and REASONS[MISSING] in said["reason"], said["reason"]
assert said["reason"].startswith("核查模型不可用") and REASONS[ref] in said["reason"], said["reason"]
record = artifact_store.load(out["challenge_artifact"])
assert all(REASONS[MISSING] in c["rationale"] for c in record["claims"])
assert all(REASONS[ref] in c["rationale"] for c in record["claims"])
# 只有写作者调用了模型
assert called == [WRITER_MODEL]
no_mock(evs, run.output, out, record)
async def test_an_inquiry_with_a_broken_verify_provider_answers_with_the_reason(monkeypatch, sales, client):
@pytest.mark.parametrize("ref", [MISSING, DISABLED])
async def test_an_inquiry_with_a_broken_verify_provider_answers_with_the_reason(monkeypatch, sales, client, ref):
called = script(monkeypatch, writer=TEXT)
await put_setting("verify", {"provider": DISABLED})
await put_setting("verify", {"provider": ref})
paused = await start(report_graph(sales, node("gate", "human", mode="approve", title="周报可以出具吗")),
statuses=("interrupted",))
async with SessionLocal() as session:
@@ -314,7 +316,7 @@ async def test_an_inquiry_with_a_broken_verify_provider_answers_with_the_reason(
inquiry = r.json()["inquiry"]
answer = inquiry["answer"]
assert answer["ok"] is False and answer["text"] == ""
assert answer["error"].startswith("核查模型不可用") and REASONS[DISABLED] in answer["error"], answer["error"]
assert answer["error"].startswith("核查模型不可用") and REASONS[ref] in answer["error"], answer["error"]
assert inquiry["model"] is None and inquiry["usage"]["calls"] == 0
evs = await events(paused.id)
[event] = [e for e in evs if e.type == "approval.inquiry"]
@@ -400,13 +402,14 @@ async def test_the_assistant_model_lookup_reports_no_error_when_it_works(client)
assert body["error"] is None
async def test_a_broken_gate_provider_hands_the_call_to_a_person_and_says_why(monkeypatch):
@pytest.mark.parametrize("ref", [MISSING, DISABLED])
async def test_a_broken_gate_provider_hands_the_call_to_a_person_and_says_why(monkeypatch, ref):
from langchain_core.tools import StructuredTool
from app.tools.trust import ask_gate
called = script(monkeypatch)
await put_setting("run", {"tool_gate_provider": MISSING})
await put_setting("run", {"tool_gate_provider": ref})
def lookup(name: str) -> str:
return name
@@ -414,7 +417,7 @@ async def test_a_broken_gate_provider_hands_the_call_to_a_person_and_says_why(mo
tool = StructuredTool.from_function(lookup, name="crm_lookup", description="按客户名称查询客户档案")
verdict = await ask_gate(tool=tool, args={"name": "甲公司"}, node_title="查客户", task="查甲公司的档案")
assert verdict.allowed is False
assert verdict.reason.startswith("门控模型未给出判断") and REASONS[MISSING] in verdict.reason, verdict.reason
assert verdict.reason.startswith("门控模型未给出判断") and REASONS[ref] in verdict.reason, verdict.reason
assert verdict.model == "" and called == []