From c05f48f52007b444c5c007e39d99593d4cdfda71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Fri, 8 May 2026 21:36:36 +0200 Subject: [PATCH] =?UTF-8?q?feat(settings):=20KI-provider=20=E2=80=94=20Ope?= =?UTF-8?q?nAI=20key=20field,=20model=20preset=20dropdown,=20gated=20OAuth?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bucket C of the v1.4.3 polish pass. Three independent bugs in the KI-provider settings, fixed together because they all live on the same panel: 1. **Selecting "OpenAI" left no way to provide a key.** The schema stored Anthropic and Local API keys, but OPENAI was a valid `aiProvider` value with no matching credential column — the resolver silently fell through to the admin-level OpenAI key. So a self-hosted user who picked OpenAI and typed nothing got the admin's key (might not exist), and a user who *wanted* their own OpenAI key had no UI surface to enter it. Migration `0026_user_ai_openai_key` adds `users.ai_openai_key_ encrypted`. The resolver's `OPENAI` branch now picks up the user-level key first and only falls back to admin if the user slot is empty. The settings UI grew an OpenAI-key field gated on `provider === "OPENAI"` mirroring the Anthropic flow. The `/api/ai/test` override schema accepts `openaiKey` so the "Verbindung testen" button can validate an unsaved key without persisting plaintext. 2. **Model field was a freetext Input, easy to typo.** Replaced with a ` setProvider(e.target.value)} + onChange={(e) => handleProviderChange(e.target.value)} className="bg-background border-input mt-1 h-9 w-full rounded-md border px-2 text-sm" > - + -
- - setModel(e.target.value)} - placeholder={ - provider === "ANTHROPIC" - ? "claude-3-5-sonnet-latest" - : provider === "LOCAL" - ? "llama3:8b" - : "gpt-4o-mini" - } - className="mt-1" - /> + +
+ {modelChoice === CUSTOM_MODEL_SENTINEL && provider && ( +
+ + setCustomModel(e.target.value)} + placeholder={ + provider === "ANTHROPIC" + ? "claude-3-5-sonnet-latest" + : provider === "LOCAL" + ? "llama3:8b" + : "gpt-4o-mini" + } + className="mt-1" + /> +
+ )} + + {provider === "OPENAI" && ( +
+ + setOpenaiKey(e.target.value)} + placeholder="sk-..." + className="mt-1" + /> +

+ Eigener Key — keine Verbindung zu deinem ChatGPT-Abo. Für das + Abo nutze den Verbinden-Button oben. +

+
+ )} + {provider === "ANTHROPIC" && (