Files
whetstone_DSL/editor/src/TokenBudgetGate.h
Bill de5bdd358f Close all 26 generator readiness gaps (sprints 267-270)
Sprint 268: GR-002/003/006/007/008/016/017/019/021/024 — self-containment,
  graduation thresholds, asm/ir/jvm/elixir lang coverage, semanno format.
Sprint 269: GR-005/011/013/015 — prose capture in RequirementsParser,
  GateEnforcer, ParitySkewAnalyzer, CrossArtifactConsistencyEngine.
Sprint 270: GR-009/010/012/014/018/020 — CrossFileTransactionGate,
  SemanticCompletionGate, ConstrainedProjectionGate, TokenBudgetGate,
  CppConstraintRefactorPolicy, NativeDecompositionDepthGuard.
All 50 new tests passing (steps 1873-1882, 5/5 per step).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 22:28:41 -07:00

45 lines
1.6 KiB
C++

#pragma once
// Step 1881a: Token budget gate (GR-014).
// Closes GR-014: low-yield (token-bloated) runs had no hard enforcement.
// TokenBudgetGate uses ContextWindowOptimizer to estimate tokens and blocks
// when a generation output would exceed the allowed budget.
#include "ContextWindowOptimizer.h"
#include <string>
struct TokenBudgetResult {
bool blocked = false;
int estimatedTokens = 0;
int budgetTokens = 0;
float yieldRatio = 0.0f; // output useful content / total tokens
};
class TokenBudgetGate {
public:
static constexpr float kMinYieldRatio = 0.30f; // at least 30% of tokens must be useful
// Block if the output text exceeds the budget or yield is too low.
static TokenBudgetResult evaluate(const std::string& outputText,
int contextWindowTokens,
int usefulContentTokens = -1) {
TokenBudgetResult result;
result.estimatedTokens = ContextWindowOptimizer::estimateTokens(outputText);
result.budgetTokens = ContextWindowOptimizer::budgetForContextWindow(contextWindowTokens);
if (result.estimatedTokens > result.budgetTokens) {
result.blocked = true;
return result;
}
// Yield check: if caller provides useful content token count
if (usefulContentTokens >= 0 && result.estimatedTokens > 0) {
result.yieldRatio = static_cast<float>(usefulContentTokens) / result.estimatedTokens;
if (result.yieldRatio < kMinYieldRatio) {
result.blocked = true;
}
}
return result;
}
};