Fix doppelte API-Key-Meldung: originLabel zeigt nur noch ENV-Hinweis

Der API-Key-Herkunfts-Label (apiKeyOriginLabel) zeigte bisher sowohl
INFO-Befunde (Schlüssel kommt aus Umgebungsvariable) als auch
WARNING/ERROR-Befunde (Schlüssel fehlt) an. Da das fieldErrorLabel
direkt darunter dieselben WARNING/ERROR-Befunde bereits anzeigt,
erschien die „Kein API-Key"-Meldung zweimal im selben Bereich.

Lösung: refreshApiKeyOriginLabels() wertet nur noch INFO-Befunde aus.
WARNING/ERROR-Befunde für fehlende API-Keys werden ausschließlich vom
fieldErrorLabel angezeigt. STYLE_ORIGIN_MISSING entfernt.

Drei neue Smoke-Tests sichern das Verhalten ab:
- apiKeyAbsent_originLabelHidden
- apiKeyAbsent_fieldErrorLabelVisible
- apiKeyAbsent_noDuplicateMessageInPendingMessages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-22 13:42:18 +02:00
parent 0f07947879
commit 4875a1ed42
2 changed files with 85 additions and 22 deletions
@@ -1967,14 +1967,14 @@ public final class GuiConfigurationEditorWorkspace {
/**
* Updates the API-key origin labels below each provider's API-key field.
* <p>
* The display logic follows the effective-key precedence order:
* <ol>
* <li>If the effective key comes from an environment variable, the label shows the
* variable name in an informational style.</li>
* <li>If the property value is filled and no environment variable overrides it, the label
* is hidden.</li>
* <li>If no key source is effective, the label shows a warning in the field-error style.</li>
* </ol>
* The label is shown exclusively when the effective key comes from an environment variable
* (INFO finding). In all other cases the label is hidden:
* <ul>
* <li>Key from properties file: label hidden (no action required).</li>
* <li>Key absent (WARNING finding): label hidden — the field-error label registered in
* {@link #fieldErrorLabels} already displays this finding directly below the field;
* showing it a second time in the origin label would produce a visible duplicate.</li>
* </ul>
* <p>
* The origin information is derived from the pending field findings produced by the validator,
* which already resolved the API-key precedence for both providers.
@@ -1988,28 +1988,20 @@ public final class GuiConfigurationEditorWorkspace {
String apiKeyField = "ai.provider." + family.getIdentifier() + ".apiKey";
// Look for an INFO finding about ENV-variable origin for this provider.
// WARNING/ERROR findings (missing key) are intentionally excluded here:
// those are already shown by the field-error label registered in fieldErrorLabels,
// and repeating them in the origin label would cause the same text to appear twice
// in close proximity below the API-key field.
Optional<GuiFieldFinding> envFinding = pendingFieldFindings.stream()
.filter(f -> apiKeyField.equals(f.fieldKey()))
.filter(f -> f.severity() == GuiMessageSeverity.INFO)
.findFirst();
// Look for an ERROR/WARNING finding about missing key for this provider.
Optional<GuiFieldFinding> missingFinding = pendingFieldFindings.stream()
.filter(f -> apiKeyField.equals(f.fieldKey()))
.filter(f -> f.severity() == GuiMessageSeverity.ERROR
|| f.severity() == GuiMessageSeverity.WARNING)
.findFirst();
if (envFinding.isPresent()) {
label.setText(envFinding.get().text());
label.setStyle(STYLE_ORIGIN_INFO);
label.setVisible(true);
label.setManaged(true);
} else if (missingFinding.isPresent()) {
label.setText(missingFinding.get().text());
label.setStyle(STYLE_ORIGIN_MISSING);
label.setVisible(true);
label.setManaged(true);
} else {
label.setText("");
label.setVisible(false);
@@ -2020,8 +2012,6 @@ public final class GuiConfigurationEditorWorkspace {
private static final String STYLE_ORIGIN_INFO =
"-fx-font-size: 11px; -fx-text-fill: #1565c0; -fx-padding: 0 0 4px 0;";
private static final String STYLE_ORIGIN_MISSING =
"-fx-font-size: 11px; -fx-text-fill: #b71c1c; -fx-padding: 0 0 4px 0;";
// =========================================================================
// Path picker helpers