Previously the model could emit EOS before reaching n_bars because the
EOS-suppression was only applied via the n_bars break, not the grammar
bias. Fixed by masking EOS to -inf in the logit bias while
bars_completed < n_bars.
Added _EosHungryModel fixture and test_generate_bars_overrides_early_eos
to catch this regression class.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
generate_period() now accepts n_bars=N to stop after exactly N complete
bars. bars_completed is seeded from the prefix length so --bars counts
the full output, not just the generated tail.
scripts/generate.py exposes this as --bars (default: None = model decides).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_encode_prefix now handles hold ('.') and no-chord ('NC') tokens
alongside chord symbols, and returns (ids, n_positions) so that
pos_in_bar is tracked correctly regardless of token type.
Fixes ChordParseError when dots were passed in --prefix.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>