feat: Claude CLI Pfad mit ask_user_choice, Plan-Modus und Tool-Konfiguration
- ClaudeCliService: Marker-basierte ask_user_choice Erkennung im Stream-Parser - AnthropicService: StreamChatViaCli mit allowUserChoice, planMode, webSearch - BuildHistoryContext erweitert für tool_use/tool_result (Choice-Antworten) - Tool-Use Records werden in DB persistiert (Poll-Kompatibilität) - CLI Tools konfigurierbar: Workspace/Plan-Modus/WebSearch/kein Workspace - OAuth DB-Felder für zukünftige Token-Verwaltung Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
8150b58110
commit
4af9430466
7 files changed
+1039
-3
No files matched your search
@@ -563,4 +563,61 @@ public partial class DatabaseService
|
||||
$"SELECT COUNT(*) FROM scanner_logs {where}",
|
||||
new { type, scanner });
|
||||
}
|
||||
|
||||
// ── OAuth Tokens ──
|
||||
|
||||
/// <summary>
|
||||
/// Erstellt einen neuen API-Key-Eintrag für OAuth-Tokens.
|
||||
/// </summary>
|
||||
public async Task<string> CreateOAuthApiKey(string provider, string name, string accessToken, string refreshToken, DateTime expiresAt, string oauthProvider)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var keyId = Guid.NewGuid().ToString("N");
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(@"
|
||||
INSERT INTO api_keys (key_id, provider, name, api_key, is_public, status, plan, refresh_token, access_token_expires_at, oauth_provider, created_at, updated_at)
|
||||
VALUES (@keyId, @provider, @name, @accessToken, 0, 'valid', NULL, @refreshToken, @expiresAt, @oauthProvider, @now, @now)",
|
||||
new { keyId, provider, name, accessToken, refreshToken, expiresAt = expiresAt.ToString("o"), oauthProvider, now });
|
||||
return keyId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aktualisiert Access-Token und Ablaufzeit eines OAuth-Keys.
|
||||
/// </summary>
|
||||
public async Task UpdateOAuthTokens(string keyId, string newAccessToken, DateTime newExpiresAt)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(@"
|
||||
UPDATE api_keys SET api_key = @newAccessToken, access_token_expires_at = @expiresAt, updated_at = @now
|
||||
WHERE key_id = @keyId",
|
||||
new { keyId, newAccessToken, expiresAt = newExpiresAt.ToString("o"), now });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holt alle OAuth-Keys die bald ablaufen (innerhalb von refreshBeforeMinutes).
|
||||
/// </summary>
|
||||
public async Task<IEnumerable<ApiKeyRecord>> GetOAuthKeysNeedingRefresh(int refreshBeforeMinutes = 60)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var threshold = DateTime.UtcNow.AddMinutes(refreshBeforeMinutes).ToString("o");
|
||||
return await conn.QueryAsync<ApiKeyRecord>(@"
|
||||
SELECT * FROM api_keys
|
||||
WHERE refresh_token IS NOT NULL AND refresh_token != ''
|
||||
AND access_token_expires_at IS NOT NULL AND access_token_expires_at != ''
|
||||
AND access_token_expires_at < @threshold",
|
||||
new { threshold });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setzt den Status eines API-Keys auf "expired".
|
||||
/// </summary>
|
||||
public async Task SetApiKeyExpired(string keyId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(
|
||||
"UPDATE api_keys SET status = 'expired', updated_at = @now WHERE key_id = @keyId",
|
||||
new { keyId, now });
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user