mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-22 00:31:44 +00:00
fix(matrix-builder): greptile — surface pass over not_applicable when mixed
When a cell aggregates per-model results across three tiers (Haiku/Sonnet/Opus), a mix of (pass, not_applicable) used to short-circuit to not_applicable on the first NA match, discarding the passing tiers from the published matrix. Treat not_applicable like not_tested when mixed with pass: only return not_applicable when every observed row is NA. Otherwise any pass surfaces as pass, so the cell answers 'does this feature work on this provider?' truthfully when at least one tier passes. Add two regression tests pinning the new precedence: - mixed pass + NA → pass - all NA → not_applicable (with first reason)
This commit is contained in:
parent
88a795bfcc
commit
5d121fa697
2 changed files with 87 additions and 10 deletions
|
|
@ -189,6 +189,78 @@ def test_build_matrix_all_not_tested_stays_not_tested():
|
|||
assert matrix["features"][0]["providers"]["anthropic"] == {"status": "not_tested"}
|
||||
|
||||
|
||||
def test_build_matrix_mixed_pass_and_not_applicable_surfaces_pass():
|
||||
"""A `not_applicable` row mixed with `pass` rows must surface as
|
||||
`pass`, not `not_applicable`. The published cell answers "does this
|
||||
feature work on this provider?"; if any tier passes, the feature
|
||||
works there. Discarding passing tiers because one tier is NA would
|
||||
misrepresent the cell as unsupported.
|
||||
"""
|
||||
manifest = {
|
||||
"schema_version": "1",
|
||||
"providers": ["anthropic"],
|
||||
"features": [{"id": "f", "name": "F"}],
|
||||
}
|
||||
results = [
|
||||
{"feature_id": "f", "provider": "anthropic", "result": {"status": "pass"}},
|
||||
{
|
||||
"feature_id": "f",
|
||||
"provider": "anthropic",
|
||||
"result": {
|
||||
"status": "not_applicable",
|
||||
"reason": "haiku does not support extended thinking",
|
||||
},
|
||||
},
|
||||
{"feature_id": "f", "provider": "anthropic", "result": {"status": "pass"}},
|
||||
]
|
||||
matrix = build_matrix(
|
||||
manifest=manifest,
|
||||
results=results,
|
||||
litellm_version="v",
|
||||
claude_code_version="c",
|
||||
generated_at="t",
|
||||
)
|
||||
assert matrix["features"][0]["providers"]["anthropic"] == {"status": "pass"}
|
||||
|
||||
|
||||
def test_build_matrix_all_not_applicable_stays_not_applicable():
|
||||
"""When every observed row is `not_applicable`, the cell remains
|
||||
`not_applicable` and the first row's reason carries through to the
|
||||
published matrix.
|
||||
"""
|
||||
manifest = {
|
||||
"schema_version": "1",
|
||||
"providers": ["anthropic"],
|
||||
"features": [{"id": "f", "name": "F"}],
|
||||
}
|
||||
results = [
|
||||
{
|
||||
"feature_id": "f",
|
||||
"provider": "anthropic",
|
||||
"result": {
|
||||
"status": "not_applicable",
|
||||
"reason": "feature unsupported on this provider",
|
||||
},
|
||||
},
|
||||
{
|
||||
"feature_id": "f",
|
||||
"provider": "anthropic",
|
||||
"result": {"status": "not_applicable", "reason": "ditto"},
|
||||
},
|
||||
]
|
||||
matrix = build_matrix(
|
||||
manifest=manifest,
|
||||
results=results,
|
||||
litellm_version="v",
|
||||
claude_code_version="c",
|
||||
generated_at="t",
|
||||
)
|
||||
assert matrix["features"][0]["providers"]["anthropic"] == {
|
||||
"status": "not_applicable",
|
||||
"reason": "feature unsupported on this provider",
|
||||
}
|
||||
|
||||
|
||||
def test_build_matrix_fills_not_tested_for_missing_cells():
|
||||
manifest = {
|
||||
"schema_version": "1",
|
||||
|
|
|
|||
|
|
@ -133,8 +133,14 @@ def _aggregate_cell(results: Sequence[Mapping[str, Any]]) -> Dict[str, Any]:
|
|||
- Any `fail` → cell is `fail` with every failing model's error
|
||||
joined by `"; "` so a multi-tier breakage doesn't silently hide
|
||||
all but the first error from the published matrix.
|
||||
- `not_applicable` → cell is `not_applicable` with the reason.
|
||||
- `pass` → cell is `pass`.
|
||||
- Any `pass` → cell is `pass`. A mix of (pass, not_applicable) —
|
||||
e.g. a tier where the feature isn't supported alongside tiers
|
||||
where it works — surfaces as `pass` so the published cell
|
||||
reflects that the feature *does* work on this provider rather
|
||||
than silently demoting it to `not_applicable` and discarding
|
||||
the passing tiers.
|
||||
- All `not_applicable` → cell is `not_applicable` with the first
|
||||
row's reason.
|
||||
- empty / nothing recognized → `not_tested`.
|
||||
|
||||
`not_tested` rows are treated as absent data: they're dropped before
|
||||
|
|
@ -156,16 +162,15 @@ def _aggregate_cell(results: Sequence[Mapping[str, Any]]) -> Dict[str, Any]:
|
|||
errors = [str(r.get("error", "test failed")) for r in failures]
|
||||
return {"status": "fail", "error": "; ".join(errors)}
|
||||
|
||||
for r in observed:
|
||||
if r.get("status") == "not_applicable":
|
||||
return {
|
||||
"status": "not_applicable",
|
||||
"reason": str(r.get("reason", "not applicable")),
|
||||
}
|
||||
|
||||
if all(r.get("status") == "pass" for r in observed):
|
||||
if any(r.get("status") == "pass" for r in observed):
|
||||
return {"status": "pass"}
|
||||
|
||||
if all(r.get("status") == "not_applicable" for r in observed):
|
||||
return {
|
||||
"status": "not_applicable",
|
||||
"reason": str(observed[0].get("reason", "not applicable")),
|
||||
}
|
||||
|
||||
return {"status": "not_tested"}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue