namespace ClawdDotNet.Core.Engine; public sealed record AgentRunResult( string AgentId, AgentRunStatus Status, string? FinalMessage, int StepCount, int TokensUsed, TimeSpan Duration, Exception? Error = null ) { /// Summe der Eingabe-Tokens über alle Schritte des Runs. public int PromptTokens { get; init; } /// Summe der Ausgabe-Tokens über alle Schritte des Runs. public int CompletionTokens { get; init; } /// /// Anteil der Eingabe-Tokens, der aus dem Prompt-Cache kam. Diese Tokens sind bereits /// in enthalten, kosten aber nur einen Bruchteil. /// public int CachedTokens { get; init; } /// /// Der vom Gateway gemeldete Betrag über alle Schritte (#550), falls geliefert. /// /// 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. /// public decimal? ReportedCostUsd { get; init; } /// #712: The runtime the run happened in; empty for native. public string Runtime { get; init; } = ""; /// #712: Paid from a subscription's quota — 0 $, but not free (#699). public bool OnSubscription { get; init; } /// #712: The model a foreign runtime reported, when it differs from the configured name. public string? ActualModel { get; init; } } public enum AgentRunStatus { Completed, Failed, Cancelled, LoopLimitExceeded, /// Der Lauf fand nicht statt, weil das Tagesbudget erschöpft ist. BudgetExceeded, /// /// 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. /// TargetBusy, /// /// Der Lauf fand nicht statt, weil die Instanz gerade geordnet endet (#528). /// /// 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. /// ShuttingDown, /// /// Das Modell stieß an die Ausgabegrenze, bevor es fertig war (#548). /// /// Der Lauf ist damit nicht gescheitert — es liegt ein Teilergebnis vor, und /// das steht in . Er ist aber auch nicht /// : 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. /// Truncated, /// /// Das Modell antwortete leer - auch nach einmaligem Nachfassen (#577). Vorher galt das /// als , und ein Agent, der mitten im Auftrag verstummte, sah /// aus wie einer, der fertig war. /// EmptyResponse, /// /// Ein Aufgabenlauf endete ohne Ergebniszeile - auch nach einmaligem Nachfassen (#577). /// Die Antwort steht in , war aber kein /// erklaerter Abschluss. /// Incomplete, /// /// Derselbe Werkzeugaufruf ist wiederholt gleich gescheitert; der Lauf wurde beendet, /// statt bis zur Schrittgrenze weiterzulaufen (#581). /// RepeatedFailure }