Testfundament aufbauen und Bestandsaufnahme dokumentieren

IChatCompletionClient aus OpenRouterClient extrahiert, damit AgentEngine und
ContextCompactor ohne echte API-Aufrufe testbar sind.

Neues Testprojekt tests/ClawdDotNet.Core.Tests (xUnit, Shouldly, NSubstitute,
FsCheck) mit:
- FakeChatClient (programmierbare Antwortfolgen, Deep-Copy der Requests)
- ContextInvariants (prueft die API-Regeln fuer tool_call-Paarung)
- Conversation-Builder fuer gueltige Testkonversationen
- 26 Tests: Compaction, LoopGuard, 2 Property-Tests

10 Tests sind bewusst rot — sie reproduzieren die Bugs B1, B3 und B14 aus der
Bestandsaufnahme und werden mit den Fixes gruen.

Ausserdem: fehlende Tool-Projekte in slnx ergaenzt, Test-Pakete im
packageSourceMapping der NuGet.Config eingetragen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-27 10:07:54 +02:00
co-authored by Claude Opus 4.8
parent 92e50d3ac4
commit 667cecce25
17 changed files with 1887 additions and 5 deletions
@@ -0,0 +1,12 @@
using ClawdDotNet.Core.Api.Models;
namespace ClawdDotNet.Core.Api;
/// <summary>
/// Abstraktion über den Chat-Completion-Endpunkt.
/// Erlaubt es, Engine und Compactor ohne echte API-Aufrufe zu testen.
/// </summary>
public interface IChatCompletionClient
{
Task<ChatResponse> CompleteAsync(ChatRequest request, CancellationToken ct);
}
+1 -1
View File
@@ -6,7 +6,7 @@ using Microsoft.Extensions.Logging;
namespace ClawdDotNet.Core.Api;
public sealed class OpenRouterClient : IDisposable
public sealed class OpenRouterClient : IChatCompletionClient, IDisposable
{
private const string BaseUrl = "https://openrouter.ai/api/v1/";
+2 -2
View File
@@ -12,7 +12,7 @@ namespace ClawdDotNet.Core.Engine;
public sealed class AgentEngine : IAgentMessageRouter
{
private readonly OpenRouterClient _client;
private readonly IChatCompletionClient _client;
private readonly ToolRegistry _toolRegistry;
private readonly PermissionGate _permissionGate;
private readonly IStateStore _stateStore;
@@ -35,7 +35,7 @@ public sealed class AgentEngine : IAgentMessageRouter
};
public AgentEngine(
OpenRouterClient client,
IChatCompletionClient client,
ToolRegistry toolRegistry,
PermissionGate permissionGate,
IStateStore stateStore,
@@ -7,14 +7,14 @@ namespace ClawdDotNet.Core.Engine;
public sealed class ContextCompactor
{
private readonly OpenRouterClient _client;
private readonly IChatCompletionClient _client;
private readonly ILogger _logger;
private const int ProtectedTailMessages = 6;
private const int MaxToolResultChars = 2000;
private const string TruncatedMarker = "\n\n[... Ergebnis gekürzt ...]";
public ContextCompactor(OpenRouterClient client, ILoggerFactory loggerFactory)
public ContextCompactor(IChatCompletionClient client, ILoggerFactory loggerFactory)
{
_client = client;
_logger = loggerFactory.CreateLogger("ClawdDotNet.Core.Engine.ContextCompactor");