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
@@ -10,7 +10,7 @@ public sealed class ChatMessageSerializationTests
|
||||
private static ChatMessage Deserialize(string json) => JsonSerializer.Deserialize<ChatMessage>(json)!;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Standardformat
|
||||
// Standard format
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
[Fact]
|
||||
@@ -78,7 +78,7 @@ public sealed class ChatMessageSerializationTests
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Deserialisierung: beide Formate
|
||||
// Deserialization: both formats
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
[Fact]
|
||||
@@ -93,7 +93,7 @@ public sealed class ChatMessageSerializationTests
|
||||
[Fact]
|
||||
public void Inhalt_als_Blockarray_wird_gelesen()
|
||||
{
|
||||
// So sieht ein persistierter Kontext aus, der mit Breakpoint geschrieben wurde.
|
||||
// This is what a persisted context written with a breakpoint looks like.
|
||||
var msg = Deserialize(
|
||||
"""{"role":"system","content":[{"type":"text","text":"Prompt","cache_control":{"type":"ephemeral"}}]}""");
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ using Shouldly;
|
||||
namespace ClawdDotNet.Core.Tests.Api;
|
||||
|
||||
/// <summary>
|
||||
/// B4, zweiter Teil: Die Preise standen fest im Code, waren veraltet, und ausgerechnet
|
||||
/// das Standardmodell der Agenten fehlte. CalculateCost gab dafür stillschweigend 0
|
||||
/// zurück — die Anzeige meldete also 0 €, während echte Kosten anfielen.
|
||||
/// B4, second part: the prices were hard-coded, outdated, and of all things
|
||||
/// the agents' default model was missing. CalculateCost silently returned 0 for it
|
||||
/// — the display thus reported 0 € while real costs were incurred.
|
||||
/// </summary>
|
||||
public sealed class ModelPricingTests
|
||||
{
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Umrechnung der OpenRouter-Angaben
|
||||
// Conversion of the OpenRouter figures
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
[Theory]
|
||||
@@ -39,7 +39,7 @@ public sealed class ModelPricingTests
|
||||
[Fact]
|
||||
public void Die_Umrechnung_ist_unabhaengig_von_der_Systemsprache()
|
||||
{
|
||||
// Mit deutscher Kultur würde "0.000003" sonst als 3 statt als 0,000003 gelesen.
|
||||
// With German culture "0.000003" would otherwise be read as 3 instead of 0.000003.
|
||||
var original = Thread.CurrentThread.CurrentCulture;
|
||||
try
|
||||
{
|
||||
@@ -53,7 +53,7 @@ public sealed class ModelPricingTests
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Auslesen aus der API-Antwort
|
||||
// Reading from the API response
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
[Fact]
|
||||
@@ -78,13 +78,13 @@ public sealed class ModelPricingTests
|
||||
[InlineData("""{ "id": "x", "pricing": "kostenlos" }""")]
|
||||
public void Unvollstaendige_Preisangaben_ergeben_null(string json)
|
||||
{
|
||||
// Halbe Angaben sind schlimmer als keine — sie ergäben eine plausibel
|
||||
// aussehende, aber falsche Summe.
|
||||
// Half the information is worse than none — it would result in a plausible-looking
|
||||
// but wrong sum.
|
||||
OpenRouterClient.ReadPricing(JsonDocument.Parse(json).RootElement).ShouldBeNull();
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Katalog und Kostenschätzung
|
||||
// Catalog and cost estimate
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
private static ModelPricingCatalog CatalogWith(params (string Id, decimal In, decimal Out)[] models)
|
||||
@@ -104,7 +104,7 @@ public sealed class ModelPricingTests
|
||||
{
|
||||
var catalog = CatalogWith(("anthropic/claude-sonnet-4-5", 3m, 15m));
|
||||
|
||||
// 95.000 Eingabe + 5.000 Ausgabe = 0,285 + 0,075 = 0,36 $
|
||||
// 95,000 input + 5,000 output = 0.285 + 0.075 = 0.36 $
|
||||
var estimate = catalog.Estimate("anthropic/claude-sonnet-4-5", 95_000, 5_000);
|
||||
|
||||
estimate.IsKnown.ShouldBeTrue();
|
||||
@@ -114,7 +114,7 @@ public sealed class ModelPricingTests
|
||||
[Fact]
|
||||
public void Ein_unbekanntes_Modell_wird_als_unbekannt_gemeldet_statt_als_null_Kosten()
|
||||
{
|
||||
// Der Kern des alten Fehlers: 0 sah aus wie kostenlos.
|
||||
// The core of the old error: 0 looked like free.
|
||||
var catalog = CatalogWith(("openai/gpt-4o", 2.5m, 10m));
|
||||
|
||||
var estimate = catalog.Estimate("anthropic/claude-sonnet-4-5", 100_000, 5_000);
|
||||
|
||||
@@ -8,9 +8,9 @@ using Shouldly;
|
||||
namespace ClawdDotNet.Core.Tests.Api;
|
||||
|
||||
/// <summary>
|
||||
/// B12 aus der Bestandsaufnahme: Der Client warf bei jedem Nicht-2xx sofort. Ein
|
||||
/// einzelnes HTTP 429 beendete damit einen kompletten geplanten Lauf, obwohl
|
||||
/// Rate-Limits und kurze 5xx bei OpenRouter Normalbetrieb sind.
|
||||
/// B12 from the inventory: the client threw immediately on every non-2xx. A
|
||||
/// single HTTP 429 thus ended a complete scheduled run, although
|
||||
/// rate limits and brief 5xx are normal operation at OpenRouter.
|
||||
/// </summary>
|
||||
public sealed class RetryPolicyTests
|
||||
{
|
||||
@@ -28,8 +28,8 @@ public sealed class RetryPolicyTests
|
||||
[InlineData(HttpStatusCode.Conflict, false)]
|
||||
public void Nur_voruebergehende_Stoerungen_werden_wiederholt(HttpStatusCode status, bool expected)
|
||||
{
|
||||
// Ein 400 oder 401 wiederholt sich nicht von selbst — dafür zu warten
|
||||
// verzögert nur die Fehlermeldung.
|
||||
// A 400 or 401 does not repeat itself by itself — waiting for it
|
||||
// only delays the error message.
|
||||
RetryPolicy.Default.ShouldRetry(status).ShouldBe(expected);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public sealed class RetryPolicyTests
|
||||
[Fact]
|
||||
public void Auch_ein_RetryAfter_wird_gedeckelt()
|
||||
{
|
||||
// Ein Server könnte Stunden verlangen — so lange darf kein Lauf blockieren.
|
||||
// A server could demand hours — no run may block that long.
|
||||
var policy = new RetryPolicy { MaxDelay = TimeSpan.FromSeconds(30) };
|
||||
|
||||
policy.GetDelay(1, TimeSpan.FromHours(1)).ShouldBe(TimeSpan.FromSeconds(30));
|
||||
@@ -99,7 +99,7 @@ public sealed class OpenRouterClientRetryTests
|
||||
private const string SuccessBody =
|
||||
"""{"id":"x","choices":[{"index":0,"message":{"role":"assistant","content":"Hi"}}]}""";
|
||||
|
||||
/// <summary>Wartet nicht wirklich — sonst dauerte die Suite Sekunden.</summary>
|
||||
/// <summary>Does not really wait — otherwise the suite would take seconds.</summary>
|
||||
private static Task NoWait(TimeSpan _, CancellationToken __) => Task.CompletedTask;
|
||||
|
||||
private static OpenRouterClient CreateClient(FakeHttpMessageHandler handler, RetryPolicy? policy = null)
|
||||
@@ -159,7 +159,7 @@ public sealed class OpenRouterClientRetryTests
|
||||
[Fact]
|
||||
public async Task Ein_dauerhafter_Fehler_wird_nicht_wiederholt()
|
||||
{
|
||||
// Ein 401 wird durch Warten nicht besser — sofort melden.
|
||||
// A 401 does not get better by waiting — report immediately.
|
||||
var handler = new FakeHttpMessageHandler()
|
||||
.Responds(HttpStatusCode.Unauthorized, """{"error":"invalid key"}""");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user