Prompt history: every run records its transcript (task, each model step with tokens and cost, tool calls and results, engine follow-ups) - bounded in size, scrubbed of recognisable secrets, system prompts stored once per text. Retention in days per instance (default 14) and per agent (0 = never, -1 = forever); an hourly janitor deletes what is past it, "never" also purges. Usage analysis over run receipts: filter by period, agent, model, event, status, cost and free text; sort by every column; totals over the whole filter; hourly or daily series grouped by agent, model or event; markers for budget denials and model changes; run detail with receipt, transcript, tool calls and approvals. WebUI: Analysis > Token usage > Runs / Timeline, run detail, Prompt History with retention settings. New code, comments and texts in English; texts come from language packs (i18n/en.json, de.json) via modules/i18n.js. CLAUDE.md records English as the main language. Version 0.1.12. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
79 lines
2.4 KiB
C#
79 lines
2.4 KiB
C#
using ClawdDotNet.Core.Accounting;
|
|
using ClawdDotNet.Core.Audit;
|
|
using ClawdDotNet.Core.Config;
|
|
using ClawdDotNet.Core.Engine;
|
|
using ClawdDotNet.Core.Security;
|
|
using ClawdDotNet.Core.Staging;
|
|
using ClawdDotNet.Core.Tools;
|
|
|
|
namespace ClawdDotNet.Core.Tests.Infrastructure;
|
|
|
|
/// <summary>
|
|
/// Baut eine einsatzbereite AgentEngine mit Fake-Client, Fake-Tools und
|
|
/// In-Memory-State zusammen.
|
|
/// </summary>
|
|
internal sealed class EngineFixture
|
|
{
|
|
public FakeChatClient Client { get; } = new();
|
|
public ToolRegistry Registry { get; } = new();
|
|
public InMemoryStateStore StateStore { get; } = new();
|
|
public AgentEngine Engine { get; }
|
|
|
|
private readonly List<AgentConfig> _agents = new();
|
|
|
|
/// <summary>Die registrierten Agenten — für Tests, die einen Dispatcher selbst bauen.</summary>
|
|
public IReadOnlyList<AgentConfig> Agents => _agents;
|
|
|
|
public EngineFixture(
|
|
IAuditRepository? audit = null, StagingGate? staging = null, TimeProvider? clock = null,
|
|
IUsageRepository? usage = null, Core.Transcripts.IRunTranscriptStore? transcripts = null)
|
|
{
|
|
Engine = new AgentEngine(
|
|
Client,
|
|
Registry,
|
|
new PermissionGate(),
|
|
StateStore,
|
|
TestLogging.Factory,
|
|
usageRepository: usage,
|
|
auditRepository: audit,
|
|
stagingGate: staging,
|
|
clock: clock)
|
|
{
|
|
TranscriptStore = transcripts
|
|
};
|
|
|
|
// Kein Agent-Verzeichnis → keine Persistenz auf die Platte während der Tests.
|
|
Engine.SetAgentConfigProvider(() => _agents, "test-instance", _ => null);
|
|
}
|
|
|
|
public EngineFixture WithTool(IAgentTool tool)
|
|
{
|
|
Registry.Register(tool);
|
|
return this;
|
|
}
|
|
|
|
public AgentConfig AddAgent(string agentId, params string[] toolNames)
|
|
{
|
|
var config = new AgentConfig
|
|
{
|
|
AgentId = agentId,
|
|
DisplayName = agentId,
|
|
Model = "test/model",
|
|
SystemPrompt = $"Du bist {agentId}.",
|
|
LoopGuard = new LoopGuardConfig
|
|
{
|
|
MaxSteps = 50,
|
|
MaxCumulativeTokens = 10_000_000,
|
|
TimeoutSeconds = 60,
|
|
MaxContextTokens = 10_000_000 // Compaction in Engine-Tests ausschalten
|
|
}
|
|
};
|
|
|
|
foreach (var name in toolNames)
|
|
config.Tools[name] = new Dictionary<string, object?>();
|
|
|
|
_agents.Add(config);
|
|
return config;
|
|
}
|
|
}
|