// Copyright 2026 TesterArmy. // Modified by Dario Kondratiuk. // SPDX-License-Identifier: Apache-2.0 namespace E2E; /// What reads of the agent's limits (upstream's ObservationBudgetLimits). /// agent.maxObservationBytes: the configured ceiling. /// agent.maxInputTokens: the per-call ceiling the model pre-flight checks. internal readonly record struct ObservationBudgetLimits(int MaxObservationBytes, int MaxInputTokens); /// What reads of the request (upstream's ObservationBudgetRequest). /// Bytes the rest of the request already costs: system message, ledger, context. /// Bytes of the caller's instruction as the prompt carries it; 0 when it is not sent with the observation. /// Whether a screenshot travels with the tree, reserving its token cost too. internal readonly record struct ObservationBudgetRequest(int FixedBytes, int InstructionBytes, bool Pixels); /// /// The observation byte budget both agent tiers capture under (upstream's agent/observation-budget.ts). The judgment tier /// derived it first; the act loop reuses it so a dense page costs the same bounded slice of the per-call token ceiling in either path. /// internal static class ObservationBudget { /// /// Headroom reserved for what travels with the instruction, in the byte-scaled units works in: /// the request text, the prompt's markup, and a repair section quoting a rejected response. The instruction itself is measured, not /// reserved for: a long extract instruction outgrows any fixed figure, and the pre-flight refuses the request instead of the screen /// being cut to fit. /// private const int InstructionReserve = 4_096; /// /// Headroom reserved for one attached screenshot on a vision call, in the same units. The exact cost is only known once the /// observation reports its viewport, which is after the budget has to be fixed, so this reserves for the largest viewport worth /// planning for, derived through the same function the pre-flight bills with. /// private static readonly int PixelReserve = ModelAdapter.ImageTokenUpperBound(2_560, 1_440); /// Floor below which a clamped budget never falls; a tree this small still names the visible controls. private const int MinObservationBytes = 1_024; /// /// Bytes one observation may contribute to a request. agent.maxObservationBytes is the configured ceiling, but the per-call /// token limit binds first on a large screen. Deriving the budget from what the rest of the request actually costs makes a big screen /// truncate visibly rather than fail the pre-flight check. /// public static int ObservationByteBudget(ObservationBudgetLimits limits, ObservationBudgetRequest request) { var overhead = (long)request.FixedBytes + request.InstructionBytes + InstructionReserve + (request.Pixels ? PixelReserve : 0); var withinTokenCeiling = Math.Max(MinObservationBytes, limits.MaxInputTokens - overhead); return (int)Math.Min(limits.MaxObservationBytes, withinTokenCeiling); } }