feat(capability_matrix): add 12 v2 fields to VendorCapabilities
The 7 v1 fields (vision, tool_calling, caching, streaming, model_discovery, context_window, cost_tracking) plus 2 cost fields and notes are now extended by 12 v2 fields: local, reasoning, structured_output, code_execution, web_search, x_search, file_search, mcp_support, audio, video, grounding, computer_use All default to False. Registry entries continue to work unchanged (backward compatible). t4_1 of Phase 4. Tests: - 12 parameterized 'default is False' tests - 12 parameterized 'round-trip to True' tests - 3 'local flag' tests: per-model, wildcard fallback, vendor isolation - 3 pre-existing registry tests still pass - 96/96 vendor+tool+provider+import-isolation tests pass (no regressions; +27 new tests this commit)
This commit is contained in:
@@ -15,6 +15,19 @@ class VendorCapabilities:
|
|||||||
cost_input_per_mtok: float = 0.0
|
cost_input_per_mtok: float = 0.0
|
||||||
cost_output_per_mtok: float = 0.0
|
cost_output_per_mtok: float = 0.0
|
||||||
notes: str = ''
|
notes: str = ''
|
||||||
|
# v2 fields (added 2026-06-11)
|
||||||
|
local: bool = False
|
||||||
|
reasoning: bool = False
|
||||||
|
structured_output: bool = False
|
||||||
|
code_execution: bool = False
|
||||||
|
web_search: bool = False
|
||||||
|
x_search: bool = False
|
||||||
|
file_search: bool = False
|
||||||
|
mcp_support: bool = False
|
||||||
|
audio: bool = False
|
||||||
|
video: bool = False
|
||||||
|
grounding: bool = False
|
||||||
|
computer_use: bool = False
|
||||||
|
|
||||||
_REGISTRY: dict[tuple[str, str], VendorCapabilities] = {}
|
_REGISTRY: dict[tuple[str, str], VendorCapabilities] = {}
|
||||||
|
|
||||||
|
|||||||
@@ -38,3 +38,35 @@ def test_fallback_to_vendor_default():
|
|||||||
def test_unknown_vendor_raises():
|
def test_unknown_vendor_raises():
|
||||||
with pytest.raises(KeyError, match='No capabilities registered'):
|
with pytest.raises(KeyError, match='No capabilities registered'):
|
||||||
get_capabilities('nonexistent_vendor', 'anymodel')
|
get_capabilities('nonexistent_vendor', 'anymodel')
|
||||||
|
|
||||||
|
V2_FIELDS: list[str] = [
|
||||||
|
'local', 'reasoning', 'structured_output', 'code_execution',
|
||||||
|
'web_search', 'x_search', 'file_search', 'mcp_support',
|
||||||
|
'audio', 'video', 'grounding', 'computer_use',
|
||||||
|
]
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('field_name', V2_FIELDS)
|
||||||
|
def test_v2_field_default_is_false(field_name: str) -> None:
|
||||||
|
caps = VendorCapabilities(vendor='test', model='m')
|
||||||
|
assert getattr(caps, field_name) is False, f'{field_name} should default to False'
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('field_name', V2_FIELDS)
|
||||||
|
def test_v2_field_round_trip(field_name: str) -> None:
|
||||||
|
caps = VendorCapabilities(vendor='test', model='m', **{field_name: True})
|
||||||
|
assert getattr(caps, field_name) is True, f'{field_name} should round-trip to True'
|
||||||
|
|
||||||
|
def test_v2_local_flag_works_for_local_vendor() -> None:
|
||||||
|
register(VendorCapabilities(vendor='llama', model='llama-local-test-3.1', local=True))
|
||||||
|
caps = get_capabilities('llama', 'llama-local-test-3.1')
|
||||||
|
assert caps.local is True
|
||||||
|
|
||||||
|
def test_v2_local_flag_falls_back_to_wildcard() -> None:
|
||||||
|
register(VendorCapabilities(vendor='llama', model='*', local=True))
|
||||||
|
caps = get_capabilities('llama', 'some-unregistered-model-3.1-future')
|
||||||
|
assert caps.local is True
|
||||||
|
|
||||||
|
def test_v2_local_flag_does_not_affect_other_vendors() -> None:
|
||||||
|
register(VendorCapabilities(vendor='llama', model='*', local=True))
|
||||||
|
register(VendorCapabilities(vendor='qwen', model='*'))
|
||||||
|
caps = get_capabilities('qwen', 'qwen-turbo')
|
||||||
|
assert caps.local is False
|
||||||
|
|||||||
Reference in New Issue
Block a user