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>
45 lines
1.6 KiB
C++
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;
|
|
}
|
|
};
|