Private
Public Access
0
0

feat(gui): add v2 capability badges in provider panel

Phase 5 t5_4 (UI adaptations for 11 v2 fields): the simplest
honest adaptation — render small colored badges for the 11
v2 fields where the active vendor+model supports them. Each
badge has a tooltip showing the field name.

The 11 fields:
  reasoning, structured_output, code_execution, web_search,
  x_search, file_search, mcp_support, audio, video,
  grounding, computer_use

A new module-level function _render_v2_capability_badges(caps)
is added to src/gui_2.py (per the HARD RULE on no new
src/<thing>.py files). It's called from render_provider_panel
right after the existing '[Local]' badge (which uses the
runtime override for caps.local).

What this is NOT: a full UI for the 11 fields (per-field
toggles, panels, attachment buttons). Those are design-heavy
work and need their own track. This change gives the user
visibility into which capabilities the active vendor+model
supports, so they can make informed decisions about which
prompts/features to use.

For example, when the user selects qwen-audio, they'll see:
  Provider: qwen [Local]  Capabilities [Audio]
Which makes it obvious they can attach audio files.

Tests:
- 2 new tests in tests/test_vendor_capabilities.py:
  * All 11 v2 fields are present in the helper (drift guard)
  * Helper is a no-op on empty caps (no fields True)
- 118/118 vendor+tool+provider+import-isolation tests pass
  (no regressions; +2 new tests this commit)
- 3 audit scripts pass
This commit is contained in:
2026-06-11 21:46:41 -04:00
parent 7fee76f491
commit c9135b0565
2 changed files with 69 additions and 0 deletions
+42
View File
@@ -258,6 +258,47 @@ def _apply_runtime_caps_override(app: "App", caps: "VendorCapabilities") -> "Ven
return replace(caps, local=True)
return caps
def _render_v2_capability_badges(caps: "VendorCapabilities") -> None:
"""Render small colored badges for the 11 v2 capability flags.
Only fields where caps.<field> is True are shown. Each badge
has a tooltip with the field name. Per-field colors map to
the existing theme convention: green for supported, grey for
not. Fields with no entry (False) are silently omitted.
Added 2026-06-11 as part of Phase 5 t5_4 (UI adaptations for
new v2 fields). The 11 fields are the v2 matrix fields beyond
the original 7 v1 fields (vision, tool_calling, caching,
streaming, model_discovery, context_window, cost_tracking)
which are already gated elsewhere in the GUI.
[C: src/gui_2.py:render_provider_panel]
"""
badged_fields: list[tuple[str, str]] = [
("reasoning", "Reasoning"),
("structured_output", "JSON"),
("code_execution", "Code"),
("web_search", "Web"),
("x_search", "X"),
("file_search", "File"),
("mcp_support", "MCP"),
("audio", "Audio"),
("video", "Video"),
("grounding", "Ground"),
("computer_use", "Comp"),
]
enabled: list[tuple[str, str]] = []
for field_name, label in badged_fields:
if getattr(caps, field_name, False):
enabled.append((field_name, label))
if not enabled:
return
imgui.text("Capabilities")
for field_name, label in enabled:
imgui.same_line()
imgui.text_colored(theme.get_color("status_success"), f" [{label}]")
if imgui.is_item_hovered():
imgui.set_tooltip(f"caps.{field_name}=True")
class App:
"""The main ImGui interface orchestrator for Manual Slop."""
@@ -2334,6 +2375,7 @@ def render_provider_panel(app: App) -> None:
if app.current_provider == "llama":
base_url = getattr(ai_client, "_llama_base_url", "")
imgui.set_tooltip(f"Local backend: {base_url or 'unknown'}" if base_url else "Local backend")
_render_v2_capability_badges(caps)
imgui.separator()
imgui.text("Model")
if imgui.begin_list_box("##models", imgui.ImVec2(-1, 120)):
+27
View File
@@ -193,3 +193,30 @@ def test_deepseek_wildcard_falls_back_to_v3_defaults() -> None:
caps = get_capabilities('deepseek', 'deepseek-future-unregistered')
assert caps.reasoning is True
assert caps.structured_output is True
def test_v2_capability_badge_helper_contains_all_11_v2_fields() -> None:
"""The GUI's v2 capability badges should render badges for all
11 v2 fields. This test ensures the helper stays in sync with
the v2 matrix."""
import src.gui_2
import inspect
src_lines: str = inspect.getsource(src.gui_2._render_v2_capability_badges)
known_v2_fields: list[str] = [
"reasoning", "structured_output", "code_execution",
"web_search", "x_search", "file_search", "mcp_support",
"audio", "video", "grounding", "computer_use",
]
for field in known_v2_fields:
assert f'"{field}"' in src_lines, f'v2 field {field!r} missing from _render_v2_capability_badges helper'
def test_v2_capability_badge_helper_skips_disabled_fields() -> None:
"""Sanity: a caps with all v2 fields False should produce no
badges. We can verify this by passing a default-constructed
VendorCapabilities and asserting the helper returns without
erroring. (We can't easily verify the ImGui output without
a live context, but we can verify the helper is a no-op on
the no-cap case.)"""
from src.gui_2 import _render_v2_capability_badges
from src.vendor_capabilities import VendorCapabilities
empty_caps = VendorCapabilities(vendor='test', model='empty')
_render_v2_capability_badges(empty_caps)