use crate::profiles::configuration::normalized_param_values;
use crate::records::{JsonValue, ModelRecord, RuntimeId, SourceKind};
pub const COMPLETION_FLOOR: i64 = 256;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Verdict {
Fits {
clamped_max_tokens: Option<i64>,
},
Exceeds {
estimated: i64,
window: i64,
},
}
pub fn estimated_tokens(characters: i64) -> i64 {
(characters + 3) / 4
}
pub fn assess(prompt_characters: i64, window: i64, requested_max_tokens: Option<i64>) -> Verdict {
let estimated = estimated_tokens(prompt_characters);
if estimated + COMPLETION_FLOOR > window {
return Verdict::Exceeds { estimated, window };
}
let available = window - estimated;
let clamped = requested_max_tokens.unwrap_or(available).min(available);
Verdict::Fits {
clamped_max_tokens: Some(clamped),
}
}
pub fn effective_window(
record: &ModelRecord,
requested_context_length: Option<i64>,
) -> Option<i64> {
if record.source.kind == SourceKind::builtin() {
return Some(4096);
}
let window = record_policy_window(record, requested_context_length)?;
(window > 0).then_some(window)
}
fn record_policy_window(record: &ModelRecord, requested: Option<i64>) -> Option<i64> {
let id = record.runtime.id.as_ref()?;
if *id == RuntimeId::ollama() {
requested.or(record.context_length)
} else if *id == RuntimeId::llama_cpp()
|| *id == RuntimeId::mlx_swift()
|| *id == RuntimeId::mlx_lm()
{
record.context_length
} else {
None
}
}
pub fn stored_context_length(record: &ModelRecord) -> Option<i64> {
normalized_param_values(record)
.get("context_length")
.and_then(JsonValue::as_i64)
}
pub fn prompt_characters(payload: &JsonValue) -> i64 {
let JsonValue::Object(object) = payload else {
return 0;
};
let mut total = 0i64;
if let Some(JsonValue::Array(messages)) = object.get("messages") {
for message in messages {
if let JsonValue::Object(fields) = message
&& let Some(JsonValue::String(content)) = fields.get("content")
{
total += content.chars().count() as i64;
}
}
}
if let Some(JsonValue::String(prompt)) = object.get("prompt") {
total += prompt.chars().count() as i64;
}
total
}