Refactoring + Dokumentation: api.js komprimiert (745→267 Zeilen), SseHelper extrahiert, DatabaseService in Partial Classes aufgeteilt, unbenutztes CSS entfernt, ARCHITECTURE.md/ARCHITECTURE_QUICK.md/README.md aktualisiert (neue Features: Embedding, Remote, API-Keys, 16 Tools)
This commit is contained in:
1 parent
8dc52c1337
commit
db1a7c7f64
18 files changed
+1701
-2007
No files matched your search
@@ -0,0 +1,85 @@
|
||||
using System.Diagnostics;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Gott.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Gott.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Shared SSE-Streaming-Utilities für AnthropicService und OpenAiService.
|
||||
/// </summary>
|
||||
public static class SseHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Schreibt ein SSE-Event (wirft bei CancellationToken).
|
||||
/// </summary>
|
||||
public static async Task WriteSseEvent(HttpResponse response, string eventType, object data, CancellationToken ct = default)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
var json = JsonSerializer.Serialize(data);
|
||||
await response.WriteAsync($"event: {eventType}\ndata: {json}\n\n", ct);
|
||||
await response.Body.FlushAsync(ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Versucht ein SSE-Event zu schreiben, ignoriert Fehler (Client disconnected).
|
||||
/// </summary>
|
||||
public static async Task TryWriteSse(HttpResponse response, string eventType, object data, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ct.IsCancellationRequested)
|
||||
await WriteSseEvent(response, eventType, data, ct);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Client bereits disconnected – ignorieren
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalisiert eine Chain in der Datenbank (Token-Counts, Stopgrund, Dauer).
|
||||
/// </summary>
|
||||
public static async Task FinalizeChain(DatabaseService db, ChainRecord chain, TokenUsage usage, int iterations, string stopReason, Stopwatch sw, string streamErrorInfo = null)
|
||||
{
|
||||
chain.InputTokens = usage.InputTokens;
|
||||
chain.OutputTokens = usage.OutputTokens;
|
||||
chain.CacheCreationTokens = usage.CacheCreationTokens;
|
||||
chain.CacheReadTokens = usage.CacheReadTokens;
|
||||
chain.Iterations = iterations;
|
||||
chain.StopReason = stopReason;
|
||||
chain.StreamErrorInfo = streamErrorInfo;
|
||||
chain.DurationMs = sw.ElapsedMilliseconds;
|
||||
await db.UpdateChain(chain);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kürzt Tool-Results auf max. Zeichenzahl.
|
||||
/// </summary>
|
||||
public const int MaxToolResultChars = 20_000;
|
||||
|
||||
public static string TruncateToolResult(string result)
|
||||
{
|
||||
return result.Length > MaxToolResultChars
|
||||
? result[..MaxToolResultChars] + $"\n\n[... gekürzt, {result.Length - MaxToolResultChars} weitere Zeichen ...]"
|
||||
: result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Token-Zähler für eine Chat-Session (Input, Output, Cache).
|
||||
/// </summary>
|
||||
public class TokenUsage
|
||||
{
|
||||
public long InputTokens { get; set; }
|
||||
public long OutputTokens { get; set; }
|
||||
public long CacheCreationTokens { get; set; }
|
||||
public long CacheReadTokens { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ergebnis einer Tool-Ausführung.
|
||||
/// </summary>
|
||||
public record ToolResult(string Id, string Result, bool IsError);
|
||||
Reference in new issue
Block a user