Stufe 4c (#764): Kommentare in C#, WebUI-Skripten, CSS und HTML auf Englisch
Rund 2.600 Kommentarblöcke in 310 C#-Dateien übersetzt, Begründungen vollständig erhalten: blockweise gleiche Anzahl wie vorher, kein Block unter 60 % seiner Länge, der Code außerhalb der Kommentare per Tokenizer byte-identisch geprüft. Zitate deutscher Oberflächentexte und Testdaten bleiben deutsch. WebUI: Kommentare in JS/CSS/HTML übersetzt, JSDoc-@param an die in 4b umbenannten Parameter angeglichen. Dabei behoben: - 4b hatte "tag" (HTML-Tag) als deutsches "Tag" gelesen und zu "dayValue" gemacht (makeElement, svg, Tagesübersicht) - zurück auf tag/day. - Aufgaben "InProgress" bekamen die Plakettenart "laufend", für die es nie eine CSS-Klasse gab - jetzt "success" wie laufende Instanzen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
da4ceac7d5
commit
837a634a22
@@ -15,32 +15,32 @@ public sealed class ChatMessage
|
||||
public string? ToolCallId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Setzt einen Prompt-Caching-Breakpoint auf diese Nachricht.
|
||||
/// Sets a prompt caching breakpoint on this message.
|
||||
///
|
||||
/// Alles, was im Prompt VOR dem Breakpoint steht (Tool-Definitionen, System-Prompt,
|
||||
/// vorherige Nachrichten), wird beim nächsten Aufruf aus dem Cache gelesen und
|
||||
/// kostet nur einen Bruchteil. Der Inhalt wird dann als Block-Array statt als
|
||||
/// einfacher String serialisiert.
|
||||
/// Everything in the prompt BEFORE the breakpoint (tool definitions, system prompt,
|
||||
/// previous messages) is read from the cache on the next call and
|
||||
/// costs only a fraction. The content is then serialized as a block array instead of a
|
||||
/// plain string.
|
||||
///
|
||||
/// Wichtig: Der Prompt-Abschnitt vor dem Breakpoint muss zwischen zwei Aufrufen
|
||||
/// zeichengenau identisch sein, sonst greift der Cache nicht.
|
||||
/// Important: the prompt section before the breakpoint must be identical to the character
|
||||
/// between two calls, otherwise the cache does not apply.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public bool CacheBreakpoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Der Denkverlauf als Klartext, so wie der Anbieter ihn geliefert hat.
|
||||
/// The reasoning as plain text, as the provider delivered it.
|
||||
/// </summary>
|
||||
public string? Reasoning { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Der strukturierte Denkverlauf, unverändert.
|
||||
/// The structured reasoning, unchanged.
|
||||
///
|
||||
/// Wird bei Werkzeugnutzung in der folgenden Anfrage zurückgeschickt: Das Modell
|
||||
/// setzt seine begonnene Antwort fort, statt eine neue zu beginnen. Die Abfolge
|
||||
/// muss dabei genau der gelieferten entsprechen — umstellen oder verändern macht
|
||||
/// sie unbrauchbar, und bei signierten Formaten kann der Anbieter sie dann nicht
|
||||
/// mehr zuordnen. Deshalb wird hier rohes JSON gehalten und nichts ausgelegt.
|
||||
/// With tool use it is sent back in the following request: the model
|
||||
/// continues its started answer instead of beginning a new one. The sequence
|
||||
/// must correspond exactly to the delivered one — reordering or changing it makes
|
||||
/// it unusable, and with signed formats the provider can then no longer
|
||||
/// match it. That's why raw JSON is held here and nothing is interpreted.
|
||||
/// </summary>
|
||||
public JsonElement? ReasoningDetails { get; set; }
|
||||
|
||||
@@ -49,12 +49,12 @@ public sealed class ChatMessage
|
||||
public static ChatMessage Assistant(string content) => new() { Role = "assistant", Content = content };
|
||||
|
||||
/// <summary>
|
||||
/// Baut die assistant-Nachricht für einen Zug mit Werkzeugaufrufen.
|
||||
/// Builds the assistant message for a turn with tool calls.
|
||||
///
|
||||
/// <paramref name="content"/> ist der Text, den das Modell neben die Aufrufe
|
||||
/// geschrieben hat („Ich sehe zuerst in der Konfiguration nach"). Er gehört in den
|
||||
/// Verlauf: Ohne ihn verliert das Modell im nächsten Schritt seinen eigenen Plan,
|
||||
/// und im Audit steht, <i>dass</i> ein Werkzeug lief, nicht <i>warum</i>.
|
||||
/// <paramref name="content"/> is the text the model wrote next to the calls
|
||||
/// ("I'll look in the configuration first"). It belongs in the
|
||||
/// history: without it the model loses its own plan in the next step,
|
||||
/// and the audit says <i>that</i> a tool ran, not <i>why</i>.
|
||||
/// </summary>
|
||||
public static ChatMessage AssistantWithToolCalls(
|
||||
List<ToolCall> toolCalls,
|
||||
@@ -78,13 +78,12 @@ public sealed class ChatMessage
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialisiert <see cref="ChatMessage"/>. Der Inhalt geht normalerweise als einfacher
|
||||
/// String raus; ist ein <see cref="ChatMessage.CacheBreakpoint"/> gesetzt, stattdessen
|
||||
/// als Block-Array mit cache_control — das Format, das Anbieter für Prompt-Caching
|
||||
/// erwarten.
|
||||
/// Serializes <see cref="ChatMessage"/>. The content normally goes out as a plain
|
||||
/// string; if a <see cref="ChatMessage.CacheBreakpoint"/> is set, instead
|
||||
/// as a block array with cache_control — the format providers expect for prompt caching.
|
||||
///
|
||||
/// Beim Lesen werden beide Formate akzeptiert: Antworten liefern den Inhalt als String,
|
||||
/// gespeicherte Kontexte können ihn als Array enthalten.
|
||||
/// When reading, both formats are accepted: responses deliver the content as a string,
|
||||
/// stored contexts may contain it as an array.
|
||||
/// </summary>
|
||||
public sealed class ChatMessageConverter : JsonConverter<ChatMessage>
|
||||
{
|
||||
@@ -126,8 +125,8 @@ public sealed class ChatMessageConverter : JsonConverter<ChatMessage>
|
||||
message.ToolCallId = reader.GetString();
|
||||
break;
|
||||
|
||||
// Der Denkverlauf wird durchgereicht, nicht ausgelegt. "reasoning_content"
|
||||
// ist derselbe Inhalt unter anderem Namen; wer zuerst kommt, gewinnt.
|
||||
// The reasoning is passed through, not interpreted. "reasoning_content"
|
||||
// is the same content under a different name; whichever comes first wins.
|
||||
case "reasoning":
|
||||
case "reasoning_content":
|
||||
message.Reasoning ??= reader.TokenType == JsonTokenType.String
|
||||
@@ -138,7 +137,7 @@ public sealed class ChatMessageConverter : JsonConverter<ChatMessage>
|
||||
break;
|
||||
|
||||
case "reasoning_details":
|
||||
// Clone(), weil der Reader nach dieser Schleife nicht mehr gilt.
|
||||
// Clone(), because the reader is no longer valid after this loop.
|
||||
message.ReasoningDetails = reader.TokenType == JsonTokenType.Null
|
||||
? null
|
||||
: JsonDocument.ParseValue(ref reader).RootElement.Clone();
|
||||
@@ -153,7 +152,7 @@ public sealed class ChatMessageConverter : JsonConverter<ChatMessage>
|
||||
throw new JsonException("ChatMessage: unerwartetes Ende.");
|
||||
}
|
||||
|
||||
/// <summary>Nimmt den Inhalt als String oder als Block-Array entgegen.</summary>
|
||||
/// <summary>Accepts the content as a string or as a block array.</summary>
|
||||
private static string? ReadContent(ref Utf8JsonReader reader)
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.Null)
|
||||
@@ -168,7 +167,7 @@ public sealed class ChatMessageConverter : JsonConverter<ChatMessage>
|
||||
return null;
|
||||
}
|
||||
|
||||
// Block-Array: die text-Anteile zusammenführen.
|
||||
// Block array: join the text parts.
|
||||
var parts = new List<string>();
|
||||
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
|
||||
{
|
||||
@@ -224,8 +223,8 @@ public sealed class ChatMessageConverter : JsonConverter<ChatMessage>
|
||||
if (value.ToolCallId is not null)
|
||||
writer.WriteString("tool_call_id", value.ToolCallId);
|
||||
|
||||
// Unverändert zurück. Das strukturierte Feld hat Vorrang, weil nur es Signatur
|
||||
// und Reihenfolge trägt; der Klartext geht mit, wenn es keines gibt.
|
||||
// Back unchanged. The structured field takes precedence because only it carries signature
|
||||
// and order; the plain text goes along if there is none.
|
||||
if (value.ReasoningDetails is { } details)
|
||||
{
|
||||
writer.WritePropertyName("reasoning_details");
|
||||
|
||||
Reference in New Issue
Block a user