86 lines
3.2 KiB
C#
86 lines
3.2 KiB
C#
namespace ClawdDotNet.Core.Accounting;
|
|
|
|
/// <summary>Verbrauch eines abgeschlossenen Laufs.</summary>
|
|
public sealed record RunUsage
|
|
{
|
|
public long Id { get; init; }
|
|
public string AgentId { get; init; } = "";
|
|
public string Model { get; init; } = "";
|
|
|
|
public int PromptTokens { get; init; }
|
|
public int CompletionTokens { get; init; }
|
|
|
|
/// <summary>Anteil der Eingabe-Tokens aus dem Prompt-Cache — in PromptTokens enthalten.</summary>
|
|
public int CachedTokens { get; init; }
|
|
|
|
public int TotalTokens => PromptTokens + CompletionTokens;
|
|
|
|
public decimal CostUsd { get; init; }
|
|
|
|
/// <summary>
|
|
/// Ob für das Modell Preise vorlagen. Ohne diese Angabe wäre eine zu niedrige
|
|
/// Summe von einer vollständigen nicht zu unterscheiden.
|
|
/// </summary>
|
|
public bool CostIsKnown { get; init; }
|
|
|
|
public string Status { get; init; } = "";
|
|
public int StepCount { get; init; }
|
|
public long DurationMs { get; init; }
|
|
|
|
public DateTime OccurredAt { get; init; }
|
|
|
|
/// <summary>
|
|
/// #717: The task whose special budget the run drew on; empty for the daily budget. Such
|
|
/// runs do not count against the daily limits — that is what the pot is for.
|
|
/// </summary>
|
|
public string BudgetPot { get; init; } = "";
|
|
|
|
/// <summary>#712: The runtime of the run; empty for native.</summary>
|
|
public string Runtime { get; init; } = "";
|
|
|
|
/// <summary>#712: Paid from a subscription's quota. The cost is 0 $, the tokens are real (#699).</summary>
|
|
public bool OnSubscription { get; init; }
|
|
}
|
|
|
|
/// <summary>Verbrauch eines Tages, aggregiert.</summary>
|
|
public sealed record DailyUsage(
|
|
DateOnly Date,
|
|
int PromptTokens,
|
|
int CompletionTokens,
|
|
decimal CostUsd,
|
|
bool CostIsComplete,
|
|
int RunCount)
|
|
{
|
|
public int TotalTokens => PromptTokens + CompletionTokens;
|
|
|
|
public static DailyUsage Empty(DateOnly date) => new(date, 0, 0, 0m, true, 0);
|
|
}
|
|
|
|
public interface IUsageRepository
|
|
{
|
|
Task RecordAsync(RunUsage usage, CancellationToken ct);
|
|
|
|
/// <summary>Tagesverbrauch eines Agenten. <paramref name="agentId"/> leer = ganze Instanz.</summary>
|
|
Task<DailyUsage> GetDailyAsync(DateOnly date, string agentId, CancellationToken ct);
|
|
|
|
/// <summary>
|
|
/// #717: What counts against the daily limits — the day's usage without runs that drew on
|
|
/// a special budget. <see cref="GetDailyAsync"/> keeps showing everything that was used.
|
|
/// </summary>
|
|
Task<DailyUsage> GetDailyForBudgetAsync(DateOnly date, string agentId, CancellationToken ct)
|
|
=> GetDailyAsync(date, agentId, ct);
|
|
|
|
Task<IReadOnlyList<RunUsage>> GetRecentAsync(int limit, CancellationToken ct);
|
|
|
|
/// <summary>
|
|
/// #716: The most recent runs of one agent — the basis for estimating what a run of
|
|
/// it will cost. Without an implementation there is no estimate, and a reservation
|
|
/// counts nothing.
|
|
/// </summary>
|
|
Task<IReadOnlyList<RunUsage>> GetRecentForAgentAsync(string agentId, int limit, CancellationToken ct)
|
|
=> Task.FromResult<IReadOnlyList<RunUsage>>([]);
|
|
|
|
/// <summary>Entfernt Einträge älter als das angegebene Datum. Gibt die Anzahl zurück.</summary>
|
|
Task<int> PurgeBeforeAsync(DateOnly date, CancellationToken ct);
|
|
}
|