mirror of
https://github.com/usestrix/strix.git
synced 2026-08-19 01:55:46 +02:00
fix(viewer): show the actual subscription provider name
The Run details panel hardcoded "ChatGPT subscription" for any subscription run. Emit subscription_provider (ChatGPT/Grok) in the run record and render it in the viewer, so Grok runs read "Grok subscription". Rebuilds the committed viewer bundle.
This commit is contained in:
@@ -19,6 +19,9 @@ if TYPE_CHECKING:
|
||||
|
||||
_PROVIDERS: tuple[ModuleType, ...] = (codex, grok)
|
||||
|
||||
# Human-facing provider names keyed by each module's ``PROVIDER`` constant.
|
||||
_DISPLAY_NAMES: dict[str, str] = {codex.PROVIDER: "ChatGPT", grok.PROVIDER: "Grok"}
|
||||
|
||||
|
||||
def provider_for_model(model_name: str | None) -> ModuleType | None:
|
||||
"""Return the subscription provider module that owns ``model_name``'s prefix,
|
||||
@@ -31,3 +34,12 @@ def provider_for_model(model_name: str | None) -> ModuleType | None:
|
||||
|
||||
def auth_mode(model_name: str | None) -> str:
|
||||
return "subscription" if provider_for_model(model_name) is not None else "api_key"
|
||||
|
||||
|
||||
def provider_label(model_name: str | None) -> str | None:
|
||||
"""Human-facing name of the subscription provider for ``model_name`` (e.g.
|
||||
"ChatGPT" or "Grok"), or None when the model isn't a subscription model."""
|
||||
provider = provider_for_model(model_name)
|
||||
if provider is None:
|
||||
return None
|
||||
return _DISPLAY_NAMES.get(provider.PROVIDER)
|
||||
|
||||
@@ -101,6 +101,7 @@ export function RunDetails({
|
||||
const totalTokens = num(usage.total_tokens);
|
||||
const cost = num(usage.cost);
|
||||
const subscription = str(raw.auth_mode) === "subscription";
|
||||
const subscriptionProvider = str(raw.subscription_provider) || "ChatGPT";
|
||||
|
||||
const sub = (n: number, word: string) => (
|
||||
<span className="text-[#666]"> ({formatNumber(n)} {word})</span>
|
||||
@@ -180,7 +181,7 @@ export function RunDetails({
|
||||
<Field label="Provider">
|
||||
<span className="inline-flex items-center gap-1.5">
|
||||
<span className="rounded-full border border-[#22c55e]/40 bg-[#22c55e]/10 px-2 py-0.5 text-[11px] text-[#22c55e]">
|
||||
ChatGPT subscription
|
||||
{subscriptionProvider} subscription
|
||||
</span>
|
||||
</span>
|
||||
</Field>
|
||||
|
||||
+21
-21
File diff suppressed because one or more lines are too long
@@ -6,7 +6,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="color-scheme" content="dark" />
|
||||
<title>Strix Results</title>
|
||||
<script type="module" crossorigin src="./assets/index-DzvI_0HX.js"></script>
|
||||
<script type="module" crossorigin src="./assets/index-BAP4-Z16.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-C3kQ5kk8.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -119,7 +119,8 @@ class ReportState:
|
||||
self.scan_results: dict[str, Any] | None = None
|
||||
self.scan_config: dict[str, Any] | None = None
|
||||
self._llm_usage = LLMUsageLedger()
|
||||
auth_mode = subscription.auth_mode(load_settings().llm.model)
|
||||
model = load_settings().llm.model
|
||||
auth_mode = subscription.auth_mode(model)
|
||||
self._llm_usage.zero_cost = auth_mode == "subscription"
|
||||
self.run_record: dict[str, Any] = {
|
||||
"run_id": self.run_id,
|
||||
@@ -128,6 +129,7 @@ class ReportState:
|
||||
"end_time": None,
|
||||
"status": "running",
|
||||
"auth_mode": auth_mode,
|
||||
"subscription_provider": subscription.provider_label(model),
|
||||
"targets_info": [],
|
||||
"llm_usage": self._build_llm_usage_record(),
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@ from unittest import mock
|
||||
|
||||
from agents.models.openai_chatcompletions import OpenAIChatCompletionsModel
|
||||
|
||||
from strix.config import grok
|
||||
from strix.config import grok, subscription
|
||||
from strix.config.models import StrixProvider
|
||||
from strix.report import state as state_mod
|
||||
|
||||
|
||||
def test_grok_prefix_routes_to_chat_completions(monkeypatch) -> None: # type: ignore[no-untyped-def]
|
||||
@@ -32,3 +33,21 @@ def test_non_subscription_model_is_not_hijacked_by_grok(monkeypatch) -> None: #
|
||||
# not the subscription route.
|
||||
model = StrixProvider().get_model("xai/grok-4")
|
||||
assert not (isinstance(model, OpenAIChatCompletionsModel) and model.model == "grok-4")
|
||||
|
||||
|
||||
def test_provider_label_names_the_subscription() -> None:
|
||||
assert subscription.provider_label("grok/grok-4") == "Grok"
|
||||
assert subscription.provider_label("chatgpt/gpt-5.4") == "ChatGPT"
|
||||
# Metered API-key models are not subscriptions.
|
||||
assert subscription.provider_label("xai/grok-4") is None
|
||||
assert subscription.provider_label("openai/gpt-5.4") is None
|
||||
|
||||
|
||||
def test_run_record_reports_grok_provider(monkeypatch) -> None: # type: ignore[no-untyped-def]
|
||||
settings = mock.MagicMock()
|
||||
settings.llm.model = "grok/grok-4"
|
||||
monkeypatch.setattr(state_mod, "load_settings", lambda: settings)
|
||||
|
||||
record = state_mod.ReportState(run_name="run-test").run_record
|
||||
assert record["auth_mode"] == "subscription"
|
||||
assert record["subscription_provider"] == "Grok"
|
||||
|
||||
Reference in New Issue
Block a user