Packages
liter_llm
1.4.0-rc.21
1.11.3
1.11.2
1.11.1
1.11.0
1.10.1
1.10.0
1.9.3
1.9.0
1.9.0-rc.2
1.9.0-rc.1
1.8.2
1.8.1
1.8.0
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.6.4
1.6.3
1.6.2
1.5.1
1.5.0
1.4.1
1.4.0-rc.61
1.4.0-rc.60
1.4.0-rc.59
1.4.0-rc.58
1.4.0-rc.57
1.4.0-rc.56
1.4.0-rc.55
1.4.0-rc.53
1.4.0-rc.52
1.4.0-rc.50
1.4.0-rc.48
1.4.0-rc.47
1.4.0-rc.46
1.4.0-rc.45
1.4.0-rc.44
1.4.0-rc.43
1.4.0-rc.39
1.4.0-rc.38
1.4.0-rc.37
1.4.0-rc.36
1.4.0-rc.35
1.4.0-rc.34
1.4.0-rc.33
1.4.0-rc.32
1.4.0-rc.31
1.4.0-rc.30
1.4.0-rc.27
1.4.0-rc.26
1.4.0-rc.25
1.4.0-rc.24
1.4.0-rc.22
1.4.0-rc.21
1.4.0-rc.20
1.4.0-rc.19
1.4.0-rc.18
1.4.0-rc.17
1.4.0-rc.16
1.4.0-rc.14
1.4.0-rc.13
1.4.0-rc.11
1.2.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.0
1.0.0-rc.9
1.0.0-rc.8
1.0.0-rc.7
1.0.0-rc.6
1.0.0-rc.5
1.0.0-rc.4
1.0.0-rc.3
1.0.0-rc.2
Universal LLM API client with Rust-powered polyglot bindings.
Current section
Files
Jump to
Current section
Files
native/liter_llm_nif/src/lib.rs
// This file is auto-generated by alef. DO NOT EDIT.
// alef:hash:a08da97bbed9e12818bae5c66207589a77e4711ba7fc47d1fe4d2f59f21f15d8
// Re-generate with: alef generate
#![allow(dead_code, unused_imports, unused_variables)]
#![allow(
clippy::too_many_arguments,
clippy::let_unit_value,
clippy::needless_borrow,
clippy::map_identity,
clippy::just_underscores_and_digits,
clippy::unused_unit,
clippy::unnecessary_cast,
clippy::unwrap_or_default,
clippy::derivable_impls,
clippy::needless_borrows_for_generic_args,
clippy::unnecessary_fallible_conversions
)]
use liter_llm::client::LlmClient;
use rustler::Encoder;
use rustler::ResourceArc;
use std::collections::HashMap;
use std::sync::Arc;
#[derive(Clone)]
pub struct LiterLlmError {
inner: Arc<liter_llm::LiterLlmError>,
}
// SAFETY: See gen_opaque_resource in alef-backend-rustler for rationale.
impl std::panic::RefUnwindSafe for LiterLlmError {}
impl rustler::Resource for LiterLlmError {}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct SystemMessage {
pub content: String,
pub name: Option<String>,
}
impl SystemMessage {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
content: opts.get("content").and_then(|t| t.decode().ok()).unwrap_or_default(),
name: opts.get("name").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct UserMessage {
pub content: UserContent,
pub name: Option<String>,
}
impl UserMessage {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
content: opts.get("content").and_then(|t| t.decode().ok()).unwrap_or_default(),
name: opts.get("name").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct ImageUrl {
pub url: String,
pub detail: Option<ImageDetail>,
}
impl ImageUrl {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
url: opts.get("url").and_then(|t| t.decode().ok()).unwrap_or_default(),
detail: opts.get("detail").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct DocumentContent {
pub data: String,
pub media_type: String,
}
impl DocumentContent {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
data: opts.get("data").and_then(|t| t.decode().ok()).unwrap_or_default(),
media_type: opts.get("media_type").and_then(|t| t.decode().ok()).unwrap_or_default(),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct AudioContent {
pub data: String,
pub format: String,
}
impl AudioContent {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
data: opts.get("data").and_then(|t| t.decode().ok()).unwrap_or_default(),
format: opts.get("format").and_then(|t| t.decode().ok()).unwrap_or_default(),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct AssistantMessage {
pub content: Option<String>,
pub name: Option<String>,
pub tool_calls: Option<Vec<ToolCall>>,
pub refusal: Option<String>,
pub function_call: Option<FunctionCall>,
}
impl AssistantMessage {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
content: opts.get("content").and_then(|t| t.decode().ok()),
name: opts.get("name").and_then(|t| t.decode().ok()),
tool_calls: opts.get("tool_calls").and_then(|t| t.decode().ok()),
refusal: opts.get("refusal").and_then(|t| t.decode().ok()),
function_call: opts.get("function_call").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct ToolMessage {
pub content: String,
pub tool_call_id: String,
pub name: Option<String>,
}
impl ToolMessage {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
content: opts.get("content").and_then(|t| t.decode().ok()).unwrap_or_default(),
tool_call_id: opts
.get("tool_call_id")
.and_then(|t| t.decode().ok())
.unwrap_or_default(),
name: opts.get("name").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct DeveloperMessage {
pub content: String,
pub name: Option<String>,
}
impl DeveloperMessage {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
content: opts.get("content").and_then(|t| t.decode().ok()).unwrap_or_default(),
name: opts.get("name").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct FunctionMessage {
pub content: String,
pub name: String,
}
impl FunctionMessage {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
content: opts.get("content").and_then(|t| t.decode().ok()).unwrap_or_default(),
name: opts.get("name").and_then(|t| t.decode().ok()).unwrap_or_default(),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.ChatCompletionTool"]
pub struct ChatCompletionTool {
pub tool_type: ToolType,
pub function: FunctionDefinition,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.FunctionDefinition"]
pub struct FunctionDefinition {
pub name: String,
pub description: Option<String>,
pub parameters: Option<String>,
pub strict: Option<bool>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.ToolCall"]
pub struct ToolCall {
pub id: String,
pub call_type: ToolType,
pub function: FunctionCall,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.FunctionCall"]
pub struct FunctionCall {
pub name: String,
pub arguments: String,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct SpecificToolChoice {
pub choice_type: ToolType,
pub function: SpecificFunction,
}
impl SpecificToolChoice {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
choice_type: opts
.get("choice_type")
.and_then(|t| t.decode().ok())
.unwrap_or_default(),
function: opts.get("function").and_then(|t| t.decode().ok()).unwrap_or_default(),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct SpecificFunction {
pub name: String,
}
impl SpecificFunction {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
name: opts.get("name").and_then(|t| t.decode().ok()).unwrap_or_default(),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct JsonSchemaFormat {
pub name: String,
pub description: Option<String>,
pub schema: String,
pub strict: Option<bool>,
}
impl JsonSchemaFormat {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
name: opts.get("name").and_then(|t| t.decode().ok()).unwrap_or_default(),
description: opts.get("description").and_then(|t| t.decode().ok()),
schema: opts.get("schema").and_then(|t| t.decode().ok()).unwrap_or_default(),
strict: opts.get("strict").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct Usage {
pub prompt_tokens: u64,
pub completion_tokens: u64,
pub total_tokens: u64,
}
impl Usage {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
prompt_tokens: opts
.get("prompt_tokens")
.and_then(|t| t.decode().ok())
.unwrap_or_default(),
completion_tokens: opts
.get("completion_tokens")
.and_then(|t| t.decode().ok())
.unwrap_or_default(),
total_tokens: opts
.get("total_tokens")
.and_then(|t| t.decode().ok())
.unwrap_or_default(),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct ChatCompletionRequest {
pub model: String,
pub messages: Vec<Message>,
pub temperature: Option<f64>,
pub top_p: Option<f64>,
pub n: Option<u32>,
pub stream: Option<bool>,
pub stop: Option<StopSequence>,
pub max_tokens: Option<u64>,
pub presence_penalty: Option<f64>,
pub frequency_penalty: Option<f64>,
pub logit_bias: Option<HashMap<String, f64>>,
pub user: Option<String>,
pub tools: Option<Vec<ChatCompletionTool>>,
pub tool_choice: Option<ToolChoice>,
pub parallel_tool_calls: Option<bool>,
pub response_format: Option<ResponseFormat>,
pub stream_options: Option<StreamOptions>,
pub seed: Option<i64>,
pub reasoning_effort: Option<ReasoningEffort>,
pub extra_body: Option<String>,
}
impl ChatCompletionRequest {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
model: opts.get("model").and_then(|t| t.decode().ok()).unwrap_or_default(),
messages: opts.get("messages").and_then(|t| t.decode().ok()).unwrap_or_default(),
temperature: opts.get("temperature").and_then(|t| t.decode().ok()),
top_p: opts.get("top_p").and_then(|t| t.decode().ok()),
n: opts.get("n").and_then(|t| t.decode().ok()),
stream: opts.get("stream").and_then(|t| t.decode().ok()),
stop: opts.get("stop").and_then(|t| t.decode().ok()),
max_tokens: opts.get("max_tokens").and_then(|t| t.decode().ok()),
presence_penalty: opts.get("presence_penalty").and_then(|t| t.decode().ok()),
frequency_penalty: opts.get("frequency_penalty").and_then(|t| t.decode().ok()),
logit_bias: opts.get("logit_bias").and_then(|t| t.decode().ok()),
user: opts.get("user").and_then(|t| t.decode().ok()),
tools: opts.get("tools").and_then(|t| t.decode().ok()),
tool_choice: opts.get("tool_choice").and_then(|t| t.decode().ok()),
parallel_tool_calls: opts.get("parallel_tool_calls").and_then(|t| t.decode().ok()),
response_format: opts.get("response_format").and_then(|t| t.decode().ok()),
stream_options: opts.get("stream_options").and_then(|t| t.decode().ok()),
seed: opts.get("seed").and_then(|t| t.decode().ok()),
reasoning_effort: opts.get("reasoning_effort").and_then(|t| t.decode().ok()),
extra_body: opts.get("extra_body").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct StreamOptions {
pub include_usage: Option<bool>,
}
impl StreamOptions {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
include_usage: opts.get("include_usage").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct ChatCompletionResponse {
pub id: String,
pub object: String,
pub created: u64,
pub model: String,
pub choices: Vec<Choice>,
pub usage: Option<Usage>,
pub system_fingerprint: Option<String>,
pub service_tier: Option<String>,
}
impl ChatCompletionResponse {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
id: opts.get("id").and_then(|t| t.decode().ok()).unwrap_or_default(),
object: opts.get("object").and_then(|t| t.decode().ok()).unwrap_or_default(),
created: opts.get("created").and_then(|t| t.decode().ok()).unwrap_or_default(),
model: opts.get("model").and_then(|t| t.decode().ok()).unwrap_or_default(),
choices: opts.get("choices").and_then(|t| t.decode().ok()).unwrap_or_default(),
usage: opts.get("usage").and_then(|t| t.decode().ok()),
system_fingerprint: opts.get("system_fingerprint").and_then(|t| t.decode().ok()),
service_tier: opts.get("service_tier").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct Choice {
pub index: u32,
pub message: AssistantMessage,
pub finish_reason: Option<FinishReason>,
}
impl Choice {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
index: opts.get("index").and_then(|t| t.decode().ok()).unwrap_or_default(),
message: opts.get("message").and_then(|t| t.decode().ok()).unwrap_or_default(),
finish_reason: opts.get("finish_reason").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct ChatCompletionChunk {
pub id: String,
pub object: String,
pub created: u64,
pub model: String,
pub choices: Vec<StreamChoice>,
pub usage: Option<Usage>,
pub system_fingerprint: Option<String>,
pub service_tier: Option<String>,
}
impl ChatCompletionChunk {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
id: opts.get("id").and_then(|t| t.decode().ok()).unwrap_or_default(),
object: opts.get("object").and_then(|t| t.decode().ok()).unwrap_or_default(),
created: opts.get("created").and_then(|t| t.decode().ok()).unwrap_or_default(),
model: opts.get("model").and_then(|t| t.decode().ok()).unwrap_or_default(),
choices: opts.get("choices").and_then(|t| t.decode().ok()).unwrap_or_default(),
usage: opts.get("usage").and_then(|t| t.decode().ok()),
system_fingerprint: opts.get("system_fingerprint").and_then(|t| t.decode().ok()),
service_tier: opts.get("service_tier").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct StreamChoice {
pub index: u32,
pub delta: StreamDelta,
pub finish_reason: Option<FinishReason>,
}
impl StreamChoice {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
index: opts.get("index").and_then(|t| t.decode().ok()).unwrap_or_default(),
delta: opts.get("delta").and_then(|t| t.decode().ok()).unwrap_or_default(),
finish_reason: opts.get("finish_reason").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct StreamDelta {
pub role: Option<String>,
pub content: Option<String>,
pub tool_calls: Option<Vec<StreamToolCall>>,
pub function_call: Option<StreamFunctionCall>,
pub refusal: Option<String>,
}
impl StreamDelta {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
role: opts.get("role").and_then(|t| t.decode().ok()),
content: opts.get("content").and_then(|t| t.decode().ok()),
tool_calls: opts.get("tool_calls").and_then(|t| t.decode().ok()),
function_call: opts.get("function_call").and_then(|t| t.decode().ok()),
refusal: opts.get("refusal").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct StreamToolCall {
pub index: u32,
pub id: Option<String>,
pub call_type: Option<ToolType>,
pub function: Option<StreamFunctionCall>,
}
impl StreamToolCall {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
index: opts.get("index").and_then(|t| t.decode().ok()).unwrap_or_default(),
id: opts.get("id").and_then(|t| t.decode().ok()),
call_type: opts.get("call_type").and_then(|t| t.decode().ok()),
function: opts.get("function").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct StreamFunctionCall {
pub name: Option<String>,
pub arguments: Option<String>,
}
impl StreamFunctionCall {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
name: opts.get("name").and_then(|t| t.decode().ok()),
arguments: opts.get("arguments").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.EmbeddingRequest"]
pub struct EmbeddingRequest {
pub model: String,
pub input: EmbeddingInput,
pub encoding_format: Option<EmbeddingFormat>,
pub dimensions: Option<u32>,
pub user: Option<String>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.EmbeddingResponse"]
pub struct EmbeddingResponse {
pub object: String,
pub data: Vec<EmbeddingObject>,
pub model: String,
pub usage: Option<Usage>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.EmbeddingObject"]
pub struct EmbeddingObject {
pub object: String,
pub embedding: Vec<f64>,
pub index: u32,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct CreateImageRequest {
pub prompt: String,
pub model: Option<String>,
pub n: Option<u32>,
pub size: Option<String>,
pub quality: Option<String>,
pub style: Option<String>,
pub response_format: Option<String>,
pub user: Option<String>,
}
impl CreateImageRequest {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
prompt: opts.get("prompt").and_then(|t| t.decode().ok()).unwrap_or_default(),
model: opts.get("model").and_then(|t| t.decode().ok()),
n: opts.get("n").and_then(|t| t.decode().ok()),
size: opts.get("size").and_then(|t| t.decode().ok()),
quality: opts.get("quality").and_then(|t| t.decode().ok()),
style: opts.get("style").and_then(|t| t.decode().ok()),
response_format: opts.get("response_format").and_then(|t| t.decode().ok()),
user: opts.get("user").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct ImagesResponse {
pub created: u64,
pub data: Vec<Image>,
}
impl ImagesResponse {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
created: opts.get("created").and_then(|t| t.decode().ok()).unwrap_or_default(),
data: opts.get("data").and_then(|t| t.decode().ok()).unwrap_or_default(),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct Image {
pub url: Option<String>,
pub b64_json: Option<String>,
pub revised_prompt: Option<String>,
}
impl Image {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
url: opts.get("url").and_then(|t| t.decode().ok()),
b64_json: opts.get("b64_json").and_then(|t| t.decode().ok()),
revised_prompt: opts.get("revised_prompt").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct CreateSpeechRequest {
pub model: String,
pub input: String,
pub voice: String,
pub response_format: Option<String>,
pub speed: Option<f64>,
}
impl CreateSpeechRequest {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
model: opts.get("model").and_then(|t| t.decode().ok()).unwrap_or_default(),
input: opts.get("input").and_then(|t| t.decode().ok()).unwrap_or_default(),
voice: opts.get("voice").and_then(|t| t.decode().ok()).unwrap_or_default(),
response_format: opts.get("response_format").and_then(|t| t.decode().ok()),
speed: opts.get("speed").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct CreateTranscriptionRequest {
pub model: String,
pub file: String,
pub language: Option<String>,
pub prompt: Option<String>,
pub response_format: Option<String>,
pub temperature: Option<f64>,
}
impl CreateTranscriptionRequest {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
model: opts.get("model").and_then(|t| t.decode().ok()).unwrap_or_default(),
file: opts.get("file").and_then(|t| t.decode().ok()).unwrap_or_default(),
language: opts.get("language").and_then(|t| t.decode().ok()),
prompt: opts.get("prompt").and_then(|t| t.decode().ok()),
response_format: opts.get("response_format").and_then(|t| t.decode().ok()),
temperature: opts.get("temperature").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct TranscriptionResponse {
pub text: String,
pub language: Option<String>,
pub duration: Option<f64>,
pub segments: Option<Vec<TranscriptionSegment>>,
}
impl TranscriptionResponse {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
text: opts.get("text").and_then(|t| t.decode().ok()).unwrap_or_default(),
language: opts.get("language").and_then(|t| t.decode().ok()),
duration: opts.get("duration").and_then(|t| t.decode().ok()),
segments: opts.get("segments").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct TranscriptionSegment {
pub id: u32,
pub start: f64,
pub end: f64,
pub text: String,
}
impl TranscriptionSegment {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
id: opts.get("id").and_then(|t| t.decode().ok()).unwrap_or_default(),
start: opts.get("start").and_then(|t| t.decode().ok()).unwrap_or_default(),
end: opts.get("end").and_then(|t| t.decode().ok()).unwrap_or_default(),
text: opts.get("text").and_then(|t| t.decode().ok()).unwrap_or_default(),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.ModerationRequest"]
pub struct ModerationRequest {
pub input: ModerationInput,
pub model: Option<String>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.ModerationResponse"]
pub struct ModerationResponse {
pub id: String,
pub model: String,
pub results: Vec<ModerationResult>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.ModerationResult"]
pub struct ModerationResult {
pub flagged: bool,
pub categories: ModerationCategories,
pub category_scores: ModerationCategoryScores,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.ModerationCategories"]
pub struct ModerationCategories {
pub sexual: bool,
pub hate: bool,
pub harassment: bool,
pub self_harm: bool,
pub sexual_minors: bool,
pub hate_threatening: bool,
pub violence_graphic: bool,
pub self_harm_intent: bool,
pub self_harm_instructions: bool,
pub harassment_threatening: bool,
pub violence: bool,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.ModerationCategoryScores"]
pub struct ModerationCategoryScores {
pub sexual: f64,
pub hate: f64,
pub harassment: f64,
pub self_harm: f64,
pub sexual_minors: f64,
pub hate_threatening: f64,
pub violence_graphic: f64,
pub self_harm_intent: f64,
pub self_harm_instructions: f64,
pub harassment_threatening: f64,
pub violence: f64,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.RerankRequest"]
pub struct RerankRequest {
pub model: String,
pub query: String,
pub documents: Vec<RerankDocument>,
pub top_n: Option<u32>,
pub return_documents: Option<bool>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.RerankResponse"]
pub struct RerankResponse {
pub id: Option<String>,
pub results: Vec<RerankResult>,
pub meta: Option<String>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.RerankResult"]
pub struct RerankResult {
pub index: u32,
pub relevance_score: f64,
pub document: Option<RerankResultDocument>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.RerankResultDocument"]
pub struct RerankResultDocument {
pub text: String,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct SearchRequest {
pub model: String,
pub query: String,
pub max_results: Option<u32>,
pub search_domain_filter: Option<Vec<String>>,
pub country: Option<String>,
}
impl SearchRequest {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
model: opts.get("model").and_then(|t| t.decode().ok()).unwrap_or_default(),
query: opts.get("query").and_then(|t| t.decode().ok()).unwrap_or_default(),
max_results: opts.get("max_results").and_then(|t| t.decode().ok()),
search_domain_filter: opts.get("search_domain_filter").and_then(|t| t.decode().ok()),
country: opts.get("country").and_then(|t| t.decode().ok()),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.SearchResponse"]
pub struct SearchResponse {
pub results: Vec<SearchResult>,
pub model: String,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.SearchResult"]
pub struct SearchResult {
pub title: String,
pub url: String,
pub snippet: String,
pub date: Option<String>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.OcrRequest"]
pub struct OcrRequest {
pub model: String,
pub document: OcrDocument,
pub pages: Option<Vec<u32>>,
pub include_image_base64: Option<bool>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.OcrResponse"]
pub struct OcrResponse {
pub pages: Vec<OcrPage>,
pub model: String,
pub usage: Option<Usage>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.OcrPage"]
pub struct OcrPage {
pub index: u32,
pub markdown: String,
pub images: Option<Vec<OcrImage>>,
pub dimensions: Option<PageDimensions>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.OcrImage"]
pub struct OcrImage {
pub id: String,
pub image_base64: Option<String>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.PageDimensions"]
pub struct PageDimensions {
pub width: u32,
pub height: u32,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct ModelsListResponse {
pub object: String,
pub data: Vec<ModelObject>,
}
impl ModelsListResponse {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
object: opts.get("object").and_then(|t| t.decode().ok()).unwrap_or_default(),
data: opts.get("data").and_then(|t| t.decode().ok()).unwrap_or_default(),
}
}
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifMap)]
pub struct ModelObject {
pub id: String,
pub object: String,
pub created: u64,
pub owned_by: String,
}
impl ModelObject {
pub fn new(opts: std::collections::HashMap<String, rustler::Term>) -> Self {
Self {
id: opts.get("id").and_then(|t| t.decode().ok()).unwrap_or_default(),
object: opts.get("object").and_then(|t| t.decode().ok()).unwrap_or_default(),
created: opts.get("created").and_then(|t| t.decode().ok()).unwrap_or_default(),
owned_by: opts.get("owned_by").and_then(|t| t.decode().ok()).unwrap_or_default(),
}
}
}
#[derive(Clone)]
pub struct DefaultClient {
inner: Arc<liter_llm::client::DefaultClient>,
}
// SAFETY: See gen_opaque_resource in alef-backend-rustler for rationale.
impl std::panic::RefUnwindSafe for DefaultClient {}
impl rustler::Resource for DefaultClient {}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, rustler::NifStruct)]
#[module = "LiterLlm.CustomProviderConfig"]
pub struct CustomProviderConfig {
pub name: String,
pub base_url: String,
pub auth_header: AuthHeaderFormat,
pub model_prefixes: Vec<String>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rustler::NifTaggedEnum)]
#[serde(tag = "role")]
pub enum Message {
System { _0: SystemMessage },
User { _0: UserMessage },
Assistant { _0: AssistantMessage },
Tool { _0: ToolMessage },
Developer { _0: DeveloperMessage },
Function { _0: FunctionMessage },
}
#[allow(clippy::derivable_impls)]
impl Default for Message {
fn default() -> Self {
Self::System { _0: Default::default() }
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rustler::NifTaggedEnum)]
pub enum UserContent {
Text { _0: String },
Parts { _0: Vec<ContentPart> },
}
#[allow(clippy::derivable_impls)]
impl Default for UserContent {
fn default() -> Self {
Self::Text { _0: Default::default() }
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rustler::NifTaggedEnum)]
#[serde(tag = "type")]
pub enum ContentPart {
Text { text: String },
ImageUrl { image_url: ImageUrl },
Document { document: DocumentContent },
InputAudio { input_audio: AudioContent },
}
#[allow(clippy::derivable_impls)]
impl Default for ContentPart {
fn default() -> Self {
Self::Text {
text: Default::default(),
}
}
}
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, rustler::NifUnitEnum)]
pub enum ImageDetail {
Low,
High,
Auto,
}
#[allow(clippy::derivable_impls)]
impl Default for ImageDetail {
fn default() -> Self {
Self::Low
}
}
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, rustler::NifUnitEnum)]
pub enum ToolType {
Function,
}
#[allow(clippy::derivable_impls)]
impl Default for ToolType {
fn default() -> Self {
Self::Function
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rustler::NifTaggedEnum)]
pub enum ToolChoice {
Mode { _0: ToolChoiceMode },
Specific { _0: SpecificToolChoice },
}
#[allow(clippy::derivable_impls)]
impl Default for ToolChoice {
fn default() -> Self {
Self::Mode { _0: Default::default() }
}
}
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, rustler::NifUnitEnum)]
pub enum ToolChoiceMode {
Auto,
Required,
None,
}
#[allow(clippy::derivable_impls)]
impl Default for ToolChoiceMode {
fn default() -> Self {
Self::Auto
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rustler::NifTaggedEnum)]
#[serde(tag = "type")]
pub enum ResponseFormat {
Text,
JsonObject,
JsonSchema { json_schema: JsonSchemaFormat },
}
#[allow(clippy::derivable_impls)]
impl Default for ResponseFormat {
fn default() -> Self {
Self::Text
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rustler::NifTaggedEnum)]
pub enum StopSequence {
Single { _0: String },
Multiple { _0: Vec<String> },
}
#[allow(clippy::derivable_impls)]
impl Default for StopSequence {
fn default() -> Self {
Self::Single { _0: Default::default() }
}
}
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, rustler::NifUnitEnum)]
pub enum FinishReason {
Stop,
Length,
ToolCalls,
ContentFilter,
FunctionCall,
Other,
}
#[allow(clippy::derivable_impls)]
impl Default for FinishReason {
fn default() -> Self {
Self::Stop
}
}
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, rustler::NifUnitEnum)]
pub enum ReasoningEffort {
Low,
Medium,
High,
}
#[allow(clippy::derivable_impls)]
impl Default for ReasoningEffort {
fn default() -> Self {
Self::Low
}
}
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, rustler::NifUnitEnum)]
pub enum EmbeddingFormat {
Float,
Base64,
}
#[allow(clippy::derivable_impls)]
impl Default for EmbeddingFormat {
fn default() -> Self {
Self::Float
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rustler::NifTaggedEnum)]
pub enum EmbeddingInput {
Single { _0: String },
Multiple { _0: Vec<String> },
}
#[allow(clippy::derivable_impls)]
impl Default for EmbeddingInput {
fn default() -> Self {
Self::Single { _0: Default::default() }
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rustler::NifTaggedEnum)]
pub enum ModerationInput {
Single { _0: String },
Multiple { _0: Vec<String> },
}
#[allow(clippy::derivable_impls)]
impl Default for ModerationInput {
fn default() -> Self {
Self::Single { _0: Default::default() }
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rustler::NifTaggedEnum)]
pub enum RerankDocument {
Text { _0: String },
Object { text: String },
}
#[allow(clippy::derivable_impls)]
impl Default for RerankDocument {
fn default() -> Self {
Self::Text { _0: Default::default() }
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rustler::NifTaggedEnum)]
#[serde(tag = "type")]
pub enum OcrDocument {
Url { url: String },
Base64 { data: String, media_type: String },
}
#[allow(clippy::derivable_impls)]
impl Default for OcrDocument {
fn default() -> Self {
Self::Url {
url: Default::default(),
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rustler::NifTaggedEnum)]
pub enum AuthHeaderFormat {
Bearer,
ApiKey { _0: String },
None,
}
#[allow(clippy::derivable_impls)]
impl Default for AuthHeaderFormat {
fn default() -> Self {
Self::Bearer
}
}
/// Create a new LLM client with simple scalar configuration.
///
/// This is the primary binding entry-point. All parameters except `api_key`
/// are optional — omitting them uses the same defaults as
/// [`ClientConfigBuilder`].
///
/// # Errors
///
/// Returns [`LiterLlmError`] if the underlying HTTP client cannot be
/// constructed, or if the resolved provider configuration is invalid.
#[rustler::nif]
pub fn create_client(
api_key: String,
base_url: Option<String>,
timeout_secs: Option<u64>,
max_retries: Option<u32>,
model_hint: Option<String>,
) -> Result<ResourceArc<DefaultClient>, String> {
let result = liter_llm::bindings::create_client(api_key, base_url, timeout_secs, max_retries, model_hint)
.map_err(|e| e.to_string())?;
Ok(ResourceArc::new(DefaultClient {
inner: Arc::new(result),
}))
}
/// Create a new LLM client from a JSON string.
///
/// The JSON object accepts the same fields as `liter-llm.toml` (snake_case).
///
/// # Errors
///
/// Returns [`LiterLlmError::BadRequest`] if `json` is not valid JSON or
/// contains unknown fields.
#[rustler::nif]
pub fn create_client_from_json(json: String) -> Result<ResourceArc<DefaultClient>, String> {
let result = liter_llm::bindings::create_client_from_json(&json).map_err(|e| e.to_string())?;
Ok(ResourceArc::new(DefaultClient {
inner: Arc::new(result),
}))
}
/// Register a custom provider in the global runtime registry.
///
/// The provider will be checked **before** all built-in providers during model
/// detection. If a provider with the same `name` already exists it is replaced.
///
/// # Errors
///
/// Returns an error if the config is invalid (empty name, empty base_url, or
/// no model prefixes).
#[rustler::nif]
pub fn register_custom_provider(config: CustomProviderConfig) -> Result<(), String> {
let result = liter_llm::provider::custom::register_custom_provider(config.into()).map_err(|e| e.to_string())?;
Ok(result)
}
/// Remove a previously registered custom provider by name.
///
/// Returns `true` if a provider with the given name was found and removed,
/// `false` if no such provider existed.
///
/// # Errors
///
/// Returns an error only if the internal lock is poisoned.
#[rustler::nif]
pub fn unregister_custom_provider(name: String) -> Result<bool, String> {
let result = liter_llm::provider::custom::unregister_custom_provider(&name).map_err(|e| e.to_string())?;
Ok(result)
}
#[rustler::nif(schedule = "DirtyCpu")]
pub fn defaultclient_chat_async(
resource: rustler::ResourceArc<DefaultClient>,
req: ChatCompletionRequest,
) -> Result<ChatCompletionResponse, String> {
let rt = tokio::runtime::Runtime::new().map_err(|e| e.to_string())?;
let result = rt
.block_on(async { resource.inner.chat(req.into()).await })
.map_err(|e| e.to_string())?;
Ok(result.into())
}
#[rustler::nif(schedule = "DirtyCpu")]
pub fn defaultclient_chat_stream_async(
resource: rustler::ResourceArc<DefaultClient>,
req: ChatCompletionRequest,
) -> Result<String, String> {
use futures_util::StreamExt;
let rt = tokio::runtime::Runtime::new().map_err(|e| e.to_string())?;
let core_req: liter_llm::ChatCompletionRequest = req.into();
rt.block_on(async {
let stream = resource.inner.chat_stream(core_req).await.map_err(|e| e.to_string())?;
let chunks: Vec<ChatCompletionChunk> = stream
.collect::<Vec<_>>()
.await
.into_iter()
.collect::<std::result::Result<Vec<_>, _>>()
.map(|v| v.into_iter().map(ChatCompletionChunk::from).collect())
.map_err(|e| e.to_string())?;
serde_json::to_string(&chunks).map_err(|e| e.to_string())
})
}
#[rustler::nif(schedule = "DirtyCpu")]
pub fn defaultclient_embed_async(
resource: rustler::ResourceArc<DefaultClient>,
req: EmbeddingRequest,
) -> Result<EmbeddingResponse, String> {
let rt = tokio::runtime::Runtime::new().map_err(|e| e.to_string())?;
let result = rt
.block_on(async { resource.inner.embed(req.into()).await })
.map_err(|e| e.to_string())?;
Ok(result.into())
}
#[rustler::nif(schedule = "DirtyCpu")]
pub fn defaultclient_list_models_async(
resource: rustler::ResourceArc<DefaultClient>,
) -> Result<ModelsListResponse, String> {
let rt = tokio::runtime::Runtime::new().map_err(|e| e.to_string())?;
let result = rt
.block_on(async { resource.inner.list_models().await })
.map_err(|e| e.to_string())?;
Ok(result.into())
}
#[rustler::nif(schedule = "DirtyCpu")]
pub fn defaultclient_image_generate_async(
resource: rustler::ResourceArc<DefaultClient>,
req: CreateImageRequest,
) -> Result<ImagesResponse, String> {
let rt = tokio::runtime::Runtime::new().map_err(|e| e.to_string())?;
let result = rt
.block_on(async { resource.inner.image_generate(req.into()).await })
.map_err(|e| e.to_string())?;
Ok(result.into())
}
#[rustler::nif(schedule = "DirtyCpu")]
pub fn defaultclient_transcribe_async(
resource: rustler::ResourceArc<DefaultClient>,
req: CreateTranscriptionRequest,
) -> Result<TranscriptionResponse, String> {
let rt = tokio::runtime::Runtime::new().map_err(|e| e.to_string())?;
let result = rt
.block_on(async { resource.inner.transcribe(req.into()).await })
.map_err(|e| e.to_string())?;
Ok(result.into())
}
#[rustler::nif(schedule = "DirtyCpu")]
pub fn defaultclient_moderate_async(
resource: rustler::ResourceArc<DefaultClient>,
req: ModerationRequest,
) -> Result<ModerationResponse, String> {
let rt = tokio::runtime::Runtime::new().map_err(|e| e.to_string())?;
let result = rt
.block_on(async { resource.inner.moderate(req.into()).await })
.map_err(|e| e.to_string())?;
Ok(result.into())
}
#[rustler::nif(schedule = "DirtyCpu")]
pub fn defaultclient_rerank_async(
resource: rustler::ResourceArc<DefaultClient>,
req: RerankRequest,
) -> Result<RerankResponse, String> {
let rt = tokio::runtime::Runtime::new().map_err(|e| e.to_string())?;
let result = rt
.block_on(async { resource.inner.rerank(req.into()).await })
.map_err(|e| e.to_string())?;
Ok(result.into())
}
#[rustler::nif(schedule = "DirtyCpu")]
pub fn defaultclient_search_async(
resource: rustler::ResourceArc<DefaultClient>,
req: SearchRequest,
) -> Result<SearchResponse, String> {
let rt = tokio::runtime::Runtime::new().map_err(|e| e.to_string())?;
let result = rt
.block_on(async { resource.inner.search(req.into()).await })
.map_err(|e| e.to_string())?;
Ok(result.into())
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<SystemMessage> for liter_llm::types::SystemMessage {
fn from(val: SystemMessage) -> Self {
Self {
content: val.content,
name: val.name,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::SystemMessage> for SystemMessage {
fn from(val: liter_llm::types::SystemMessage) -> Self {
Self {
content: val.content,
name: val.name,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<UserMessage> for liter_llm::types::UserMessage {
fn from(val: UserMessage) -> Self {
Self {
content: val.content.into(),
name: val.name,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::UserMessage> for UserMessage {
fn from(val: liter_llm::types::UserMessage) -> Self {
Self {
content: val.content.into(),
name: val.name,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ImageUrl> for liter_llm::types::ImageUrl {
fn from(val: ImageUrl) -> Self {
Self {
url: val.url,
detail: val.detail.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ImageUrl> for ImageUrl {
fn from(val: liter_llm::types::ImageUrl) -> Self {
Self {
url: val.url,
detail: val.detail.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<DocumentContent> for liter_llm::types::DocumentContent {
fn from(val: DocumentContent) -> Self {
Self {
data: val.data,
media_type: val.media_type,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::DocumentContent> for DocumentContent {
fn from(val: liter_llm::types::DocumentContent) -> Self {
Self {
data: val.data,
media_type: val.media_type,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<AudioContent> for liter_llm::types::AudioContent {
fn from(val: AudioContent) -> Self {
Self {
data: val.data,
format: val.format,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::AudioContent> for AudioContent {
fn from(val: liter_llm::types::AudioContent) -> Self {
Self {
data: val.data,
format: val.format,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<AssistantMessage> for liter_llm::types::AssistantMessage {
fn from(val: AssistantMessage) -> Self {
Self {
content: val.content,
name: val.name,
tool_calls: val.tool_calls.map(|v| v.into_iter().map(Into::into).collect()),
refusal: val.refusal,
function_call: val.function_call.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::AssistantMessage> for AssistantMessage {
fn from(val: liter_llm::types::AssistantMessage) -> Self {
Self {
content: val.content,
name: val.name,
tool_calls: val.tool_calls.map(|v| v.into_iter().map(Into::into).collect()),
refusal: val.refusal,
function_call: val.function_call.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ToolMessage> for liter_llm::types::ToolMessage {
fn from(val: ToolMessage) -> Self {
Self {
content: val.content,
tool_call_id: val.tool_call_id,
name: val.name,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ToolMessage> for ToolMessage {
fn from(val: liter_llm::types::ToolMessage) -> Self {
Self {
content: val.content,
tool_call_id: val.tool_call_id,
name: val.name,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<DeveloperMessage> for liter_llm::types::DeveloperMessage {
fn from(val: DeveloperMessage) -> Self {
Self {
content: val.content,
name: val.name,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::DeveloperMessage> for DeveloperMessage {
fn from(val: liter_llm::types::DeveloperMessage) -> Self {
Self {
content: val.content,
name: val.name,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<FunctionMessage> for liter_llm::types::FunctionMessage {
fn from(val: FunctionMessage) -> Self {
Self {
content: val.content,
name: val.name,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::FunctionMessage> for FunctionMessage {
fn from(val: liter_llm::types::FunctionMessage) -> Self {
Self {
content: val.content,
name: val.name,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ChatCompletionTool> for liter_llm::types::ChatCompletionTool {
fn from(val: ChatCompletionTool) -> Self {
Self {
tool_type: val.tool_type.into(),
function: val.function.into(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ChatCompletionTool> for ChatCompletionTool {
fn from(val: liter_llm::types::ChatCompletionTool) -> Self {
Self {
tool_type: val.tool_type.into(),
function: val.function.into(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<FunctionDefinition> for liter_llm::types::FunctionDefinition {
fn from(val: FunctionDefinition) -> Self {
Self {
name: val.name,
description: val.description,
parameters: val.parameters.as_ref().and_then(|s| serde_json::from_str(s).ok()),
strict: val.strict,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::FunctionDefinition> for FunctionDefinition {
fn from(val: liter_llm::types::FunctionDefinition) -> Self {
Self {
name: val.name,
description: val.description,
parameters: val.parameters.as_ref().map(ToString::to_string),
strict: val.strict,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ToolCall> for liter_llm::types::ToolCall {
fn from(val: ToolCall) -> Self {
Self {
id: val.id,
call_type: val.call_type.into(),
function: val.function.into(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ToolCall> for ToolCall {
fn from(val: liter_llm::types::ToolCall) -> Self {
Self {
id: val.id,
call_type: val.call_type.into(),
function: val.function.into(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<FunctionCall> for liter_llm::types::FunctionCall {
fn from(val: FunctionCall) -> Self {
Self {
name: val.name,
arguments: val.arguments,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::FunctionCall> for FunctionCall {
fn from(val: liter_llm::types::FunctionCall) -> Self {
Self {
name: val.name,
arguments: val.arguments,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<SpecificToolChoice> for liter_llm::types::SpecificToolChoice {
fn from(val: SpecificToolChoice) -> Self {
Self {
choice_type: val.choice_type.into(),
function: val.function.into(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::SpecificToolChoice> for SpecificToolChoice {
fn from(val: liter_llm::types::SpecificToolChoice) -> Self {
Self {
choice_type: val.choice_type.into(),
function: val.function.into(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<SpecificFunction> for liter_llm::types::SpecificFunction {
fn from(val: SpecificFunction) -> Self {
Self { name: val.name }
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::SpecificFunction> for SpecificFunction {
fn from(val: liter_llm::types::SpecificFunction) -> Self {
Self { name: val.name }
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<JsonSchemaFormat> for liter_llm::types::JsonSchemaFormat {
fn from(val: JsonSchemaFormat) -> Self {
Self {
name: val.name,
description: val.description,
schema: serde_json::from_str(&val.schema).unwrap_or_default(),
strict: val.strict,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::JsonSchemaFormat> for JsonSchemaFormat {
fn from(val: liter_llm::types::JsonSchemaFormat) -> Self {
Self {
name: val.name,
description: val.description,
schema: val.schema.to_string(),
strict: val.strict,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<Usage> for liter_llm::types::Usage {
fn from(val: Usage) -> Self {
Self {
prompt_tokens: val.prompt_tokens,
completion_tokens: val.completion_tokens,
total_tokens: val.total_tokens,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::Usage> for Usage {
fn from(val: liter_llm::types::Usage) -> Self {
Self {
prompt_tokens: val.prompt_tokens,
completion_tokens: val.completion_tokens,
total_tokens: val.total_tokens,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ChatCompletionRequest> for liter_llm::types::ChatCompletionRequest {
fn from(val: ChatCompletionRequest) -> Self {
Self {
model: val.model,
messages: val.messages.into_iter().map(Into::into).collect(),
temperature: val.temperature,
top_p: val.top_p,
n: val.n,
stream: val.stream,
stop: val.stop.map(Into::into),
max_tokens: val.max_tokens,
presence_penalty: val.presence_penalty,
frequency_penalty: val.frequency_penalty,
logit_bias: val.logit_bias.map(|m| m.into_iter().collect()),
user: val.user,
tools: val.tools.map(|v| v.into_iter().map(Into::into).collect()),
tool_choice: val.tool_choice.map(Into::into),
parallel_tool_calls: val.parallel_tool_calls,
response_format: val.response_format.map(Into::into),
stream_options: val.stream_options.map(Into::into),
seed: val.seed,
reasoning_effort: val.reasoning_effort.map(Into::into),
extra_body: val.extra_body.as_ref().and_then(|s| serde_json::from_str(s).ok()),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ChatCompletionRequest> for ChatCompletionRequest {
fn from(val: liter_llm::types::ChatCompletionRequest) -> Self {
Self {
model: val.model,
messages: val.messages.into_iter().map(Into::into).collect(),
temperature: val.temperature,
top_p: val.top_p,
n: val.n,
stream: val.stream,
stop: val.stop.map(Into::into),
max_tokens: val.max_tokens,
presence_penalty: val.presence_penalty,
frequency_penalty: val.frequency_penalty,
logit_bias: val.logit_bias.map(|m| m.into_iter().collect()),
user: val.user,
tools: val.tools.map(|v| v.into_iter().map(Into::into).collect()),
tool_choice: val.tool_choice.map(Into::into),
parallel_tool_calls: val.parallel_tool_calls,
response_format: val.response_format.map(Into::into),
stream_options: val.stream_options.map(Into::into),
seed: val.seed,
reasoning_effort: val.reasoning_effort.map(Into::into),
extra_body: val.extra_body.as_ref().map(ToString::to_string),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<StreamOptions> for liter_llm::types::StreamOptions {
fn from(val: StreamOptions) -> Self {
Self {
include_usage: val.include_usage,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::StreamOptions> for StreamOptions {
fn from(val: liter_llm::types::StreamOptions) -> Self {
Self {
include_usage: val.include_usage,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ChatCompletionResponse> for liter_llm::types::ChatCompletionResponse {
fn from(val: ChatCompletionResponse) -> Self {
Self {
id: val.id,
object: val.object,
created: val.created,
model: val.model,
choices: val.choices.into_iter().map(Into::into).collect(),
usage: val.usage.map(Into::into),
system_fingerprint: val.system_fingerprint,
service_tier: val.service_tier,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ChatCompletionResponse> for ChatCompletionResponse {
fn from(val: liter_llm::types::ChatCompletionResponse) -> Self {
Self {
id: val.id,
object: val.object,
created: val.created,
model: val.model,
choices: val.choices.into_iter().map(Into::into).collect(),
usage: val.usage.map(Into::into),
system_fingerprint: val.system_fingerprint,
service_tier: val.service_tier,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<Choice> for liter_llm::types::Choice {
fn from(val: Choice) -> Self {
Self {
index: val.index,
message: val.message.into(),
finish_reason: val.finish_reason.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::Choice> for Choice {
fn from(val: liter_llm::types::Choice) -> Self {
Self {
index: val.index,
message: val.message.into(),
finish_reason: val.finish_reason.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ChatCompletionChunk> for ChatCompletionChunk {
fn from(val: liter_llm::types::ChatCompletionChunk) -> Self {
Self {
id: val.id,
object: val.object,
created: val.created,
model: val.model,
choices: val.choices.into_iter().map(Into::into).collect(),
usage: val.usage.map(Into::into),
system_fingerprint: val.system_fingerprint,
service_tier: val.service_tier,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::StreamChoice> for StreamChoice {
fn from(val: liter_llm::types::StreamChoice) -> Self {
Self {
index: val.index,
delta: val.delta.into(),
finish_reason: val.finish_reason.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::StreamDelta> for StreamDelta {
fn from(val: liter_llm::types::StreamDelta) -> Self {
Self {
role: val.role,
content: val.content,
tool_calls: val.tool_calls.map(|v| v.into_iter().map(Into::into).collect()),
function_call: val.function_call.map(Into::into),
refusal: val.refusal,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::StreamToolCall> for StreamToolCall {
fn from(val: liter_llm::types::StreamToolCall) -> Self {
Self {
index: val.index,
id: val.id,
call_type: val.call_type.map(Into::into),
function: val.function.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::StreamFunctionCall> for StreamFunctionCall {
fn from(val: liter_llm::types::StreamFunctionCall) -> Self {
Self {
name: val.name,
arguments: val.arguments,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<EmbeddingRequest> for liter_llm::types::EmbeddingRequest {
fn from(val: EmbeddingRequest) -> Self {
Self {
model: val.model,
input: val.input.into(),
encoding_format: val.encoding_format.map(Into::into),
dimensions: val.dimensions,
user: val.user,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::EmbeddingRequest> for EmbeddingRequest {
fn from(val: liter_llm::types::EmbeddingRequest) -> Self {
Self {
model: val.model,
input: val.input.into(),
encoding_format: val.encoding_format.map(Into::into),
dimensions: val.dimensions,
user: val.user,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<EmbeddingResponse> for liter_llm::types::EmbeddingResponse {
fn from(val: EmbeddingResponse) -> Self {
Self {
object: val.object,
data: val.data.into_iter().map(Into::into).collect(),
model: val.model,
usage: val.usage.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::EmbeddingResponse> for EmbeddingResponse {
fn from(val: liter_llm::types::EmbeddingResponse) -> Self {
Self {
object: val.object,
data: val.data.into_iter().map(Into::into).collect(),
model: val.model,
usage: val.usage.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<EmbeddingObject> for liter_llm::types::EmbeddingObject {
fn from(val: EmbeddingObject) -> Self {
Self {
object: val.object,
embedding: val.embedding,
index: val.index,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::EmbeddingObject> for EmbeddingObject {
fn from(val: liter_llm::types::EmbeddingObject) -> Self {
Self {
object: val.object,
embedding: val.embedding,
index: val.index,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<CreateImageRequest> for liter_llm::types::CreateImageRequest {
fn from(val: CreateImageRequest) -> Self {
Self {
prompt: val.prompt,
model: val.model,
n: val.n,
size: val.size,
quality: val.quality,
style: val.style,
response_format: val.response_format,
user: val.user,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::CreateImageRequest> for CreateImageRequest {
fn from(val: liter_llm::types::CreateImageRequest) -> Self {
Self {
prompt: val.prompt,
model: val.model,
n: val.n,
size: val.size,
quality: val.quality,
style: val.style,
response_format: val.response_format,
user: val.user,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ImagesResponse> for liter_llm::types::ImagesResponse {
fn from(val: ImagesResponse) -> Self {
Self {
created: val.created,
data: val.data.into_iter().map(Into::into).collect(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ImagesResponse> for ImagesResponse {
fn from(val: liter_llm::types::ImagesResponse) -> Self {
Self {
created: val.created,
data: val.data.into_iter().map(Into::into).collect(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<Image> for liter_llm::types::Image {
fn from(val: Image) -> Self {
Self {
url: val.url,
b64_json: val.b64_json,
revised_prompt: val.revised_prompt,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::Image> for Image {
fn from(val: liter_llm::types::Image) -> Self {
Self {
url: val.url,
b64_json: val.b64_json,
revised_prompt: val.revised_prompt,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::CreateSpeechRequest> for CreateSpeechRequest {
fn from(val: liter_llm::types::CreateSpeechRequest) -> Self {
Self {
model: val.model,
input: val.input,
voice: val.voice,
response_format: val.response_format,
speed: val.speed,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<CreateTranscriptionRequest> for liter_llm::types::CreateTranscriptionRequest {
fn from(val: CreateTranscriptionRequest) -> Self {
Self {
model: val.model,
file: val.file,
language: val.language,
prompt: val.prompt,
response_format: val.response_format,
temperature: val.temperature,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::CreateTranscriptionRequest> for CreateTranscriptionRequest {
fn from(val: liter_llm::types::CreateTranscriptionRequest) -> Self {
Self {
model: val.model,
file: val.file,
language: val.language,
prompt: val.prompt,
response_format: val.response_format,
temperature: val.temperature,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<TranscriptionResponse> for liter_llm::types::TranscriptionResponse {
fn from(val: TranscriptionResponse) -> Self {
Self {
text: val.text,
language: val.language,
duration: val.duration,
segments: val.segments.map(|v| v.into_iter().map(Into::into).collect()),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::TranscriptionResponse> for TranscriptionResponse {
fn from(val: liter_llm::types::TranscriptionResponse) -> Self {
Self {
text: val.text,
language: val.language,
duration: val.duration,
segments: val.segments.map(|v| v.into_iter().map(Into::into).collect()),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<TranscriptionSegment> for liter_llm::types::TranscriptionSegment {
fn from(val: TranscriptionSegment) -> Self {
Self {
id: val.id,
start: val.start,
end: val.end,
text: val.text,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::TranscriptionSegment> for TranscriptionSegment {
fn from(val: liter_llm::types::TranscriptionSegment) -> Self {
Self {
id: val.id,
start: val.start,
end: val.end,
text: val.text,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ModerationRequest> for liter_llm::types::ModerationRequest {
fn from(val: ModerationRequest) -> Self {
Self {
input: val.input.into(),
model: val.model,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ModerationRequest> for ModerationRequest {
fn from(val: liter_llm::types::ModerationRequest) -> Self {
Self {
input: val.input.into(),
model: val.model,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ModerationResponse> for liter_llm::types::ModerationResponse {
fn from(val: ModerationResponse) -> Self {
Self {
id: val.id,
model: val.model,
results: val.results.into_iter().map(Into::into).collect(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ModerationResponse> for ModerationResponse {
fn from(val: liter_llm::types::ModerationResponse) -> Self {
Self {
id: val.id,
model: val.model,
results: val.results.into_iter().map(Into::into).collect(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ModerationResult> for liter_llm::types::ModerationResult {
fn from(val: ModerationResult) -> Self {
Self {
flagged: val.flagged,
categories: val.categories.into(),
category_scores: val.category_scores.into(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ModerationResult> for ModerationResult {
fn from(val: liter_llm::types::ModerationResult) -> Self {
Self {
flagged: val.flagged,
categories: val.categories.into(),
category_scores: val.category_scores.into(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ModerationCategories> for liter_llm::types::ModerationCategories {
fn from(val: ModerationCategories) -> Self {
Self {
sexual: val.sexual,
hate: val.hate,
harassment: val.harassment,
self_harm: val.self_harm,
sexual_minors: val.sexual_minors,
hate_threatening: val.hate_threatening,
violence_graphic: val.violence_graphic,
self_harm_intent: val.self_harm_intent,
self_harm_instructions: val.self_harm_instructions,
harassment_threatening: val.harassment_threatening,
violence: val.violence,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ModerationCategories> for ModerationCategories {
fn from(val: liter_llm::types::ModerationCategories) -> Self {
Self {
sexual: val.sexual,
hate: val.hate,
harassment: val.harassment,
self_harm: val.self_harm,
sexual_minors: val.sexual_minors,
hate_threatening: val.hate_threatening,
violence_graphic: val.violence_graphic,
self_harm_intent: val.self_harm_intent,
self_harm_instructions: val.self_harm_instructions,
harassment_threatening: val.harassment_threatening,
violence: val.violence,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ModerationCategoryScores> for liter_llm::types::ModerationCategoryScores {
fn from(val: ModerationCategoryScores) -> Self {
Self {
sexual: val.sexual,
hate: val.hate,
harassment: val.harassment,
self_harm: val.self_harm,
sexual_minors: val.sexual_minors,
hate_threatening: val.hate_threatening,
violence_graphic: val.violence_graphic,
self_harm_intent: val.self_harm_intent,
self_harm_instructions: val.self_harm_instructions,
harassment_threatening: val.harassment_threatening,
violence: val.violence,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ModerationCategoryScores> for ModerationCategoryScores {
fn from(val: liter_llm::types::ModerationCategoryScores) -> Self {
Self {
sexual: val.sexual,
hate: val.hate,
harassment: val.harassment,
self_harm: val.self_harm,
sexual_minors: val.sexual_minors,
hate_threatening: val.hate_threatening,
violence_graphic: val.violence_graphic,
self_harm_intent: val.self_harm_intent,
self_harm_instructions: val.self_harm_instructions,
harassment_threatening: val.harassment_threatening,
violence: val.violence,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<RerankRequest> for liter_llm::types::RerankRequest {
fn from(val: RerankRequest) -> Self {
Self {
model: val.model,
query: val.query,
documents: val.documents.into_iter().map(Into::into).collect(),
top_n: val.top_n,
return_documents: val.return_documents,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::RerankRequest> for RerankRequest {
fn from(val: liter_llm::types::RerankRequest) -> Self {
Self {
model: val.model,
query: val.query,
documents: val.documents.into_iter().map(Into::into).collect(),
top_n: val.top_n,
return_documents: val.return_documents,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<RerankResponse> for liter_llm::types::RerankResponse {
fn from(val: RerankResponse) -> Self {
Self {
id: val.id,
results: val.results.into_iter().map(Into::into).collect(),
meta: val.meta.as_ref().and_then(|s| serde_json::from_str(s).ok()),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::RerankResponse> for RerankResponse {
fn from(val: liter_llm::types::RerankResponse) -> Self {
Self {
id: val.id,
results: val.results.into_iter().map(Into::into).collect(),
meta: val.meta.as_ref().map(ToString::to_string),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<RerankResult> for liter_llm::types::RerankResult {
fn from(val: RerankResult) -> Self {
Self {
index: val.index,
relevance_score: val.relevance_score,
document: val.document.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::RerankResult> for RerankResult {
fn from(val: liter_llm::types::RerankResult) -> Self {
Self {
index: val.index,
relevance_score: val.relevance_score,
document: val.document.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<RerankResultDocument> for liter_llm::types::RerankResultDocument {
fn from(val: RerankResultDocument) -> Self {
Self { text: val.text }
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::RerankResultDocument> for RerankResultDocument {
fn from(val: liter_llm::types::RerankResultDocument) -> Self {
Self { text: val.text }
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<SearchRequest> for liter_llm::types::SearchRequest {
fn from(val: SearchRequest) -> Self {
Self {
model: val.model,
query: val.query,
max_results: val.max_results,
search_domain_filter: val.search_domain_filter,
country: val.country,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::SearchRequest> for SearchRequest {
fn from(val: liter_llm::types::SearchRequest) -> Self {
Self {
model: val.model,
query: val.query,
max_results: val.max_results,
search_domain_filter: val.search_domain_filter,
country: val.country,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<SearchResponse> for liter_llm::types::SearchResponse {
fn from(val: SearchResponse) -> Self {
Self {
results: val.results.into_iter().map(Into::into).collect(),
model: val.model,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::SearchResponse> for SearchResponse {
fn from(val: liter_llm::types::SearchResponse) -> Self {
Self {
results: val.results.into_iter().map(Into::into).collect(),
model: val.model,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<SearchResult> for liter_llm::types::SearchResult {
fn from(val: SearchResult) -> Self {
Self {
title: val.title,
url: val.url,
snippet: val.snippet,
date: val.date,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::SearchResult> for SearchResult {
fn from(val: liter_llm::types::SearchResult) -> Self {
Self {
title: val.title,
url: val.url,
snippet: val.snippet,
date: val.date,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::OcrRequest> for OcrRequest {
fn from(val: liter_llm::types::OcrRequest) -> Self {
Self {
model: val.model,
document: val.document.into(),
pages: val.pages,
include_image_base64: val.include_image_base64,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::OcrResponse> for OcrResponse {
fn from(val: liter_llm::types::OcrResponse) -> Self {
Self {
pages: val.pages.into_iter().map(Into::into).collect(),
model: val.model,
usage: val.usage.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::OcrPage> for OcrPage {
fn from(val: liter_llm::types::OcrPage) -> Self {
Self {
index: val.index,
markdown: val.markdown,
images: val.images.map(|v| v.into_iter().map(Into::into).collect()),
dimensions: val.dimensions.map(Into::into),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::OcrImage> for OcrImage {
fn from(val: liter_llm::types::OcrImage) -> Self {
Self {
id: val.id,
image_base64: val.image_base64,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::PageDimensions> for PageDimensions {
fn from(val: liter_llm::types::PageDimensions) -> Self {
Self {
width: val.width,
height: val.height,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ModelsListResponse> for liter_llm::types::ModelsListResponse {
fn from(val: ModelsListResponse) -> Self {
Self {
object: val.object,
data: val.data.into_iter().map(Into::into).collect(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ModelsListResponse> for ModelsListResponse {
fn from(val: liter_llm::types::ModelsListResponse) -> Self {
Self {
object: val.object,
data: val.data.into_iter().map(Into::into).collect(),
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<ModelObject> for liter_llm::types::ModelObject {
fn from(val: ModelObject) -> Self {
Self {
id: val.id,
object: val.object,
created: val.created,
owned_by: val.owned_by,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::types::ModelObject> for ModelObject {
fn from(val: liter_llm::types::ModelObject) -> Self {
Self {
id: val.id,
object: val.object,
created: val.created,
owned_by: val.owned_by,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<CustomProviderConfig> for liter_llm::provider::custom::CustomProviderConfig {
fn from(val: CustomProviderConfig) -> Self {
Self {
name: val.name,
base_url: val.base_url,
auth_header: val.auth_header.into(),
model_prefixes: val.model_prefixes,
}
}
}
#[allow(clippy::redundant_closure, clippy::useless_conversion)]
impl From<liter_llm::provider::custom::CustomProviderConfig> for CustomProviderConfig {
fn from(val: liter_llm::provider::custom::CustomProviderConfig) -> Self {
Self {
name: val.name,
base_url: val.base_url,
auth_header: val.auth_header.into(),
model_prefixes: val.model_prefixes,
}
}
}
impl From<Message> for liter_llm::types::Message {
fn from(val: Message) -> Self {
match val {
Message::System { _0 } => Self::System(_0.into()),
Message::User { _0 } => Self::User(_0.into()),
Message::Assistant { _0 } => Self::Assistant(_0.into()),
Message::Tool { _0 } => Self::Tool(_0.into()),
Message::Developer { _0 } => Self::Developer(_0.into()),
Message::Function { _0 } => Self::Function(_0.into()),
}
}
}
impl From<liter_llm::types::Message> for Message {
fn from(val: liter_llm::types::Message) -> Self {
match val {
liter_llm::types::Message::System(_0) => Self::System { _0: _0.into() },
liter_llm::types::Message::User(_0) => Self::User { _0: _0.into() },
liter_llm::types::Message::Assistant(_0) => Self::Assistant { _0: _0.into() },
liter_llm::types::Message::Tool(_0) => Self::Tool { _0: _0.into() },
liter_llm::types::Message::Developer(_0) => Self::Developer { _0: _0.into() },
liter_llm::types::Message::Function(_0) => Self::Function { _0: _0.into() },
}
}
}
impl From<UserContent> for liter_llm::types::UserContent {
fn from(val: UserContent) -> Self {
match val {
UserContent::Text { _0 } => Self::Text(_0),
UserContent::Parts { _0 } => Self::Parts(_0.into_iter().map(Into::into).collect()),
}
}
}
impl From<liter_llm::types::UserContent> for UserContent {
fn from(val: liter_llm::types::UserContent) -> Self {
match val {
liter_llm::types::UserContent::Text(_0) => Self::Text { _0 },
liter_llm::types::UserContent::Parts(_0) => Self::Parts {
_0: _0.into_iter().map(Into::into).collect(),
},
}
}
}
impl From<ContentPart> for liter_llm::types::ContentPart {
fn from(val: ContentPart) -> Self {
match val {
ContentPart::Text { text } => Self::Text { text },
ContentPart::ImageUrl { image_url } => Self::ImageUrl {
image_url: image_url.into(),
},
ContentPart::Document { document } => Self::Document {
document: document.into(),
},
ContentPart::InputAudio { input_audio } => Self::InputAudio {
input_audio: input_audio.into(),
},
}
}
}
impl From<liter_llm::types::ContentPart> for ContentPart {
fn from(val: liter_llm::types::ContentPart) -> Self {
match val {
liter_llm::types::ContentPart::Text { text } => Self::Text { text },
liter_llm::types::ContentPart::ImageUrl { image_url } => Self::ImageUrl {
image_url: image_url.into(),
},
liter_llm::types::ContentPart::Document { document } => Self::Document {
document: document.into(),
},
liter_llm::types::ContentPart::InputAudio { input_audio } => Self::InputAudio {
input_audio: input_audio.into(),
},
}
}
}
impl From<ImageDetail> for liter_llm::types::ImageDetail {
fn from(val: ImageDetail) -> Self {
match val {
ImageDetail::Low => Self::Low,
ImageDetail::High => Self::High,
ImageDetail::Auto => Self::Auto,
}
}
}
impl From<liter_llm::types::ImageDetail> for ImageDetail {
fn from(val: liter_llm::types::ImageDetail) -> Self {
match val {
liter_llm::types::ImageDetail::Low => Self::Low,
liter_llm::types::ImageDetail::High => Self::High,
liter_llm::types::ImageDetail::Auto => Self::Auto,
}
}
}
impl From<ToolType> for liter_llm::types::ToolType {
fn from(val: ToolType) -> Self {
match val {
ToolType::Function => Self::Function,
}
}
}
impl From<liter_llm::types::ToolType> for ToolType {
fn from(val: liter_llm::types::ToolType) -> Self {
match val {
liter_llm::types::ToolType::Function => Self::Function,
}
}
}
impl From<ToolChoice> for liter_llm::types::ToolChoice {
fn from(val: ToolChoice) -> Self {
match val {
ToolChoice::Mode { _0 } => Self::Mode(_0.into()),
ToolChoice::Specific { _0 } => Self::Specific(_0.into()),
}
}
}
impl From<liter_llm::types::ToolChoice> for ToolChoice {
fn from(val: liter_llm::types::ToolChoice) -> Self {
match val {
liter_llm::types::ToolChoice::Mode(_0) => Self::Mode { _0: _0.into() },
liter_llm::types::ToolChoice::Specific(_0) => Self::Specific { _0: _0.into() },
}
}
}
impl From<ToolChoiceMode> for liter_llm::types::ToolChoiceMode {
fn from(val: ToolChoiceMode) -> Self {
match val {
ToolChoiceMode::Auto => Self::Auto,
ToolChoiceMode::Required => Self::Required,
ToolChoiceMode::None => Self::None,
}
}
}
impl From<liter_llm::types::ToolChoiceMode> for ToolChoiceMode {
fn from(val: liter_llm::types::ToolChoiceMode) -> Self {
match val {
liter_llm::types::ToolChoiceMode::Auto => Self::Auto,
liter_llm::types::ToolChoiceMode::Required => Self::Required,
liter_llm::types::ToolChoiceMode::None => Self::None,
}
}
}
impl From<ResponseFormat> for liter_llm::types::ResponseFormat {
fn from(val: ResponseFormat) -> Self {
match val {
ResponseFormat::Text => Self::Text,
ResponseFormat::JsonObject => Self::JsonObject,
ResponseFormat::JsonSchema { json_schema } => Self::JsonSchema {
json_schema: json_schema.into(),
},
}
}
}
impl From<liter_llm::types::ResponseFormat> for ResponseFormat {
fn from(val: liter_llm::types::ResponseFormat) -> Self {
match val {
liter_llm::types::ResponseFormat::Text => Self::Text,
liter_llm::types::ResponseFormat::JsonObject => Self::JsonObject,
liter_llm::types::ResponseFormat::JsonSchema { json_schema } => Self::JsonSchema {
json_schema: json_schema.into(),
},
}
}
}
impl From<StopSequence> for liter_llm::types::StopSequence {
fn from(val: StopSequence) -> Self {
match val {
StopSequence::Single { _0 } => Self::Single(_0),
StopSequence::Multiple { _0 } => Self::Multiple(_0),
}
}
}
impl From<liter_llm::types::StopSequence> for StopSequence {
fn from(val: liter_llm::types::StopSequence) -> Self {
match val {
liter_llm::types::StopSequence::Single(_0) => Self::Single { _0 },
liter_llm::types::StopSequence::Multiple(_0) => Self::Multiple { _0 },
}
}
}
impl From<FinishReason> for liter_llm::types::FinishReason {
fn from(val: FinishReason) -> Self {
match val {
FinishReason::Stop => Self::Stop,
FinishReason::Length => Self::Length,
FinishReason::ToolCalls => Self::ToolCalls,
FinishReason::ContentFilter => Self::ContentFilter,
FinishReason::FunctionCall => Self::FunctionCall,
FinishReason::Other => Self::Other,
}
}
}
impl From<liter_llm::types::FinishReason> for FinishReason {
fn from(val: liter_llm::types::FinishReason) -> Self {
match val {
liter_llm::types::FinishReason::Stop => Self::Stop,
liter_llm::types::FinishReason::Length => Self::Length,
liter_llm::types::FinishReason::ToolCalls => Self::ToolCalls,
liter_llm::types::FinishReason::ContentFilter => Self::ContentFilter,
liter_llm::types::FinishReason::FunctionCall => Self::FunctionCall,
liter_llm::types::FinishReason::Other => Self::Other,
}
}
}
impl From<ReasoningEffort> for liter_llm::types::ReasoningEffort {
fn from(val: ReasoningEffort) -> Self {
match val {
ReasoningEffort::Low => Self::Low,
ReasoningEffort::Medium => Self::Medium,
ReasoningEffort::High => Self::High,
}
}
}
impl From<liter_llm::types::ReasoningEffort> for ReasoningEffort {
fn from(val: liter_llm::types::ReasoningEffort) -> Self {
match val {
liter_llm::types::ReasoningEffort::Low => Self::Low,
liter_llm::types::ReasoningEffort::Medium => Self::Medium,
liter_llm::types::ReasoningEffort::High => Self::High,
}
}
}
impl From<EmbeddingFormat> for liter_llm::types::EmbeddingFormat {
fn from(val: EmbeddingFormat) -> Self {
match val {
EmbeddingFormat::Float => Self::Float,
EmbeddingFormat::Base64 => Self::Base64,
}
}
}
impl From<liter_llm::types::EmbeddingFormat> for EmbeddingFormat {
fn from(val: liter_llm::types::EmbeddingFormat) -> Self {
match val {
liter_llm::types::EmbeddingFormat::Float => Self::Float,
liter_llm::types::EmbeddingFormat::Base64 => Self::Base64,
}
}
}
impl From<EmbeddingInput> for liter_llm::types::EmbeddingInput {
fn from(val: EmbeddingInput) -> Self {
match val {
EmbeddingInput::Single { _0 } => Self::Single(_0),
EmbeddingInput::Multiple { _0 } => Self::Multiple(_0),
}
}
}
impl From<liter_llm::types::EmbeddingInput> for EmbeddingInput {
fn from(val: liter_llm::types::EmbeddingInput) -> Self {
match val {
liter_llm::types::EmbeddingInput::Single(_0) => Self::Single { _0 },
liter_llm::types::EmbeddingInput::Multiple(_0) => Self::Multiple { _0 },
}
}
}
impl From<ModerationInput> for liter_llm::types::ModerationInput {
fn from(val: ModerationInput) -> Self {
match val {
ModerationInput::Single { _0 } => Self::Single(_0),
ModerationInput::Multiple { _0 } => Self::Multiple(_0),
}
}
}
impl From<liter_llm::types::ModerationInput> for ModerationInput {
fn from(val: liter_llm::types::ModerationInput) -> Self {
match val {
liter_llm::types::ModerationInput::Single(_0) => Self::Single { _0 },
liter_llm::types::ModerationInput::Multiple(_0) => Self::Multiple { _0 },
}
}
}
impl From<RerankDocument> for liter_llm::types::RerankDocument {
fn from(val: RerankDocument) -> Self {
match val {
RerankDocument::Text { _0 } => Self::Text(_0),
RerankDocument::Object { text } => Self::Object { text },
}
}
}
impl From<liter_llm::types::RerankDocument> for RerankDocument {
fn from(val: liter_llm::types::RerankDocument) -> Self {
match val {
liter_llm::types::RerankDocument::Text(_0) => Self::Text { _0 },
liter_llm::types::RerankDocument::Object { text } => Self::Object { text },
}
}
}
impl From<liter_llm::types::OcrDocument> for OcrDocument {
fn from(val: liter_llm::types::OcrDocument) -> Self {
match val {
liter_llm::types::OcrDocument::Url { url } => Self::Url { url },
liter_llm::types::OcrDocument::Base64 { data, media_type } => Self::Base64 { data, media_type },
}
}
}
impl From<AuthHeaderFormat> for liter_llm::provider::custom::AuthHeaderFormat {
fn from(val: AuthHeaderFormat) -> Self {
match val {
AuthHeaderFormat::Bearer => Self::Bearer,
AuthHeaderFormat::ApiKey { _0 } => Self::ApiKey(_0),
AuthHeaderFormat::None => Self::None,
}
}
}
impl From<liter_llm::provider::custom::AuthHeaderFormat> for AuthHeaderFormat {
fn from(val: liter_llm::provider::custom::AuthHeaderFormat) -> Self {
match val {
liter_llm::provider::custom::AuthHeaderFormat::Bearer => Self::Bearer,
liter_llm::provider::custom::AuthHeaderFormat::ApiKey(_0) => Self::ApiKey { _0 },
liter_llm::provider::custom::AuthHeaderFormat::None => Self::None,
}
}
}
/// Convert a `liter_llm::error::LiterLlmError` error to a Rustler error string.
#[allow(dead_code)]
fn liter_llm_error_to_rustler_err(e: liter_llm::error::LiterLlmError) -> String {
e.to_string()
}
fn on_load(env: rustler::Env, _info: rustler::Term) -> bool {
env.register::<LiterLlmError>()
.expect("Failed to register resource type LiterLlmError");
env.register::<DefaultClient>()
.expect("Failed to register resource type DefaultClient");
true
}
rustler::init!("Elixir.LiterLlm.Native", load = on_load);