refactor: audit batch 3 (I-3 capability verdict, I-4 policy merge)
- I-3: new models.evaluate_capability returning a CapabilityVerdict (ok/missing/unknown from check, known/unknown_missing from split, status/verb derivations); decide_routing, worker gateway check, worker persisted recheck, dry-run tier+gateway checks and server shadow endpoint all call it. Blocking rules stay at the call sites (gateway has no worker-default fallback, recheck blocks only on known, dry-run/shadow never block); all user-visible audit details, dry-run notes and shadow notes are byte-identical. - I-4: new models.merge_policy_documents shared by load_routing_policy and dry_run_from_env; the old tiers-update block is kept verbatim (it was a no-op after update(): JSON tiers replace the whole map, file tiers absent from JSON are dropped -- preserved, not fixed, as that would be a behaviour change). dropped_tiers/partial_failures remain load-time records, not merge products. - Tests: test_audit_batch3.py, 13 tests (verdict matrix + parity with check/split, decide/dry-run wording, merge boundaries + 300 seeded random pairs + loader/dry-run agreement). Full suite: 1694 OK (skipped=11), baseline 1681 + 13, 0 failures.
This commit is contained in:
1 parent
a7f77c8a98
commit
06e4e16bbb
5 files changed
+485
-68
No files matched your search
+17
-21
@@ -165,10 +165,9 @@ from cloud.db import connect as _db_connect
|
||||
from cloud.goal_command import parse_goal_command as _parse_goal_command
|
||||
from cloud.logging_config import get_logger, log_event, setup_logging
|
||||
from cloud.models import ModelRouter, RoutingPolicy, decide_routing, \
|
||||
check_model_capabilities, classify_task, \
|
||||
classify_task, evaluate_capability, \
|
||||
is_fallbackable, load_routing_policy, parse_routing_policy, \
|
||||
record_fallback, record_routing, \
|
||||
split_model_capability_missing
|
||||
record_fallback, record_routing
|
||||
from cloud.routing_shadow import parse_worker_routing_detail as \
|
||||
_parse_routing_detail
|
||||
from cloud.auto_memory import AutoMemoryStore
|
||||
@@ -7032,15 +7031,15 @@ class Worker:
|
||||
if mode not in ("active", "shadow"):
|
||||
return None
|
||||
model = task.get("model")
|
||||
ok, missing, unknown = check_model_capabilities(
|
||||
verdict = evaluate_capability(
|
||||
self.routing_policy.model_capabilities, model, requires)
|
||||
if ok:
|
||||
if verdict.ok:
|
||||
return None
|
||||
known, _unk = split_model_capability_missing(
|
||||
self.routing_policy.model_capabilities, model, requires)
|
||||
known = verdict.known_missing
|
||||
detail = ("%s model=%s tier=%s mode=%s missing=%s unknown=%s"
|
||||
% (task["id"], model, tier, mode,
|
||||
",".join(missing) or "-", unknown))
|
||||
",".join(verdict.missing) or "-",
|
||||
verdict.unknown))
|
||||
if mode == "shadow":
|
||||
self._audit(task["project_id"],
|
||||
"worker_capability_recheck_shadow", detail)
|
||||
@@ -7444,17 +7443,17 @@ class Worker:
|
||||
if _gw_requires:
|
||||
_gw_mode = self.routing_policy.tier_mode(_gw_tier)
|
||||
if _gw_mode in ("active", "shadow"):
|
||||
_gw_ok, _gw_missing, _gw_unknown = \
|
||||
check_model_capabilities(
|
||||
self.routing_policy.model_capabilities,
|
||||
task.get("model"), _gw_requires)
|
||||
if not _gw_ok:
|
||||
_gw_verdict = evaluate_capability(
|
||||
self.routing_policy.model_capabilities,
|
||||
task.get("model"), _gw_requires)
|
||||
if not _gw_verdict.ok:
|
||||
_gw_note = ("gateway model %s %s capability:"
|
||||
" %s" % (
|
||||
task.get("model"),
|
||||
"cannot verify"
|
||||
if _gw_unknown else "lacks",
|
||||
", ".join(_gw_missing)))
|
||||
if _gw_verdict.unknown
|
||||
else "lacks",
|
||||
", ".join(_gw_verdict.missing)))
|
||||
# Audit fix 4(第三遍审计分档建议):
|
||||
# 显式模型按 known/unknown 分档。known
|
||||
# 是目录明确写了不满足(布尔 False、
|
||||
@@ -7463,10 +7462,7 @@ class Worker:
|
||||
# 无该模型、或条目缺字段,目录陈旧
|
||||
# 不应惩罚用户的正确选择,只审计不拦。
|
||||
# shadow 档两种情况都只审计。
|
||||
_gw_known, _gw_unk = \
|
||||
split_model_capability_missing(
|
||||
self.routing_policy.model_capabilities,
|
||||
task.get("model"), _gw_requires)
|
||||
_gw_known = _gw_verdict.known_missing
|
||||
_gw_block = False
|
||||
_gw_error = None
|
||||
if _explicit_model:
|
||||
@@ -7483,8 +7479,8 @@ class Worker:
|
||||
" missing=%s unknown=%s blocked=%s"
|
||||
% (task_id, task.get("model"),
|
||||
_gw_tier, _gw_mode,
|
||||
",".join(_gw_missing) or "-",
|
||||
_gw_unknown,
|
||||
",".join(_gw_verdict.missing) or "-",
|
||||
_gw_verdict.unknown,
|
||||
_gw_blocked))
|
||||
if _gw_blocked:
|
||||
_gw_block = True
|
||||
|
||||
Reference in new issue
Block a user