use std::sync::Arc;
use sim_codec::{Decoder, DomainCodecLib, Encoder, Input, Output, ReadCx};
use sim_kernel::{CodecId, Expr, Lib, LibManifest, Linker, LoadCx, Result, Symbol, WriteCx};
use super::openai::OpenAiCodecOptions;
use super::openai_compat::{
decode_request_for_provider, decode_response_for_provider, decode_stream_for_provider,
encode_request_for_provider, encode_response_for_codec, encode_response_for_provider,
};
const LM_STUDIO_CODEC_ID: CodecId = CodecId(0);
const PROVIDER: &str = "lm-studio";
pub type LmStudioCodecOptions = OpenAiCodecOptions;
pub type LmStudioRequestOptions = LmStudioCodecOptions;
pub struct LmStudioCodec;
impl Decoder for LmStudioCodec {
fn decode(&self, cx: &mut ReadCx<'_>, input: Input) -> Result<Expr> {
decode_request_for_provider(cx.codec, input, PROVIDER)
}
}
impl Encoder for LmStudioCodec {
fn encode(&self, cx: &mut WriteCx<'_>, expr: &Expr) -> Result<Output> {
encode_response_for_codec(cx.codec, expr).map(Output::Text)
}
}
pub struct LmStudioCodecLib {
symbol: Symbol,
codec_id: CodecId,
}
impl LmStudioCodecLib {
pub fn new(id: CodecId) -> Self {
Self {
symbol: lm_studio_codec_symbol(),
codec_id: id,
}
}
fn domain_lib(&self) -> DomainCodecLib {
DomainCodecLib::new(
self.symbol.clone(),
self.codec_id,
Arc::new(LmStudioCodec),
Arc::new(LmStudioCodec),
Symbol::qualified("codec", "LmStudioTranscript"),
)
}
}
impl Lib for LmStudioCodecLib {
fn manifest(&self) -> LibManifest {
self.domain_lib().manifest()
}
fn load(&self, cx: &mut LoadCx, linker: &mut Linker<'_>) -> Result<()> {
self.domain_lib().load(cx, linker)
}
}
pub fn lm_studio_codec_symbol() -> Symbol {
Symbol::qualified("codec", PROVIDER)
}
pub fn decode_lm_studio_request(input: Input) -> Result<Expr> {
decode_request_for_provider(LM_STUDIO_CODEC_ID, input, PROVIDER)
}
pub fn encode_lm_studio_request(expr: &Expr, options: &LmStudioRequestOptions) -> Result<Vec<u8>> {
encode_request_for_provider(expr, options)
}
pub fn decode_lm_studio_response(
runner: Symbol,
model: &str,
body: &[u8],
include_raw: bool,
) -> Result<Expr> {
decode_response_for_provider(runner, model, body, include_raw, PROVIDER)
}
pub fn decode_lm_studio_stream(
runner: Symbol,
model: &str,
body: &[u8],
include_raw: bool,
) -> Result<Expr> {
decode_stream_for_provider(runner, model, body, include_raw, PROVIDER)
}
pub fn encode_lm_studio_response(expr: &Expr) -> Result<Vec<u8>> {
encode_response_for_provider(expr)
}