User-spezifische API-Key-Auswahl, globales is_active entfernt
Backend:
- is_active komplett entfernt, durch is_public (Admin-Toggle) ersetzt
- Neues selected_api_key_id auf users-Tabelle
- AnthropicService: globaler _token entfernt, apiToken pro Request
- Token-Durchreichung: StreamChat → ProcessStream → RunAgentChat →
RunPreparer/RunReview/RunFinalizer, ExecuteTool, send_to_session
- ChatEndpoint: User-Key aus DB laden, an StreamChat übergeben
- TelegramService: Key per bot.UserId auflösen
- CronjobService: Key per job.UserId auflösen
- Neue Endpoints: GET /api/api-keys/available, PUT /api/api-keys/select/{keyId},
GET /api/api-keys/selected, PUT /api/admin/api-keys/{keyId}/public,
POST /api/admin/api-keys/check-all
- Program.cs: AnthropicService ohne Token-Parameter
Frontend:
- API-Keys-Page: Public-Toggle (Globe/Lock) statt Activate/Deactivate
- Alle prüfen Button für Batch-Key-Check
- Chat: Key-Auswahl für alle User (nicht nur Admin)
- Dummy-Badge wenn kein Key ausgewählt
- Fallback-Badge bei Key ohne Usage-Daten
- Key-Switch-Modal: apiGetAvailableKeys + apiSelectApiKey
This commit is contained in:
1 parent
cc46cf2bbc
commit
dde0fede7d
18 files changed
+340
-193
No files matched your search
@@ -51,6 +51,16 @@ public static class ChatEndpoint
|
||||
}
|
||||
|
||||
var userId = req.HttpContext.GetUserId();
|
||||
|
||||
// API-Key des Users auflösen
|
||||
var userApiKey = await db.GetUserSelectedApiKey(userId);
|
||||
if (userApiKey == null)
|
||||
{
|
||||
res.StatusCode = 400;
|
||||
await res.WriteAsJsonAsync(new { error = "Kein API-Key ausgewählt. Bitte wähle einen Key aus." });
|
||||
return;
|
||||
}
|
||||
|
||||
var maxIterations = config.GetValue<int>("MaxIterations", 100);
|
||||
|
||||
var hasRemote = remoteMgr.GetBySessionId(sessionId) != null;
|
||||
@@ -142,7 +152,7 @@ public static class ChatEndpoint
|
||||
var preparerHistory = await chatService.BuildHistoryFromDb(sessionId, includeTag: "preparer", promptBlocks: ctx.PromptBlocks);
|
||||
|
||||
var preparerResult = await anthropic.RunPreparer(
|
||||
res, ctx.Preparer, preparerHistory, ctx.ChainId, ctx.Workspace, sessionId, cancellationToken);
|
||||
res, ctx.Preparer, preparerHistory, ctx.ChainId, ctx.Workspace, sessionId, userApiKey.ApiKey, cancellationToken);
|
||||
|
||||
if (!preparerResult.ShouldForward)
|
||||
{
|
||||
@@ -216,7 +226,7 @@ public static class ChatEndpoint
|
||||
else
|
||||
{
|
||||
// Standard: Anthropic
|
||||
await anthropic.StreamChat(res, ctx.ModelId, ctx.SystemPrompt, messages, ctx.ChainId, ctx.Workspace, sessionId, agentId: ctx.AgentId, userId: userId, useMemory: ctx.UseMemory, webSearchVersion: ctx.WebSearchVersion, maxIterations: ctx.MaxIterations, toolChoice: effectiveToolChoice, review: ctx.Review, finalizer: ctx.Finalizer, allowUserChoice: ctx.Agent?.AllowUserChoice ?? true, planMode: ctx.PlanMode, useAutoContext: ctx.Agent?.UseAutoContext ?? true, useGitHubSearch: ctx.Agent?.UseGitHubSearch ?? false, useSerperSearch: ctx.Agent?.UseSerperSearch ?? false, workCt: workCt, hardCt: hardCt, sseCt: sseCt, remoteMgr: remoteMgr);
|
||||
await anthropic.StreamChat(res, ctx.ModelId, ctx.SystemPrompt, messages, ctx.ChainId, ctx.Workspace, apiToken: userApiKey.ApiKey, sessionId: sessionId, agentId: ctx.AgentId, userId: userId, useMemory: ctx.UseMemory, webSearchVersion: ctx.WebSearchVersion, maxIterations: ctx.MaxIterations, toolChoice: effectiveToolChoice, review: ctx.Review, finalizer: ctx.Finalizer, allowUserChoice: ctx.Agent?.AllowUserChoice ?? true, planMode: ctx.PlanMode, useAutoContext: ctx.Agent?.UseAutoContext ?? true, useGitHubSearch: ctx.Agent?.UseGitHubSearch ?? false, useSerperSearch: ctx.Agent?.UseSerperSearch ?? false, workCt: workCt, hardCt: hardCt, sseCt: sseCt, remoteMgr: remoteMgr);
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
||||
Reference in new issue
Block a user