use sim_codec::Input;
use sim_kernel::{CodecId, Expr, Result, Symbol};
use super::openai::{
OpenAiRequestOptions, decode_openai_request_for_codec, decode_openai_response,
decode_openai_stream, encode_openai_request, encode_openai_response,
encode_openai_response_for_codec,
};
pub(in crate::providers) fn decode_request_for_provider(
codec: CodecId,
input: Input,
provider: &'static str,
) -> Result<Expr> {
let mut expr = decode_openai_request_for_codec(codec, input)?;
stamp_provider(&mut expr, provider);
Ok(expr)
}
pub(in crate::providers) fn encode_request_for_provider(
expr: &Expr,
options: &OpenAiRequestOptions,
) -> Result<Vec<u8>> {
encode_openai_request(expr, options)
}
pub(in crate::providers) fn decode_response_for_provider(
runner: Symbol,
model: &str,
body: &[u8],
include_raw: bool,
provider: &'static str,
) -> Result<Expr> {
let mut expr = decode_openai_response(runner, model, body, include_raw)?;
stamp_provider(&mut expr, provider);
Ok(expr)
}
pub(in crate::providers) fn decode_stream_for_provider(
runner: Symbol,
model: &str,
body: &[u8],
include_raw: bool,
provider: &'static str,
) -> Result<Expr> {
let mut expr = decode_openai_stream(runner, model, body, include_raw)?;
stamp_provider(&mut expr, provider);
Ok(expr)
}
pub(in crate::providers) fn encode_response_for_codec(
codec: CodecId,
expr: &Expr,
) -> Result<String> {
encode_openai_response_for_codec(codec, expr)
}
pub(in crate::providers) fn encode_response_for_provider(expr: &Expr) -> Result<Vec<u8>> {
encode_openai_response(expr)
}
fn stamp_provider(expr: &mut Expr, provider: &'static str) {
let Expr::Map(entries) = expr else {
return;
};
let value = Expr::Symbol(Symbol::new(provider));
if let Some((_, existing)) = entries.iter_mut().find(|(key, _)| provider_key(key)) {
*existing = value;
} else {
entries.push((Expr::Symbol(Symbol::new("provider")), value));
}
}
fn provider_key(expr: &Expr) -> bool {
matches!(expr, Expr::Symbol(symbol) if symbol.name.as_ref() == "provider")
}