Files
ClawdDotNet/src/ClawdDotNet.Core/Engine/AgentRunResult.cs
T

101 lines
3.8 KiB
C#

namespace ClawdDotNet.Core.Engine;
public sealed record AgentRunResult(
string AgentId,
AgentRunStatus Status,
string? FinalMessage,
int StepCount,
int TokensUsed,
TimeSpan Duration,
Exception? Error = null
)
{
/// <summary>Summe der Eingabe-Tokens über alle Schritte des Runs.</summary>
public int PromptTokens { get; init; }
/// <summary>Summe der Ausgabe-Tokens über alle Schritte des Runs.</summary>
public int CompletionTokens { get; init; }
/// <summary>
/// Anteil der Eingabe-Tokens, der aus dem Prompt-Cache kam. Diese Tokens sind bereits
/// in <see cref="PromptTokens"/> enthalten, kosten aber nur einen Bruchteil.
/// </summary>
public int CachedTokens { get; init; }
/// <summary>
/// Der vom Gateway gemeldete Betrag über alle Schritte (#550), falls geliefert.
///
/// <para>Er ist der Eigenrechnung vorzuziehen, weil er das abbildet, was tatsächlich
/// abgerechnet wurde — einschließlich dessen, was eine Preisliste nicht kennt:
/// Cache-Schreibaufschläge, abweichende Preise je Anbieter, Rabatte.</para>
/// </summary>
public decimal? ReportedCostUsd { get; init; }
/// <summary>#712: The runtime the run happened in; empty for native.</summary>
public string Runtime { get; init; } = "";
/// <summary>#712: Paid from a subscription's quota — 0 $, but not free (#699).</summary>
public bool OnSubscription { get; init; }
/// <summary>#712: The model a foreign runtime reported, when it differs from the configured name.</summary>
public string? ActualModel { get; init; }
}
public enum AgentRunStatus
{
Completed,
Failed,
Cancelled,
LoopLimitExceeded,
/// <summary>Der Lauf fand nicht statt, weil das Tagesbudget erschöpft ist.</summary>
BudgetExceeded,
/// <summary>
/// Der Lauf fand nicht statt, weil der Agent belegt war und der Aufruf nicht
/// unbegrenzt warten darf (#461). Trifft nur delegierte Läufe — ein vom Menschen
/// angestoßener Chat reiht sich weiterhin ein und wartet, so lange es dauert.
/// </summary>
TargetBusy,
/// <summary>
/// Der Lauf fand nicht statt, weil die Instanz gerade geordnet endet (#528).
///
/// <para>Beim Herunterfahren wird zuerst die Tür geschlossen und dann gewartet.
/// Andersherum ginge die Zahl der offenen Läufe nie auf null, weil ständig neue
/// dazukämen — die Instanz käme nie zum Ende.</para>
/// </summary>
ShuttingDown,
/// <summary>
/// Das Modell stieß an die Ausgabegrenze, bevor es fertig war (#548).
///
/// <para>Der Lauf ist damit nicht gescheitert — es liegt ein Teilergebnis vor, und
/// das steht in <see cref="AgentRunResult.FinalMessage"/>. Er ist aber auch nicht
/// <see cref="Completed"/>: Was dort steht, ist ein abgeschnittener Gedanke, kein
/// Schluss. Der Unterschied muss sichtbar sein, weil ein geplanter Lauf im
/// Hintergrund sonst ein halbes Ergebnis weiterreicht, als wäre es ein ganzes.</para>
/// </summary>
Truncated,
/// <summary>
/// Das Modell antwortete leer - auch nach einmaligem Nachfassen (#577). Vorher galt das
/// als <see cref="Completed"/>, und ein Agent, der mitten im Auftrag verstummte, sah
/// aus wie einer, der fertig war.
/// </summary>
EmptyResponse,
/// <summary>
/// Ein Aufgabenlauf endete ohne Ergebniszeile - auch nach einmaligem Nachfassen (#577).
/// Die Antwort steht in <see cref="AgentRunResult.FinalMessage"/>, war aber kein
/// erklaerter Abschluss.
/// </summary>
Incomplete,
/// <summary>
/// Derselbe Werkzeugaufruf ist wiederholt gleich gescheitert; der Lauf wurde beendet,
/// statt bis zur Schrittgrenze weiterzulaufen (#581).
/// </summary>
RepeatedFailure
}