using ClawdDotNet.Core.Config; namespace ClawdDotNet.Core.Engine; public sealed class LoopGuard { private readonly LoopGuardConfig _cfg; private int _steps; private int _tokens; public LoopGuard(LoopGuardConfig cfg) => _cfg = cfg; public int Steps => _steps; public int Tokens => _tokens; public void RecordStep() { if (Interlocked.Increment(ref _steps) > _cfg.MaxSteps) throw new LoopLimitExceededException( $"Schritt-Limit erreicht: {_cfg.MaxSteps} Schritte pro Run."); } /// /// Bucht die abgerechneten Tokens eines Schritts auf das Kostenbudget des Runs. /// Das ist eine reine Kostenbremse — die Kontextgröße wird davon getrennt über /// und die Compaction gesteuert. /// public void RecordTokens(int count) { var total = Interlocked.Add(ref _tokens, count); if (total > _cfg.MaxCumulativeTokens) throw new LoopLimitExceededException( $"Kostenbudget erschöpft: {total:N0} von maximal {_cfg.MaxCumulativeTokens:N0} " + "abgerechneten Tokens in diesem Run. Hinweis: Jeder Schritt sendet den " + "kompletten Kontext erneut, die Summe wächst daher überproportional."); } } public sealed class LoopLimitExceededException(string message) : Exception(message);