struct StreamedText {
deltas: Vec<String>,
stopped: bool,
}
fn streaming_text_deltas(
tokenizer: &BPETokenizer,
token_ids: &[u32],
stops: Option<&[String]>,
) -> StreamedText {
let mut deltas = Vec::new();
let mut emitted = 0usize;
let mut stopped = false;
for i in 0..token_ids.len() {
let Ok(raw) = tokenizer.decode(&token_ids[..=i]) else {
continue;
};
let text = crate::api::realize_handlers::truncate_at_stop(raw.clone(), stops);
let stop_hit = text.len() < raw.len();
if !stop_hit && text.ends_with('\u{FFFD}') {
continue;
}
if text.len() > emitted && text.is_char_boundary(emitted) {
deltas.push(text[emitted..].to_string());
emitted = text.len();
}
if stop_hit {
stopped = true;
break;
}
}
StreamedText { deltas, stopped }
}
pub async fn openai_chat_completions_stream_handler(
State(state): State<AppState>,
headers: HeaderMap,
Extension(cancel): Extension<CancelToken>,
Json(mut request): Json<ChatCompletionRequest>,
) -> Response {
request.stream = true;
openai_chat_completions_handler(State(state), headers, Extension(cancel), Json(request)).await
}
#[cfg(test)]
mod pmat758_streaming_delta_tests {
use super::*;
fn tok(vocab: &[&str]) -> BPETokenizer {
BPETokenizer::new(
vocab.iter().map(|s| (*s).to_string()).collect(),
vec![],
"<unk>",
)
.expect("test tokenizer")
}
#[test]
fn holds_back_multibyte_utf8_until_complete() {
let t = tok(&["<unk>", "<0xF0>", "<0x9F>", "<0x98>", "<0x80>"]);
let deltas = streaming_text_deltas(&t, &[1, 2, 3, 4], None).deltas;
assert_eq!(deltas.concat(), "😀");
assert!(
!deltas.concat().contains('\u{FFFD}'),
"no replacement chars in streamed deltas"
);
}
#[test]
fn applies_stop_and_halts_emission() {
let t = tok(&["<unk>", "a", "b", "X", "c"]);
let deltas = streaming_text_deltas(&t, &[1, 2, 3, 4], Some(&["X".to_string()])).deltas;
assert_eq!(deltas.concat(), "ab");
assert!(!deltas.concat().contains('X'));
}
#[test]
fn no_stop_streams_full_text() {
let t = tok(&["<unk>", "a", "b", "X", "c"]);
let deltas = streaming_text_deltas(&t, &[1, 2, 3, 4], None).deltas;
assert_eq!(deltas.concat(), "abXc");
}
}
#[cfg(test)]
mod pmat790_stream_temperature_zero_tests {
use crate::api::realize_handlers::resolve_dense_generation_config as resolve_stream_generation_config;
use crate::generate::{sample_token, SamplingStrategy};
use crate::tensor::Tensor;
#[test]
fn temperature_zero_resolves_to_runnable_greedy_config() {
let config = resolve_stream_generation_config(0.0, None, 16);
assert_eq!(
config.strategy,
SamplingStrategy::Greedy,
"temperature 0 must request deterministic (greedy) decoding"
);
let logits = Tensor::from_vec(vec![4], vec![0.1, 0.2, 0.9, 0.3]).expect("tensor");
let token = sample_token(&logits, &config, 0.5)
.expect("temperature-0 config must sample without error (was HTTP 500)");
assert_eq!(token, 2, "greedy must select the argmax token");
}
#[test]
fn temperature_zero_ignores_top_p_and_stays_greedy() {
let config = resolve_stream_generation_config(0.0, Some(0.9), 16);
assert_eq!(config.strategy, SamplingStrategy::Greedy);
}
#[test]
fn positive_temperature_unchanged() {
let greedy = resolve_stream_generation_config(0.7, None, 16);
assert_eq!(greedy.strategy, SamplingStrategy::Greedy);
assert!((greedy.temperature - 0.7).abs() < 1e-6);
let nucleus = resolve_stream_generation_config(0.7, Some(0.8), 16);
assert!(matches!(
nucleus.strategy,
SamplingStrategy::TopP { p } if (p - 0.8).abs() < 1e-6
));
let logits = Tensor::from_vec(vec![3], vec![0.1, 2.0, 0.3]).expect("tensor");
assert!(
sample_token(&logits, &greedy, 0.5).is_ok(),
"positive-temperature config must remain runnable"
);
}
}