use super::{penalty_history_scope, strip_in_tool_opener_bias};
const CLOSE: u32 = 248059;
#[test]
fn scope_without_completed_call_is_full_history() {
let toks = vec![1, 2, 3, 4];
assert_eq!(penalty_history_scope(&toks, Some(CLOSE)), &toks[..]);
assert_eq!(penalty_history_scope(&toks, None), &toks[..]);
}
#[test]
fn scope_cuts_after_last_completed_call() {
let toks = vec![10, 11, 12, CLOSE, 198, 20, 21];
assert_eq!(penalty_history_scope(&toks, Some(CLOSE)), &[198, 20, 21]);
let toks = vec![10, CLOSE, 198, 20, CLOSE, 30];
assert_eq!(penalty_history_scope(&toks, Some(CLOSE)), &[30]);
let toks = vec![10, 11, CLOSE];
assert_eq!(penalty_history_scope(&toks, Some(CLOSE)), &[] as &[u32]);
}
#[test]
fn scoped_history_prevents_cross_call_penalty_compounding() {
use crate::scheduler::{SamplingParams, apply_penalties_and_bias};
const NL: u32 = 198;
const NL_VARIANT: u32 = 695;
let params = SamplingParams {
temperature: 0.0,
top_k: 0,
top_p: 1.0,
top_n_sigma: 0.0,
min_p: 0.0,
logit_bias: Vec::new(),
repetition_penalty: 1.1,
repetition_penalty_window: 0,
presence_penalty: 0.0,
frequency_penalty: 0.0,
lz_penalty: 0.0,
dry_multiplier: 0.0,
dry_base: 1.75,
dry_allowed_length: 2,
dry_sequence_breakers: Vec::new(),
max_tokens: 0,
stop_token_ids: Vec::new(),
seed: None,
};
let full_history: Vec<u32> = vec![NL; 6]
.into_iter()
.chain([10, 11, CLOSE, NL]) .collect();
let mut logits = vec![0.0f32; 1000];
logits[NL as usize] = 10.0;
logits[NL_VARIANT as usize] = 8.5;
apply_penalties_and_bias(&mut logits, ¶ms, &full_history);
assert!(
logits[NL_VARIANT as usize] > logits[NL as usize],
"unscoped: 1.1^7 compounding must flip the scaffold token (the bug): {} vs {}",
logits[NL as usize],
logits[NL_VARIANT as usize],
);
let mut logits = vec![0.0f32; 1000];
logits[NL as usize] = 10.0;
logits[NL_VARIANT as usize] = 8.5;
let scoped = penalty_history_scope(&full_history, Some(CLOSE));
assert_eq!(scoped, &[NL], "segment = separator newline only");
apply_penalties_and_bias(&mut logits, ¶ms, scoped);
assert!(
logits[NL as usize] > logits[NL_VARIANT as usize],
"scoped: one occurrence must NOT flip the scaffold token: {} vs {}",
logits[NL as usize],
logits[NL_VARIANT as usize],
);
}
#[test]
fn opener_bias_stripped_only_inside_tool_body() {
const OPEN: u32 = 248058;
let mut bias = vec![(OPEN, 3.0f32), (42, -8.0f32)];
strip_in_tool_opener_bias(&mut bias, true, Some(OPEN));
assert_eq!(bias, vec![(42, -8.0f32)]);
let mut bias = vec![(OPEN, -5.0f32)];
strip_in_tool_opener_bias(&mut bias, true, Some(OPEN));
assert_eq!(bias, vec![(OPEN, -5.0f32)], "anti-repeat bias survives");
let mut bias = vec![(OPEN, 3.0f32)];
strip_in_tool_opener_bias(&mut bias, false, Some(OPEN));
assert_eq!(bias, vec![(OPEN, 3.0f32)]);
let mut bias = vec![(OPEN, 3.0f32)];
strip_in_tool_opener_bias(&mut bias, true, None);
assert_eq!(bias, vec![(OPEN, 3.0f32)]);
}