feat: OpenAI Provider, Key-Checker Quota-Erkennung, persistierte Scanner-Logs

- OpenAI als vollwertiger Chat-Provider (Modell-Auswahl, Key-Routing, StreamChat)
- Hardcoded OpenAI-Modelle im Cache (gpt-5.x, gpt-4.1, o3, o4-mini etc.)
- /api/models/openai Endpoint, OpenAI-Optgroup im Agent-Dropdown
- Key-Routing: OpenAI-Key aus api_keys-Tabelle, Fallback via GetFirstActiveKeyByProvider
- OpenAI-Checker: 2-Schritt-Check (Models + chat/completions mit max_tokens=1)
- Google-Checker: 2-Schritt-Check (Models + generateContent mit maxOutputTokens=1)
- 429 insufficient_quota und billing_not_active korrekt als quota_exceeded erkannt
- Provider-Erkennung beim Adopt via KeyPatterns.DetectType() statt hardcoded anthropic
- HandleCheck/HandleCheckAll unterstützt jetzt Anthropic, OpenAI und Google
- Neue scanner_logs-Tabelle mit details-Spalte (JSON) für strukturierte Auswertung
- GitHubEventScannerService: AddLog persistiert in DB, detaillierte Key-Fund-Logs
- KeyScannerService: AddLog-Methode mit DB-Persistierung, detaillierte Logs
- Frontend: Ungeprüfte-prüfen-Button (sequenziell, stoppt bei valid)
- Frontend: Provider-Indicator im Key-Switch-Modal (Anthropic/OpenAI/Google)
- Frontend: Check-Button für alle Provider (nicht nur Anthropic)
This commit is contained in:
Meleki committed 2026-03-14 11:19:33 +01:00
1 parent c8859a89d0
commit 542a031172
15 files changed
+614 -90

No files matched your search

+22 -2
View File
@@ -220,8 +220,28 @@ public static class ChatEndpoint
{
if (!string.IsNullOrEmpty(ctx.Provider))
{
// OpenAI-kompatibler Provider (z.B. Nvidia)
await openAi.StreamChat(res, ctx.ModelId, ctx.SystemPromptText, messages, ctx.ChainId, workspace: ctx.Workspace, sessionId: sessionId, agentId: ctx.AgentId, workCt: workCt, sseCt: sseCt);
// OpenAI-kompatibler Provider – für "openai" den User-Key aus DB verwenden
string openAiKeyOverride = null;
if (ctx.Provider == "openai")
{
// Zuerst prüfen ob der ausgewählte Key ein OpenAI-Key ist
if (userApiKey.Provider == "openai")
openAiKeyOverride = userApiKey.ApiKey;
else
{
// Fallback: ersten aktiven OpenAI-Key aus DB holen
openAiKeyOverride = await db.GetFirstActiveKeyByProvider("openai");
}
if (string.IsNullOrEmpty(openAiKeyOverride))
{
await SseHelper.TryWriteSse(res, "error", new { error = "Kein OpenAI API-Key vorhanden. Bitte einen OpenAI-Key in den API-Keys hinzufügen." }, sseCt);
await SseHelper.TryWriteSse(res, "done", new { chainId = ctx.ChainId }, sseCt);
return;
}
}
await openAi.StreamChat(res, ctx.ModelId, ctx.SystemPromptText, messages, ctx.ChainId, workspace: ctx.Workspace, sessionId: sessionId, agentId: ctx.AgentId, apiKeyOverride: openAiKeyOverride, workCt: workCt, sseCt: sseCt);
}
else
{