use super::table::MeshLocal;
use super::types::ProxyError;
pub fn mesh_path_allowed(path: &str) -> bool {
matches!(
path.split('?').next().unwrap_or(""),
"/v1/chat/completions" | "/v1/completions" | "/v1/embeddings" | "/v1/models"
)
}
const SAMPLING: &[&str] = &[
"max_tokens",
"max_completion_tokens",
"temperature",
"top_p",
"top_k",
"min_p",
"stream",
"stream_options",
"stop",
"n",
"seed",
"presence_penalty",
"frequency_penalty",
"repetition_penalty",
"logit_bias",
"logprobs",
"top_logprobs",
"response_format",
"user",
];
fn allowed_keys(route: &str) -> (&'static [&'static str], &'static [&'static str]) {
match route {
"/v1/chat/completions" => (SAMPLING, &["messages", "tools", "tool_choice", "parallel_tool_calls"]),
"/v1/completions" => (SAMPLING, &["prompt"]),
"/v1/embeddings" => (&[], &["input", "encoding_format", "dimensions", "user"]),
_ => (&[], &[]),
}
}
pub fn pin_body(path: &str, body: &[u8], local: &MeshLocal) -> Result<Vec<u8>, ProxyError> {
if body.is_empty() {
return Ok(Vec::new());
}
let bad = || ProxyError::BadRequest("request body must be a JSON object".into());
let v: serde_json::Value = serde_json::from_slice(body).map_err(|_| bad())?;
let src = v.as_object().ok_or_else(bad)?;
let route = path.split('?').next().unwrap_or("");
let (common, own) = allowed_keys(route);
let mut out = serde_json::Map::new();
for (k, val) in src {
if common.contains(&k.as_str()) || own.contains(&k.as_str()) {
out.insert(k.clone(), val.clone());
}
}
let pinned = if local.runtime == "MlxLm" {
Some("default_model".to_string())
} else {
local.model.clone()
};
if let Some(m) = pinned {
out.insert("model".into(), serde_json::Value::String(m));
}
serde_json::to_vec(&serde_json::Value::Object(out)).map_err(|_| bad())
}