diff --git a/CHANGELOG.md b/CHANGELOG.md index 557626c..503a876 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## [6.2.9] - 2026-04-28 + +### Improved + +- **Toktrack-2.6.0-Modellnamen mit Provider-Suffixen** — Modelle wie `GPT-5 4::openai` werden jetzt auf die kanonische Modellfamilie und den zugehörigen Provider normalisiert, sodass vordefinierte Farben, Aggregationen und Provider-Erkennung auch mit den neuen Toktrack-Suffixen stabil bleiben +- **CodeQL-stabilere Integrationstest-Helfer** — E2E-/Integrationstest-Fetches akzeptieren nur noch validierte Loopback-URLs, Background-Registry-Fixtures werden strukturiert normalisiert, und lokale Auth-Bootstrap-Tests nutzen explizite Test-Tokens statt file-derived URLs +- **Robustere Reporting-Locale-E2E-Abdeckung** — der PDF-Reporting-Test nutzt stabile Sprachumschalter-Test-IDs und prüft den Report-Payload sowohl im deutschen Ausgangszustand als auch nach dem Wechsel auf Englisch + +### Fixed + +- **CodeQL-Alerts in Testpfaden** — TOCTOU- und Datei-/Netzwerk-Datenflüsse in Auto-Import-, Local-Auth- und Background-Registry-Tests wurden entfernt oder auf explizit validierte lokale Testdaten begrenzt +- **Fragile Sprachumschalter-Selektion im Reporting-Test** — der E2E-Test hängt nicht mehr an übersetzten `title`-Strings wie `English` oder `Englisch`, sondern an stabilen `data-testid`-Attributen + +### Commits + +- Enthält alle Branch-Commits seit `6.2.8`: `6fa78ce`, `c2494ae`, `365254b` + ## [6.2.8] - 2026-04-27 ### Added diff --git a/shared/dashboard-domain.js b/shared/dashboard-domain.js index e47f371..e6830db 100644 --- a/shared/dashboard-domain.js +++ b/shared/dashboard-domain.js @@ -10,6 +10,19 @@ const PROVIDER_MATCHERS = modelNormalizationSpec.providerMatchers.map((matcher) matcher: new RegExp(matcher.pattern, 'i'), })) +const TOKTRACK_PROVIDER_SUFFIXES = new Map([ + ['alibaba', 'Alibaba'], + ['anthropic', 'Anthropic'], + ['cohere', 'Cohere'], + ['deepseek', 'DeepSeek'], + ['google', 'Google'], + ['mistral', 'Mistral'], + ['opencode', 'OpenCode'], + ['openai', 'OpenAI'], + ['xai', 'xAI'], + ['meta', 'Meta'], +]) + function titleCaseSegment(segment) { if (!segment) return segment if (/^\d+([.-]\d+)*$/.test(segment)) return segment.replace(/-/g, '.') @@ -26,9 +39,25 @@ function formatVersion(version) { return version.replace(/-/g, '.') } +function splitToktrackProviderSuffix(raw) { + const value = String(raw || '').trim() + const match = value.match(/^(.*)::([a-z][a-z0-9_-]*)$/i) + if (!match) { + return { model: value, provider: null } + } + + const model = match[1].trim() + const provider = TOKTRACK_PROVIDER_SUFFIXES.get(match[2].toLowerCase()) ?? null + if (!model || !provider) { + return { model: value, provider: null } + } + + return { model, provider } +} + function canonicalizeModelName(raw) { - const normalized = String(raw || '') - .trim() + const { model } = splitToktrackProviderSuffix(raw) + const normalized = model .toLowerCase() .replace(/^model[:/ -]*/i, '') .replace(/^(anthropic|openai|google|vertex|models)[/-]/i, '') @@ -191,6 +220,9 @@ function normalizeModelName(raw) { * @returns The normalized provider name. */ function getModelProvider(raw) { + const suffixProvider = splitToktrackProviderSuffix(raw).provider + if (suffixProvider) return suffixProvider + const canonical = canonicalizeModelName(raw) for (const matcher of PROVIDER_MATCHERS) { if (matcher.matcher.test(canonical)) return matcher.provider diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx index 8681ebd..57b47d3 100644 --- a/src/components/layout/Header.tsx +++ b/src/components/layout/Header.tsx @@ -254,6 +254,7 @@ export function Header({