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
@@ -4,14 +4,14 @@ using ClawdDotNet.Core.Api.Models;
|
||||
namespace ClawdDotNet.Core.Tests.Infrastructure;
|
||||
|
||||
/// <summary>
|
||||
/// Prüft, ob eine Nachrichtenfolge von der Chat-Completions-API akzeptiert würde.
|
||||
/// Checks whether a message sequence would be accepted by the chat completions API.
|
||||
///
|
||||
/// Die Regeln entsprechen dem, was OpenRouter/Anthropic/OpenAI verlangen:
|
||||
/// Eine tool-Antwort ist nur gültig, wenn ihr eine assistant-Nachricht mit einem
|
||||
/// passenden tool_call vorausgeht — und jeder tool_call braucht seine Antwort.
|
||||
/// The rules correspond to what OpenRouter/Anthropic/OpenAI demand:
|
||||
/// a tool answer is only valid if it is preceded by an assistant message with a
|
||||
/// matching tool_call — and every tool_call needs its answer.
|
||||
///
|
||||
/// Wird eine Regel verletzt, antwortet die API mit HTTP 400 und der laufende
|
||||
/// Agent bricht ab. Genau das ist Bug B1 aus der Bestandsaufnahme.
|
||||
/// If a rule is violated, the API answers with HTTP 400 and the running
|
||||
/// agent aborts. That is exactly bug B1 from the inventory.
|
||||
/// </summary>
|
||||
internal static class ContextInvariants
|
||||
{
|
||||
@@ -37,22 +37,22 @@ internal static class ContextInvariants
|
||||
|
||||
private static IEnumerable<string> Validate(IReadOnlyList<ChatMessage> messages)
|
||||
{
|
||||
// ── Regel 1: höchstens eine system-Nachricht, und zwar ganz vorne ──
|
||||
// ── Rule 1: at most one system message, and at the very front ──
|
||||
for (var i = 1; i < messages.Count; i++)
|
||||
{
|
||||
if (messages[i].Role == "system")
|
||||
yield return $"[{i}] system-Nachricht steht nicht an Position 0";
|
||||
}
|
||||
|
||||
// ── Regel 2: jede tool-Nachricht braucht eine ToolCallId ──
|
||||
// ── Rule 2: every tool message needs a ToolCallId ──
|
||||
for (var i = 0; i < messages.Count; i++)
|
||||
{
|
||||
if (messages[i].Role == "tool" && string.IsNullOrEmpty(messages[i].ToolCallId))
|
||||
yield return $"[{i}] tool-Nachricht ohne tool_call_id";
|
||||
}
|
||||
|
||||
// ── Regel 3: jede tool-Nachricht gehört zum unmittelbar vorausgehenden
|
||||
// assistant-Block mit passender tool_call-Id ──
|
||||
// ── Rule 3: every tool message belongs to the immediately preceding
|
||||
// assistant block with a matching tool_call ID ──
|
||||
var openCalls = new HashSet<string>();
|
||||
var answered = new HashSet<string>();
|
||||
|
||||
@@ -62,7 +62,7 @@ internal static class ContextInvariants
|
||||
|
||||
if (msg.Role == "assistant" && msg.ToolCalls is { Count: > 0 })
|
||||
{
|
||||
// Vorheriger Block muss vollständig beantwortet sein
|
||||
// The previous block must be completely answered
|
||||
var unanswered = openCalls.Except(answered).ToList();
|
||||
if (unanswered.Count > 0)
|
||||
yield return $"[{i}] neuer assistant-Block, aber tool_call(s) noch unbeantwortet: {string.Join(", ", unanswered)}";
|
||||
@@ -87,7 +87,7 @@ internal static class ContextInvariants
|
||||
}
|
||||
else
|
||||
{
|
||||
// user/system/assistant-ohne-tool_calls beenden den Block
|
||||
// user/system/assistant-without-tool_calls end the block
|
||||
var unanswered = openCalls.Except(answered).ToList();
|
||||
if (unanswered.Count > 0)
|
||||
yield return $"[{i}] {msg.Role}-Nachricht, aber tool_call(s) unbeantwortet: {string.Join(", ", unanswered)}";
|
||||
@@ -97,13 +97,13 @@ internal static class ContextInvariants
|
||||
}
|
||||
}
|
||||
|
||||
// ── Regel 4: am Ende darf kein tool_call offen sein ──
|
||||
// ── Rule 4: no tool_call may be open at the end ──
|
||||
var stillOpen = openCalls.Except(answered).ToList();
|
||||
if (stillOpen.Count > 0)
|
||||
yield return $"[Ende] unbeantwortete tool_call(s): {string.Join(", ", stillOpen)}";
|
||||
}
|
||||
|
||||
/// <summary>Kompakte, lesbare Darstellung für Fehlermeldungen.</summary>
|
||||
/// <summary>Compact, readable representation for error messages.</summary>
|
||||
public static string Describe(IReadOnlyList<ChatMessage> messages)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
Reference in New Issue
Block a user