tenseleyflow/loader / ffef5b5

Browse files

Add capability profiles for devstral, qwen2.5-coder, and gpt-oss to fix native tool resolution

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
ffef5b5343225a920d399dedab007d04c23b6bd8
Parents
46e30a4
Tree
1d2fd00

2 changed files

StatusFile+-
M src/loader/runtime/capabilities.py 20 1
M tests/test_capabilities.py 30 0
src/loader/runtime/capabilities.pymodified
@@ -80,6 +80,25 @@ KNOWN_CAPABILITY_PROFILES: dict[str, CapabilityProfile] = {
8080
         preferred_tool_call_format="native",
8181
         verification_strictness="strict",
8282
     ),
83
+    "qwen2.5-coder": _profile(
84
+        "qwen2.5-coder",
85
+        supports_native_tools=True,
86
+        preferred_tool_call_format="native",
87
+        verification_strictness="strict",
88
+    ),
89
+    "devstral": _profile(
90
+        "devstral",
91
+        supports_native_tools=True,
92
+        preferred_tool_call_format="native",
93
+        verification_strictness="standard",
94
+        notes=["Agentic coding model; well-suited to loader's tool loop."],
95
+    ),
96
+    "gpt-oss": _profile(
97
+        "gpt-oss",
98
+        supports_native_tools=True,
99
+        preferred_tool_call_format="native",
100
+        verification_strictness="standard",
101
+    ),
83102
     "mistral": _profile(
84103
         "mistral",
85104
         supports_native_tools=True,
@@ -129,7 +148,7 @@ KNOWN_CAPABILITY_PROFILES: dict[str, CapabilityProfile] = {
129148
 
130149
 NATIVE_TOOL_FAMILIES = {
131150
     "llama3", "qwen2", "qwen2.5", "qwen3", "mistral", "mixtral",
132
-    "command-r", "granite", "devstral", "gemma4",
151
+    "command-r", "granite", "devstral", "gemma4", "gpt-oss",
133152
 }
134153
 NO_TOOL_FAMILIES = {
135154
     "llama2",
tests/test_capabilities.pymodified
@@ -49,6 +49,36 @@ def test_unknown_models_default_to_safe_react_profile() -> None:
4949
     assert "defaulting to safe" in resolved.notes[0].lower()
5050
 
5151
 
52
+def test_qwen25_coder_inherits_strict_verification() -> None:
53
+    resolved = resolve_capability_profile("qwen2.5-coder:32b")
54
+
55
+    assert resolved.supports_native_tools
56
+    assert resolved.preferred_tool_call_format == "native"
57
+    assert resolved.verification_strictness == "strict"
58
+
59
+
60
+def test_devstral_resolves_native_tools() -> None:
61
+    resolved = resolve_capability_profile("devstral:24b")
62
+
63
+    assert resolved.supports_native_tools
64
+    assert resolved.preferred_tool_call_format == "native"
65
+
66
+
67
+def test_gpt_oss_resolves_native_tools_via_registry() -> None:
68
+    resolved = resolve_capability_profile("gpt-oss")
69
+
70
+    assert resolved.supports_native_tools
71
+    assert resolved.preferred_tool_call_format == "native"
72
+
73
+
74
+def test_gpt_oss_custom_variant_resolves_native_via_family() -> None:
75
+    resolved = resolve_capability_profile("gpt-oss-custom:20b")
76
+
77
+    assert resolved.supports_native_tools
78
+    assert resolved.preferred_tool_call_format == "native"
79
+    assert "heuristic" in resolved.notes[0].lower()
80
+
81
+
5282
 def test_backend_capability_profile_prefers_explicit_backend_surface() -> None:
5383
     class DummyBackend:
5484
         def supports_native_tools(self) -> bool: