using ClawdDotNet.Core.Config; using Shouldly; namespace ClawdDotNet.Core.Tests.Config; /// /// Old configurations contain "maxTokens" — a value that was meant as a context limit, /// but counted cumulatively over all steps and aborted runs prematurely (bug B3). /// The migration must not take over this value unchanged as the cost budget. /// public sealed class ConfigMigrationTests { private static InstanceConfig WithLegacyMaxTokens(int? legacy) => new() { OpenRouterApiKey = "sk-test", Agents = [ new AgentConfig { AgentId = "test", LoopGuard = new LoopGuardConfig { LegacyMaxTokens = legacy } } ] }; [Fact] public void An_old_too_tight_maxTokens_is_replaced_by_the_new_default() { var config = WithLegacyMaxTokens(80_000); // the old, problematic value ConfigLoader.Migrate(config); var guard = config.Agents[0].LoopGuard; guard.MaxCumulativeTokens.ShouldBe(500_000); guard.LegacyMaxTokens.ShouldBeNull(); } [Fact] public void A_deliberately_generous_maxTokens_is_kept() { var config = WithLegacyMaxTokens(2_000_000); ConfigLoader.Migrate(config); config.Agents[0].LoopGuard.MaxCumulativeTokens.ShouldBe(2_000_000); } [Fact] public void Without_old_field_the_default_stays_unchanged() { var config = WithLegacyMaxTokens(null); ConfigLoader.Migrate(config); config.Agents[0].LoopGuard.MaxCumulativeTokens.ShouldBe(500_000); } [Fact] public void Migration_can_be_applied_repeatedly() { var config = WithLegacyMaxTokens(80_000); ConfigLoader.Migrate(config); ConfigLoader.Migrate(config); config.Agents[0].LoopGuard.MaxCumulativeTokens.ShouldBe(500_000); } }