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>
This commit is contained in:
@@ -26,7 +26,7 @@ internal sealed class EngineFixture
|
||||
|
||||
public EngineFixture(
|
||||
IAuditRepository? audit = null, StagingGate? staging = null, TimeProvider? clock = null,
|
||||
IUsageRepository? usage = null)
|
||||
IUsageRepository? usage = null, Core.Transcripts.IRunTranscriptStore? transcripts = null)
|
||||
{
|
||||
Engine = new AgentEngine(
|
||||
Client,
|
||||
@@ -37,7 +37,10 @@ internal sealed class EngineFixture
|
||||
usageRepository: usage,
|
||||
auditRepository: audit,
|
||||
stagingGate: staging,
|
||||
clock: clock);
|
||||
clock: clock)
|
||||
{
|
||||
TranscriptStore = transcripts
|
||||
};
|
||||
|
||||
// Kein Agent-Verzeichnis → keine Persistenz auf die Platte während der Tests.
|
||||
Engine.SetAgentConfigProvider(() => _agents, "test-instance", _ => null);
|
||||
|
||||
@@ -36,6 +36,11 @@ internal sealed class InMemoryAuditRepository : IAuditRepository
|
||||
public Task<IReadOnlyList<RunReceipt>> ListReceiptsForTaskAsync(string taskId, CancellationToken ct)
|
||||
=> Task.FromResult<IReadOnlyList<RunReceipt>>(Receipts.Where(r => r.TaskId == taskId).ToList());
|
||||
|
||||
public Task<IReadOnlyList<RunReceipt>> ListReceiptsAsync(DateTime fromUtc, DateTime toUtc, int limit, CancellationToken ct)
|
||||
=> Task.FromResult<IReadOnlyList<RunReceipt>>(Receipts
|
||||
.Where(r => r.OccurredAt >= fromUtc && r.OccurredAt < toUtc)
|
||||
.OrderBy(r => r.OccurredAt).Take(limit).ToList());
|
||||
|
||||
public Task<int> CountAsync(CancellationToken ct) => Task.FromResult(Entries.Count);
|
||||
|
||||
/// <summary>Spiegelt die SQL-Regel: Started ohne späteren Abschluss derselben CallId.</summary>
|
||||
|
||||
@@ -20,6 +20,9 @@ internal sealed class InMemoryStagingRepository : IStagingRepository
|
||||
public Task<StagedCall?> GetAsync(long id, CancellationToken ct)
|
||||
=> Task.FromResult(_calls.GetValueOrDefault(id));
|
||||
|
||||
public Task<IReadOnlyList<StagedCall>> ListForRunAsync(string runId, CancellationToken ct)
|
||||
=> Task.FromResult<IReadOnlyList<StagedCall>>(_calls.Values.Where(c => c.RunId == runId).OrderBy(c => c.Id).ToList());
|
||||
|
||||
public Task<int> CountExecutedAsync(string agentId, string tool, string? action, DateTime since, CancellationToken ct)
|
||||
=> Task.FromResult(_calls.Values.Count(c =>
|
||||
c.Status == StagingStatus.Executed && c.AgentId == agentId && c.Tool == tool
|
||||
|
||||
Reference in New Issue
Block a user