pub trait SpecConstraint {
// Required methods
fn mask_logits(&mut self, logits: &mut [f32]) -> Result<(), String>;
fn mask_words(&mut self) -> Result<Vec<u32>, String>;
fn is_allowed(&mut self, tok: u32) -> Result<bool, String>;
fn consume(&mut self, tok: u32) -> Result<(), String>;
// Provided methods
fn draft_mask_enabled(&self) -> bool { ... }
fn draft_begin(&mut self) -> Result<(), String> { ... }
fn draft_mask_words(&mut self) -> Result<Option<Vec<u32>>, String> { ... }
fn draft_advance(&mut self, _tok: u32) -> Result<bool, String> { ... }
}Expand description
GRAMMAR HOOK for constrained spec decode (lane/constrained-full, 2026-08-03). The engine
stays llguidance-agnostic: the server adapts its per-session grammar state behind this
trait. CONTRACT (the verify-side truncation rule — token-identical to constrained plain
greedy decode): the exactness walk runs UNMASKED first; the hook then (a) truncates
acceptance at the first grammar-illegal accepted token, and (b) when the truncation fired
or the bonus is illegal, the engine recomputes that slot as the MASKED argmax of the
target’s own verify column (an unmasked argmax that is grammar-legal IS the masked argmax
— masking only removes tokens — so the common case pays nothing). consume advances the
state with each EMITTED token in order; EOS handling is the implementor’s job (skip).
Required Methods§
Sourcefn mask_logits(&mut self, logits: &mut [f32]) -> Result<(), String>
fn mask_logits(&mut self, logits: &mut [f32]) -> Result<(), String>
-inf the current state’s banned ids on a HOST logits row (prompt-tail / init-feed masked argmax).
Sourcefn mask_words(&mut self) -> Result<Vec<u32>, String>
fn mask_words(&mut self) -> Result<Vec<u32>, String>
Packed 32-bit bitset words of the CURRENT state’s allowed set (device-mask form).
Provided Methods§
Sourcefn draft_mask_enabled(&self) -> bool
fn draft_mask_enabled(&self) -> bool
Is draft-side masking available on this hook? Probed ONCE per burst, before the draft graph is captured (the mask is an in-graph node — its presence is a capture-time shape).
Sourcefn draft_begin(&mut self) -> Result<(), String>
fn draft_begin(&mut self) -> Result<(), String>
Start a draft chain: clone the CURRENT (committed) grammar state into the speculative slot. Called once per spec round, before the first draft position.
Sourcefn draft_mask_words(&mut self) -> Result<Option<Vec<u32>>, String>
fn draft_mask_words(&mut self) -> Result<Option<Vec<u32>>, String>
Packed 32-bit bitset words of the SPECULATIVE state’s allowed set (target-vocab ids),
for the draft position about to be sampled. None = draft masking off (no-op).
Sourcefn draft_advance(&mut self, _tok: u32) -> Result<bool, String>
fn draft_advance(&mut self, _tok: u32) -> Result<bool, String>
Advance the SPECULATIVE state with a PROPOSED draft token. false = the chain cannot
continue (EOS proposed, or an unmasked position proposed something illegal) — the
engine stops drafting; the token already pushed still goes through verify.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".