use axum::http::StatusCode;
use crate::AppState;
use crate::openai::PromptInput;
pub(super) fn resolve_prompts(
state: &AppState,
prompt: &PromptInput,
) -> Result<Vec<Vec<u32>>, (StatusCode, String)> {
match prompt {
PromptInput::Text(s) => {
Ok(vec![state.tokenizer.encode(s).map_err(|e| {
(StatusCode::BAD_REQUEST, format!("Tokenization error: {e}"))
})?])
}
PromptInput::TextArray(parts) => {
parts
.iter()
.map(|part| {
state
.tokenizer
.encode(part)
.map_err(|e| (StatusCode::BAD_REQUEST, format!("Tokenization error: {e}")))
})
.collect()
}
PromptInput::TokenIds(ids) => {
validate_token_ids(state, ids)?;
Ok(vec![ids.clone()])
}
PromptInput::TokenIdBatch(batch) => {
for ids in batch {
validate_token_ids(state, ids)?;
}
Ok(batch.clone())
}
}
}
fn validate_token_ids(state: &AppState, ids: &[u32]) -> Result<(), (StatusCode, String)> {
let vocab_size = state.tokenizer.inner().get_vocab_size(true) as u32;
if let Some(&bad) = ids.iter().find(|&&id| id >= vocab_size) {
return Err((
StatusCode::BAD_REQUEST,
format!("Token ID {bad} out of range: vocab_size is {vocab_size}"),
));
}
Ok(())
}