liter_llm 1.17.3 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -0
- data/ext/liter_llm_rb/native/Cargo.lock +5 -5
- data/ext/liter_llm_rb/native/Cargo.toml +20 -4
- data/ext/liter_llm_rb/native/extconf.rb +5 -0
- data/ext/liter_llm_rb/src/lib.rs +334 -55
- data/lib/liter_llm/native.rb +88 -1
- data/lib/liter_llm/version.rb +2 -2
- data/lib/liter_llm.rb +1 -1
- data/sig/types.rbs +24 -8
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c5bd204a264adbd698932331bb39e051c81aee3e41ec25694acabb29b0ca3fbb
|
|
4
|
+
data.tar.gz: 2435c21142430e5f33c6543e2c734000ba05520168f4cb0ebebad3f8da39bf5a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5766c2a1de94770d1753f5c2e766ab2640687cb7a027ebf60164c295b9bcff408537e3ae4842dc421e66d3fd454e70b62bdc0901c4c7f9dd7c624e8168861d44
|
|
7
|
+
data.tar.gz: dbb82f17c226cb866f70e57f8346b30a127e469b07271d325be21a58ccd1b1b35fcb05e003e0dbaba146cf0bedd4b1432a9099eab4d9b2a69ab2b754327f73ce
|
data/README.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
<!-- This file is auto-generated by alef — DO NOT EDIT. -->
|
|
2
|
+
<!-- alef:hash:cd144fa3684b490bac9fd3b39ee03cefb1f07fcfecec6d7599e0314be7d775e3 -->
|
|
3
|
+
<!-- To regenerate: alef readme -->
|
|
4
|
+
<!-- To verify freshness: alef verify -->
|
|
5
|
+
|
|
1
6
|
<p align="center">
|
|
2
7
|
<picture>
|
|
3
8
|
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.jsdelivr.net/gh/xberg-io/assets@v1/banner/readme-banner-dark.svg">
|
|
@@ -1794,9 +1794,9 @@ checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae"
|
|
|
1794
1794
|
|
|
1795
1795
|
[[package]]
|
|
1796
1796
|
name = "liter-llm"
|
|
1797
|
-
version = "1.
|
|
1797
|
+
version = "1.18.0"
|
|
1798
1798
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1799
|
-
checksum = "
|
|
1799
|
+
checksum = "de5d980b9ebe69c204ce3dfcd1fb5f01cf374d6ecd99f04f791b98faec0a1b27"
|
|
1800
1800
|
dependencies = [
|
|
1801
1801
|
"ahash 0.8.12",
|
|
1802
1802
|
"arc-swap",
|
|
@@ -1838,7 +1838,7 @@ dependencies = [
|
|
|
1838
1838
|
|
|
1839
1839
|
[[package]]
|
|
1840
1840
|
name = "liter-llm-rb"
|
|
1841
|
-
version = "1.
|
|
1841
|
+
version = "1.18.0"
|
|
1842
1842
|
dependencies = [
|
|
1843
1843
|
"futures",
|
|
1844
1844
|
"liter-llm",
|
|
@@ -2571,9 +2571,9 @@ dependencies = [
|
|
|
2571
2571
|
|
|
2572
2572
|
[[package]]
|
|
2573
2573
|
name = "rb-sys-build"
|
|
2574
|
-
version = "0.9.
|
|
2574
|
+
version = "0.9.130"
|
|
2575
2575
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2576
|
-
checksum = "
|
|
2576
|
+
checksum = "05be6f9c86fe5482808162826f6c047d093b3670582296c770de1d94f8066694"
|
|
2577
2577
|
dependencies = [
|
|
2578
2578
|
"bindgen",
|
|
2579
2579
|
"lazy_static",
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
# This file is auto-generated by alef — DO NOT EDIT.
|
|
2
|
+
# alef:hash:e221e01ba9179e68583cafd7161d7c43de4eacc42c13af77e2e5f1e4d63bc728
|
|
3
|
+
# To regenerate: alef generate
|
|
4
|
+
# To verify freshness: alef verify
|
|
5
|
+
|
|
1
6
|
[package]
|
|
2
7
|
name = "liter-llm-rb"
|
|
3
|
-
version = "1.
|
|
8
|
+
version = "1.18.0"
|
|
4
9
|
edition = "2024"
|
|
5
10
|
license = "MIT"
|
|
6
11
|
description = "Universal LLM API client with Rust-powered polyglot bindings."
|
|
@@ -17,18 +22,29 @@ path = "../src/lib.rs"
|
|
|
17
22
|
crate-type = ["cdylib"]
|
|
18
23
|
|
|
19
24
|
[features]
|
|
20
|
-
default = ["native-http", "opendal-cache", "
|
|
25
|
+
default = ["native-http", "opendal-cache", "tokenizer", "tower", "wasm-http"]
|
|
21
26
|
native-http = ["liter-llm/native-http"]
|
|
22
27
|
opendal-cache = ["liter-llm/opendal-cache"]
|
|
23
|
-
wasm-http = ["liter-llm/wasm-http"]
|
|
24
28
|
tokenizer = ["liter-llm/tokenizer"]
|
|
25
29
|
tower = ["liter-llm/tower"]
|
|
30
|
+
wasm-http = ["liter-llm/wasm-http"]
|
|
26
31
|
|
|
27
32
|
[dependencies]
|
|
28
33
|
futures = "0.3"
|
|
29
|
-
liter-llm = { version = "1.
|
|
34
|
+
liter-llm = { version = "1.18.0", features = ["native-http", "full"] }
|
|
30
35
|
magnus = "0.8"
|
|
31
36
|
rb-sys = ">=0.9, <0.9.128"
|
|
32
37
|
serde = { version = "1", features = ["derive"] }
|
|
33
38
|
serde_json = "1"
|
|
34
39
|
tokio = { version = "1", features = ["rt-multi-thread"] }
|
|
40
|
+
|
|
41
|
+
# This crate deliberately does not use `[lints]` / `workspace = true`: its C-ABI /
|
|
42
|
+
# PyO3 / napi / ext-php-rs / NIF boundary requires `unsafe` code, and the workspace's
|
|
43
|
+
# `[workspace.lints.rust]` sets `unsafe_code = "deny"` -- an all-or-nothing table that
|
|
44
|
+
# would turn every such boundary into a compile error. The `[lints.clippy]` block below
|
|
45
|
+
# instead carries the subset of the workspace's deny-by-default lint policy this crate
|
|
46
|
+
# can actually satisfy. ~keep
|
|
47
|
+
[lints.clippy]
|
|
48
|
+
dbg_macro = "deny"
|
|
49
|
+
print_stderr = "deny"
|
|
50
|
+
print_stdout = "deny"
|
data/ext/liter_llm_rb/src/lib.rs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// This file is auto-generated by alef. DO NOT EDIT.
|
|
2
|
-
// alef:hash:
|
|
2
|
+
// alef:hash:0e3211f6b85dad033da915446b280abf238ccc5297156d5b9c3942bc8c8bd78a
|
|
3
3
|
// Re-generate with: alef generate
|
|
4
4
|
#![allow(dead_code, unused_imports, unused_variables)]
|
|
5
5
|
#![allow(
|
|
@@ -6461,6 +6461,7 @@ pub struct LlmConfig {
|
|
|
6461
6461
|
cache: Option<LlmCacheConfig>,
|
|
6462
6462
|
budget: Option<LlmBudgetConfig>,
|
|
6463
6463
|
rate_limit: Option<LlmRateLimitConfig>,
|
|
6464
|
+
in_flight_limit: Option<LlmInFlightLimitConfig>,
|
|
6464
6465
|
cost_tracking: Option<bool>,
|
|
6465
6466
|
tracing: Option<bool>,
|
|
6466
6467
|
cooldown_secs: Option<u64>,
|
|
@@ -6549,6 +6550,9 @@ impl LlmConfig {
|
|
|
6549
6550
|
rate_limit: kwargs
|
|
6550
6551
|
.get(ruby.to_symbol("rate_limit"))
|
|
6551
6552
|
.and_then(|v| LlmRateLimitConfig::try_convert(v).ok()),
|
|
6553
|
+
in_flight_limit: kwargs
|
|
6554
|
+
.get(ruby.to_symbol("in_flight_limit"))
|
|
6555
|
+
.and_then(|v| LlmInFlightLimitConfig::try_convert(v).ok()),
|
|
6552
6556
|
cost_tracking: kwargs
|
|
6553
6557
|
.get(ruby.to_symbol("cost_tracking"))
|
|
6554
6558
|
.and_then(|v| bool::try_convert(v).ok()),
|
|
@@ -6619,6 +6623,10 @@ impl LlmConfig {
|
|
|
6619
6623
|
self.rate_limit.clone()
|
|
6620
6624
|
}
|
|
6621
6625
|
|
|
6626
|
+
fn in_flight_limit(&self) -> Option<LlmInFlightLimitConfig> {
|
|
6627
|
+
self.in_flight_limit.clone()
|
|
6628
|
+
}
|
|
6629
|
+
|
|
6622
6630
|
fn cost_tracking(&self) -> Option<bool> {
|
|
6623
6631
|
self.cost_tracking
|
|
6624
6632
|
}
|
|
@@ -6869,6 +6877,65 @@ impl LlmRateLimitConfig {
|
|
|
6869
6877
|
}
|
|
6870
6878
|
}
|
|
6871
6879
|
|
|
6880
|
+
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
|
6881
|
+
#[serde(default)]
|
|
6882
|
+
#[magnus::wrap(class = "LiterLlm::LlmInFlightLimitConfig")]
|
|
6883
|
+
pub struct LlmInFlightLimitConfig {
|
|
6884
|
+
max_in_flight: Option<usize>,
|
|
6885
|
+
}
|
|
6886
|
+
|
|
6887
|
+
unsafe impl IntoValueFromNative for LlmInFlightLimitConfig {}
|
|
6888
|
+
|
|
6889
|
+
impl magnus::TryConvert for LlmInFlightLimitConfig {
|
|
6890
|
+
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
6891
|
+
if let Ok(r) = <&LlmInFlightLimitConfig as magnus::TryConvert>::try_convert(val) {
|
|
6892
|
+
return Ok(r.clone());
|
|
6893
|
+
}
|
|
6894
|
+
let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
|
|
6895
|
+
s
|
|
6896
|
+
} else {
|
|
6897
|
+
val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
|
|
6898
|
+
magnus::Error::new(
|
|
6899
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
6900
|
+
format!("no implicit conversion into LlmInFlightLimitConfig: {}", e),
|
|
6901
|
+
)
|
|
6902
|
+
})?
|
|
6903
|
+
};
|
|
6904
|
+
serde_json::from_str::<LlmInFlightLimitConfig>(&json_str).map_err(|e| {
|
|
6905
|
+
magnus::Error::new(
|
|
6906
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
6907
|
+
format!("failed to deserialize LlmInFlightLimitConfig: {}", e),
|
|
6908
|
+
)
|
|
6909
|
+
})
|
|
6910
|
+
}
|
|
6911
|
+
}
|
|
6912
|
+
|
|
6913
|
+
unsafe impl TryConvertOwned for LlmInFlightLimitConfig {}
|
|
6914
|
+
|
|
6915
|
+
impl Default for LlmInFlightLimitConfig {
|
|
6916
|
+
fn default() -> Self {
|
|
6917
|
+
liter_llm::client::LlmInFlightLimitConfig::default().into()
|
|
6918
|
+
}
|
|
6919
|
+
}
|
|
6920
|
+
|
|
6921
|
+
impl LlmInFlightLimitConfig {
|
|
6922
|
+
fn new(args: &[magnus::Value]) -> Result<Self, magnus::Error> {
|
|
6923
|
+
let ruby = unsafe { magnus::Ruby::get_unchecked() };
|
|
6924
|
+
let args = magnus::scan_args::scan_args::<(), (Option<magnus::RHash>,), (), (), (), ()>(args)?;
|
|
6925
|
+
let (kwargs_opt,) = args.optional;
|
|
6926
|
+
let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
|
|
6927
|
+
Ok(Self {
|
|
6928
|
+
max_in_flight: kwargs
|
|
6929
|
+
.get(ruby.to_symbol("max_in_flight"))
|
|
6930
|
+
.and_then(|v| usize::try_convert(v).ok()),
|
|
6931
|
+
})
|
|
6932
|
+
}
|
|
6933
|
+
|
|
6934
|
+
fn max_in_flight(&self) -> Option<usize> {
|
|
6935
|
+
self.max_in_flight
|
|
6936
|
+
}
|
|
6937
|
+
}
|
|
6938
|
+
|
|
6872
6939
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
|
6873
6940
|
#[serde(default)]
|
|
6874
6941
|
#[magnus::wrap(class = "LiterLlm::LlmProviderConfig")]
|
|
@@ -8520,6 +8587,65 @@ unsafe impl TryConvertOwned for SingleflightResult {}
|
|
|
8520
8587
|
|
|
8521
8588
|
impl SingleflightResult {}
|
|
8522
8589
|
|
|
8590
|
+
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
|
8591
|
+
#[serde(default)]
|
|
8592
|
+
#[magnus::wrap(class = "LiterLlm::InFlightLimitConfig")]
|
|
8593
|
+
pub struct InFlightLimitConfig {
|
|
8594
|
+
max_in_flight: Option<usize>,
|
|
8595
|
+
}
|
|
8596
|
+
|
|
8597
|
+
unsafe impl IntoValueFromNative for InFlightLimitConfig {}
|
|
8598
|
+
|
|
8599
|
+
impl magnus::TryConvert for InFlightLimitConfig {
|
|
8600
|
+
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
8601
|
+
if let Ok(r) = <&InFlightLimitConfig as magnus::TryConvert>::try_convert(val) {
|
|
8602
|
+
return Ok(r.clone());
|
|
8603
|
+
}
|
|
8604
|
+
let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
|
|
8605
|
+
s
|
|
8606
|
+
} else {
|
|
8607
|
+
val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
|
|
8608
|
+
magnus::Error::new(
|
|
8609
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
8610
|
+
format!("no implicit conversion into InFlightLimitConfig: {}", e),
|
|
8611
|
+
)
|
|
8612
|
+
})?
|
|
8613
|
+
};
|
|
8614
|
+
serde_json::from_str::<InFlightLimitConfig>(&json_str).map_err(|e| {
|
|
8615
|
+
magnus::Error::new(
|
|
8616
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
8617
|
+
format!("failed to deserialize InFlightLimitConfig: {}", e),
|
|
8618
|
+
)
|
|
8619
|
+
})
|
|
8620
|
+
}
|
|
8621
|
+
}
|
|
8622
|
+
|
|
8623
|
+
unsafe impl TryConvertOwned for InFlightLimitConfig {}
|
|
8624
|
+
|
|
8625
|
+
impl Default for InFlightLimitConfig {
|
|
8626
|
+
fn default() -> Self {
|
|
8627
|
+
liter_llm::InFlightLimitConfig::default().into()
|
|
8628
|
+
}
|
|
8629
|
+
}
|
|
8630
|
+
|
|
8631
|
+
impl InFlightLimitConfig {
|
|
8632
|
+
fn new(args: &[magnus::Value]) -> Result<Self, magnus::Error> {
|
|
8633
|
+
let ruby = unsafe { magnus::Ruby::get_unchecked() };
|
|
8634
|
+
let args = magnus::scan_args::scan_args::<(), (Option<magnus::RHash>,), (), (), (), ()>(args)?;
|
|
8635
|
+
let (kwargs_opt,) = args.optional;
|
|
8636
|
+
let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
|
|
8637
|
+
Ok(Self {
|
|
8638
|
+
max_in_flight: kwargs
|
|
8639
|
+
.get(ruby.to_symbol("max_in_flight"))
|
|
8640
|
+
.and_then(|v| usize::try_convert(v).ok()),
|
|
8641
|
+
})
|
|
8642
|
+
}
|
|
8643
|
+
|
|
8644
|
+
fn max_in_flight(&self) -> Option<usize> {
|
|
8645
|
+
self.max_in_flight
|
|
8646
|
+
}
|
|
8647
|
+
}
|
|
8648
|
+
|
|
8523
8649
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
|
8524
8650
|
#[serde(default)]
|
|
8525
8651
|
#[magnus::wrap(class = "LiterLlm::RateLimitConfig")]
|
|
@@ -9006,8 +9132,9 @@ impl magnus::IntoValue for ImageDetail {
|
|
|
9006
9132
|
impl magnus::TryConvert for ImageDetail {
|
|
9007
9133
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
9008
9134
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
9009
|
-
// Accept the serde wire
|
|
9010
|
-
//
|
|
9135
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
9136
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
9137
|
+
// existing consumer code written in any of those styles keep working.
|
|
9011
9138
|
match s.as_str() {
|
|
9012
9139
|
"low" | "Low" => Ok(ImageDetail::Low),
|
|
9013
9140
|
"high" | "High" => Ok(ImageDetail::High),
|
|
@@ -9166,8 +9293,9 @@ impl magnus::IntoValue for ToolType {
|
|
|
9166
9293
|
impl magnus::TryConvert for ToolType {
|
|
9167
9294
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
9168
9295
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
9169
|
-
// Accept the serde wire
|
|
9170
|
-
//
|
|
9296
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
9297
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
9298
|
+
// existing consumer code written in any of those styles keep working.
|
|
9171
9299
|
match s.as_str() {
|
|
9172
9300
|
"function" | "Function" => Ok(ToolType::Function),
|
|
9173
9301
|
other => Err(magnus::Error::new(
|
|
@@ -9265,8 +9393,9 @@ impl magnus::IntoValue for ToolChoiceMode {
|
|
|
9265
9393
|
impl magnus::TryConvert for ToolChoiceMode {
|
|
9266
9394
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
9267
9395
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
9268
|
-
// Accept the serde wire
|
|
9269
|
-
//
|
|
9396
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
9397
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
9398
|
+
// existing consumer code written in any of those styles keep working.
|
|
9270
9399
|
match s.as_str() {
|
|
9271
9400
|
"auto" | "Auto" => Ok(ToolChoiceMode::Auto),
|
|
9272
9401
|
"required" | "Required" => Ok(ToolChoiceMode::Required),
|
|
@@ -9428,8 +9557,9 @@ impl magnus::IntoValue for Modality {
|
|
|
9428
9557
|
impl magnus::TryConvert for Modality {
|
|
9429
9558
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
9430
9559
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
9431
|
-
// Accept the serde wire
|
|
9432
|
-
//
|
|
9560
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
9561
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
9562
|
+
// existing consumer code written in any of those styles keep working.
|
|
9433
9563
|
match s.as_str() {
|
|
9434
9564
|
"text" | "Text" => Ok(Modality::Text),
|
|
9435
9565
|
"audio" | "Audio" => Ok(Modality::Audio),
|
|
@@ -9480,8 +9610,9 @@ impl magnus::IntoValue for FinishReason {
|
|
|
9480
9610
|
impl magnus::TryConvert for FinishReason {
|
|
9481
9611
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
9482
9612
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
9483
|
-
// Accept the serde wire
|
|
9484
|
-
//
|
|
9613
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
9614
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
9615
|
+
// existing consumer code written in any of those styles keep working.
|
|
9485
9616
|
match s.as_str() {
|
|
9486
9617
|
"stop" | "Stop" => Ok(FinishReason::Stop),
|
|
9487
9618
|
"length" | "Length" => Ok(FinishReason::Length),
|
|
@@ -9532,8 +9663,9 @@ impl magnus::IntoValue for ReasoningEffort {
|
|
|
9532
9663
|
impl magnus::TryConvert for ReasoningEffort {
|
|
9533
9664
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
9534
9665
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
9535
|
-
// Accept the serde wire
|
|
9536
|
-
//
|
|
9666
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
9667
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
9668
|
+
// existing consumer code written in any of those styles keep working.
|
|
9537
9669
|
match s.as_str() {
|
|
9538
9670
|
"low" | "Low" => Ok(ReasoningEffort::Low),
|
|
9539
9671
|
"medium" | "Medium" => Ok(ReasoningEffort::Medium),
|
|
@@ -9577,8 +9709,9 @@ impl magnus::IntoValue for EmbeddingFormat {
|
|
|
9577
9709
|
impl magnus::TryConvert for EmbeddingFormat {
|
|
9578
9710
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
9579
9711
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
9580
|
-
// Accept the serde wire
|
|
9581
|
-
//
|
|
9712
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
9713
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
9714
|
+
// existing consumer code written in any of those styles keep working.
|
|
9582
9715
|
match s.as_str() {
|
|
9583
9716
|
"float" | "Float" => Ok(EmbeddingFormat::Float),
|
|
9584
9717
|
"base64" | "Base64" => Ok(EmbeddingFormat::Base64),
|
|
@@ -9598,6 +9731,7 @@ unsafe impl TryConvertOwned for EmbeddingFormat {}
|
|
|
9598
9731
|
pub enum EmbeddingInput {
|
|
9599
9732
|
Single(String),
|
|
9600
9733
|
Multiple(Vec<String>),
|
|
9734
|
+
Multimodal(Vec<EmbeddingContentPart>),
|
|
9601
9735
|
}
|
|
9602
9736
|
|
|
9603
9737
|
impl Default for EmbeddingInput {
|
|
@@ -9649,6 +9783,70 @@ impl magnus::TryConvert for EmbeddingInput {
|
|
|
9649
9783
|
unsafe impl IntoValueFromNative for EmbeddingInput {}
|
|
9650
9784
|
unsafe impl TryConvertOwned for EmbeddingInput {}
|
|
9651
9785
|
|
|
9786
|
+
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
|
9787
|
+
#[serde(tag = "type")]
|
|
9788
|
+
pub enum EmbeddingContentPart {
|
|
9789
|
+
#[serde(rename = "text")]
|
|
9790
|
+
Text { text: String },
|
|
9791
|
+
#[serde(rename = "image_url")]
|
|
9792
|
+
ImageUrl { image_url: ImageUrl },
|
|
9793
|
+
#[serde(rename = "image_base64")]
|
|
9794
|
+
ImageBase64 { image_base64: String },
|
|
9795
|
+
}
|
|
9796
|
+
|
|
9797
|
+
impl Default for EmbeddingContentPart {
|
|
9798
|
+
fn default() -> Self {
|
|
9799
|
+
Self::Text {
|
|
9800
|
+
text: Default::default(),
|
|
9801
|
+
}
|
|
9802
|
+
}
|
|
9803
|
+
}
|
|
9804
|
+
|
|
9805
|
+
impl magnus::IntoValue for EmbeddingContentPart {
|
|
9806
|
+
fn into_value_with(self, handle: &Ruby) -> magnus::Value {
|
|
9807
|
+
match serde_json::to_value(&self) {
|
|
9808
|
+
Ok(v) => json_to_ruby(handle, v),
|
|
9809
|
+
Err(_) => handle.qnil().into_value_with(handle),
|
|
9810
|
+
}
|
|
9811
|
+
}
|
|
9812
|
+
}
|
|
9813
|
+
|
|
9814
|
+
impl magnus::TryConvert for EmbeddingContentPart {
|
|
9815
|
+
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
9816
|
+
// For data enums with fields (e.g., PageAction), try to deserialize from JSON first.
|
|
9817
|
+
// For unit enums or when passed as a string, fall back to string-based conversion.
|
|
9818
|
+
let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
|
|
9819
|
+
s
|
|
9820
|
+
} else {
|
|
9821
|
+
val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
|
|
9822
|
+
magnus::Error::new(
|
|
9823
|
+
unsafe { Ruby::get_unchecked() }.exception_type_error(),
|
|
9824
|
+
format!("no implicit conversion into EmbeddingContentPart: {}", e),
|
|
9825
|
+
)
|
|
9826
|
+
})?
|
|
9827
|
+
};
|
|
9828
|
+
// Try deserializing as JSON first (handles JSON strings like "\"markdown\"" or "{\"click\":{\"selector\":\"...\"}}\"")
|
|
9829
|
+
// For internally-tagged enums, a bare variant string is wrapped as {"<tag>": value}.
|
|
9830
|
+
// If that fails, try treating it as a plain string value and wrap in quotes
|
|
9831
|
+
// If both fail, try as Custom variant (for untagged enum support)
|
|
9832
|
+
serde_json::from_str(&json_str)
|
|
9833
|
+
.or_else(|_| serde_json::from_value(serde_json::json!({ "type": json_str })))
|
|
9834
|
+
.or_else(|_| serde_json::from_str(&format!("\"{json_str}\"")))
|
|
9835
|
+
.or_else(|_| {
|
|
9836
|
+
// Try as a JSON string for Custom variant (untagged enums accept any remaining value)
|
|
9837
|
+
match serde_json::to_value(&json_str) {
|
|
9838
|
+
Ok(val) => serde_json::from_value(val),
|
|
9839
|
+
Err(e) => Err(e),
|
|
9840
|
+
}
|
|
9841
|
+
})
|
|
9842
|
+
.map_err(|e| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_type_error(), e.to_string()))
|
|
9843
|
+
}
|
|
9844
|
+
}
|
|
9845
|
+
|
|
9846
|
+
unsafe impl IntoValueFromNative for EmbeddingContentPart {}
|
|
9847
|
+
unsafe impl TryConvertOwned for EmbeddingContentPart {}
|
|
9848
|
+
impl EmbeddingContentPart {}
|
|
9849
|
+
|
|
9652
9850
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
|
9653
9851
|
#[serde(untagged)]
|
|
9654
9852
|
pub enum ModerationInput {
|
|
@@ -9849,7 +10047,7 @@ impl magnus::IntoValue for FilePurpose {
|
|
|
9849
10047
|
let sym = match self {
|
|
9850
10048
|
FilePurpose::Assistants => "assistants",
|
|
9851
10049
|
FilePurpose::Batch => "batch",
|
|
9852
|
-
FilePurpose::FineTune => "
|
|
10050
|
+
FilePurpose::FineTune => "fine-tune",
|
|
9853
10051
|
FilePurpose::Vision => "vision",
|
|
9854
10052
|
};
|
|
9855
10053
|
handle.to_symbol(sym).into_value_with(handle)
|
|
@@ -9859,12 +10057,13 @@ impl magnus::IntoValue for FilePurpose {
|
|
|
9859
10057
|
impl magnus::TryConvert for FilePurpose {
|
|
9860
10058
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
9861
10059
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
9862
|
-
// Accept the serde wire
|
|
9863
|
-
//
|
|
10060
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
10061
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
10062
|
+
// existing consumer code written in any of those styles keep working.
|
|
9864
10063
|
match s.as_str() {
|
|
9865
10064
|
"assistants" | "Assistants" => Ok(FilePurpose::Assistants),
|
|
9866
10065
|
"batch" | "Batch" => Ok(FilePurpose::Batch),
|
|
9867
|
-
"fine_tune" | "FineTune" => Ok(FilePurpose::FineTune),
|
|
10066
|
+
"fine-tune" | "fine_tune" | "FineTune" => Ok(FilePurpose::FineTune),
|
|
9868
10067
|
"vision" | "Vision" => Ok(FilePurpose::Vision),
|
|
9869
10068
|
other => Err(magnus::Error::new(
|
|
9870
10069
|
unsafe { Ruby::get_unchecked() }.exception_arg_error(),
|
|
@@ -9915,8 +10114,9 @@ impl magnus::IntoValue for BatchStatus {
|
|
|
9915
10114
|
impl magnus::TryConvert for BatchStatus {
|
|
9916
10115
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
9917
10116
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
9918
|
-
// Accept the serde wire
|
|
9919
|
-
//
|
|
10117
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
10118
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
10119
|
+
// existing consumer code written in any of those styles keep working.
|
|
9920
10120
|
match s.as_str() {
|
|
9921
10121
|
"validating" | "Validating" => Ok(BatchStatus::Validating),
|
|
9922
10122
|
"failed" | "Failed" => Ok(BatchStatus::Failed),
|
|
@@ -10019,8 +10219,9 @@ impl magnus::IntoValue for StreamFormat {
|
|
|
10019
10219
|
impl magnus::TryConvert for StreamFormat {
|
|
10020
10220
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
10021
10221
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
10022
|
-
// Accept the serde wire
|
|
10023
|
-
//
|
|
10222
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
10223
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
10224
|
+
// existing consumer code written in any of those styles keep working.
|
|
10024
10225
|
match s.as_str() {
|
|
10025
10226
|
"sse" | "Sse" => Ok(StreamFormat::Sse),
|
|
10026
10227
|
"aws_event_stream" | "AwsEventStream" => Ok(StreamFormat::AwsEventStream),
|
|
@@ -10054,7 +10255,7 @@ impl magnus::IntoValue for AuthType {
|
|
|
10054
10255
|
fn into_value_with(self, handle: &Ruby) -> magnus::Value {
|
|
10055
10256
|
let sym = match self {
|
|
10056
10257
|
AuthType::Bearer => "bearer",
|
|
10057
|
-
AuthType::ApiKey => "
|
|
10258
|
+
AuthType::ApiKey => "api-key",
|
|
10058
10259
|
AuthType::None => "none",
|
|
10059
10260
|
AuthType::Unknown => "unknown",
|
|
10060
10261
|
};
|
|
@@ -10065,11 +10266,12 @@ impl magnus::IntoValue for AuthType {
|
|
|
10065
10266
|
impl magnus::TryConvert for AuthType {
|
|
10066
10267
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
10067
10268
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
10068
|
-
// Accept the serde wire
|
|
10069
|
-
//
|
|
10269
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
10270
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
10271
|
+
// existing consumer code written in any of those styles keep working.
|
|
10070
10272
|
match s.as_str() {
|
|
10071
10273
|
"bearer" | "Bearer" => Ok(AuthType::Bearer),
|
|
10072
|
-
"api_key" | "ApiKey" => Ok(AuthType::ApiKey),
|
|
10274
|
+
"api-key" | "api_key" | "ApiKey" => Ok(AuthType::ApiKey),
|
|
10073
10275
|
"none" | "None" => Ok(AuthType::None),
|
|
10074
10276
|
"unknown" | "Unknown" => Ok(AuthType::Unknown),
|
|
10075
10277
|
other => Err(magnus::Error::new(
|
|
@@ -10098,8 +10300,8 @@ impl Default for Enforcement {
|
|
|
10098
10300
|
impl magnus::IntoValue for Enforcement {
|
|
10099
10301
|
fn into_value_with(self, handle: &Ruby) -> magnus::Value {
|
|
10100
10302
|
let sym = match self {
|
|
10101
|
-
Enforcement::Hard => "
|
|
10102
|
-
Enforcement::Soft => "
|
|
10303
|
+
Enforcement::Hard => "Hard",
|
|
10304
|
+
Enforcement::Soft => "Soft",
|
|
10103
10305
|
};
|
|
10104
10306
|
handle.to_symbol(sym).into_value_with(handle)
|
|
10105
10307
|
}
|
|
@@ -10108,11 +10310,12 @@ impl magnus::IntoValue for Enforcement {
|
|
|
10108
10310
|
impl magnus::TryConvert for Enforcement {
|
|
10109
10311
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
10110
10312
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
10111
|
-
// Accept the serde wire
|
|
10112
|
-
//
|
|
10313
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
10314
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
10315
|
+
// existing consumer code written in any of those styles keep working.
|
|
10113
10316
|
match s.as_str() {
|
|
10114
|
-
"
|
|
10115
|
-
"
|
|
10317
|
+
"Hard" | "hard" => Ok(Enforcement::Hard),
|
|
10318
|
+
"Soft" | "soft" => Ok(Enforcement::Soft),
|
|
10116
10319
|
other => Err(magnus::Error::new(
|
|
10117
10320
|
unsafe { Ruby::get_unchecked() }.exception_arg_error(),
|
|
10118
10321
|
format!("invalid Enforcement value: {other}"),
|
|
@@ -10199,9 +10402,9 @@ impl Default for CircuitState {
|
|
|
10199
10402
|
impl magnus::IntoValue for CircuitState {
|
|
10200
10403
|
fn into_value_with(self, handle: &Ruby) -> magnus::Value {
|
|
10201
10404
|
let sym = match self {
|
|
10202
|
-
CircuitState::Closed => "
|
|
10203
|
-
CircuitState::Open => "
|
|
10204
|
-
CircuitState::HalfOpen => "
|
|
10405
|
+
CircuitState::Closed => "Closed",
|
|
10406
|
+
CircuitState::Open => "Open",
|
|
10407
|
+
CircuitState::HalfOpen => "HalfOpen",
|
|
10205
10408
|
};
|
|
10206
10409
|
handle.to_symbol(sym).into_value_with(handle)
|
|
10207
10410
|
}
|
|
@@ -10210,12 +10413,13 @@ impl magnus::IntoValue for CircuitState {
|
|
|
10210
10413
|
impl magnus::TryConvert for CircuitState {
|
|
10211
10414
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
10212
10415
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
10213
|
-
// Accept the serde wire
|
|
10214
|
-
//
|
|
10416
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
10417
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
10418
|
+
// existing consumer code written in any of those styles keep working.
|
|
10215
10419
|
match s.as_str() {
|
|
10216
|
-
"
|
|
10217
|
-
"
|
|
10218
|
-
"
|
|
10420
|
+
"Closed" | "closed" => Ok(CircuitState::Closed),
|
|
10421
|
+
"Open" | "open" => Ok(CircuitState::Open),
|
|
10422
|
+
"HalfOpen" | "half_open" => Ok(CircuitState::HalfOpen),
|
|
10219
10423
|
other => Err(magnus::Error::new(
|
|
10220
10424
|
unsafe { Ruby::get_unchecked() }.exception_arg_error(),
|
|
10221
10425
|
format!("invalid CircuitState value: {other}"),
|
|
@@ -10242,8 +10446,8 @@ impl Default for HealthStatus {
|
|
|
10242
10446
|
impl magnus::IntoValue for HealthStatus {
|
|
10243
10447
|
fn into_value_with(self, handle: &Ruby) -> magnus::Value {
|
|
10244
10448
|
let sym = match self {
|
|
10245
|
-
HealthStatus::Healthy => "
|
|
10246
|
-
HealthStatus::Unhealthy => "
|
|
10449
|
+
HealthStatus::Healthy => "Healthy",
|
|
10450
|
+
HealthStatus::Unhealthy => "Unhealthy",
|
|
10247
10451
|
};
|
|
10248
10452
|
handle.to_symbol(sym).into_value_with(handle)
|
|
10249
10453
|
}
|
|
@@ -10252,11 +10456,12 @@ impl magnus::IntoValue for HealthStatus {
|
|
|
10252
10456
|
impl magnus::TryConvert for HealthStatus {
|
|
10253
10457
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
10254
10458
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
10255
|
-
// Accept the serde wire
|
|
10256
|
-
//
|
|
10459
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
10460
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
10461
|
+
// existing consumer code written in any of those styles keep working.
|
|
10257
10462
|
match s.as_str() {
|
|
10258
|
-
"
|
|
10259
|
-
"
|
|
10463
|
+
"Healthy" | "healthy" => Ok(HealthStatus::Healthy),
|
|
10464
|
+
"Unhealthy" | "unhealthy" => Ok(HealthStatus::Unhealthy),
|
|
10260
10465
|
other => Err(magnus::Error::new(
|
|
10261
10466
|
unsafe { Ruby::get_unchecked() }.exception_arg_error(),
|
|
10262
10467
|
format!("invalid HealthStatus value: {other}"),
|
|
@@ -10284,9 +10489,9 @@ impl Default for RefreshOutcome {
|
|
|
10284
10489
|
impl magnus::IntoValue for RefreshOutcome {
|
|
10285
10490
|
fn into_value_with(self, handle: &Ruby) -> magnus::Value {
|
|
10286
10491
|
let sym = match self {
|
|
10287
|
-
RefreshOutcome::Disabled => "
|
|
10288
|
-
RefreshOutcome::FromCache => "
|
|
10289
|
-
RefreshOutcome::Fetched => "
|
|
10492
|
+
RefreshOutcome::Disabled => "Disabled",
|
|
10493
|
+
RefreshOutcome::FromCache => "FromCache",
|
|
10494
|
+
RefreshOutcome::Fetched => "Fetched",
|
|
10290
10495
|
};
|
|
10291
10496
|
handle.to_symbol(sym).into_value_with(handle)
|
|
10292
10497
|
}
|
|
@@ -10295,12 +10500,13 @@ impl magnus::IntoValue for RefreshOutcome {
|
|
|
10295
10500
|
impl magnus::TryConvert for RefreshOutcome {
|
|
10296
10501
|
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
10297
10502
|
let s: String = magnus::TryConvert::try_convert(val)?;
|
|
10298
|
-
// Accept the serde wire
|
|
10299
|
-
//
|
|
10503
|
+
// Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
|
|
10504
|
+
// emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
|
|
10505
|
+
// existing consumer code written in any of those styles keep working.
|
|
10300
10506
|
match s.as_str() {
|
|
10301
|
-
"
|
|
10302
|
-
"
|
|
10303
|
-
"
|
|
10507
|
+
"Disabled" | "disabled" => Ok(RefreshOutcome::Disabled),
|
|
10508
|
+
"FromCache" | "from_cache" => Ok(RefreshOutcome::FromCache),
|
|
10509
|
+
"Fetched" | "fetched" => Ok(RefreshOutcome::Fetched),
|
|
10304
10510
|
other => Err(magnus::Error::new(
|
|
10305
10511
|
unsafe { Ruby::get_unchecked() }.exception_arg_error(),
|
|
10306
10512
|
format!("invalid RefreshOutcome value: {other}"),
|
|
@@ -12374,6 +12580,7 @@ impl From<liter_llm::client::LlmConfig> for LlmConfig {
|
|
|
12374
12580
|
cache: val.cache.map(Into::into),
|
|
12375
12581
|
budget: val.budget.map(Into::into),
|
|
12376
12582
|
rate_limit: val.rate_limit.map(Into::into),
|
|
12583
|
+
in_flight_limit: val.in_flight_limit.map(Into::into),
|
|
12377
12584
|
cost_tracking: val.cost_tracking,
|
|
12378
12585
|
tracing: val.tracing,
|
|
12379
12586
|
cooldown_secs: val.cooldown_secs,
|
|
@@ -12459,6 +12666,24 @@ impl From<liter_llm::client::LlmRateLimitConfig> for LlmRateLimitConfig {
|
|
|
12459
12666
|
}
|
|
12460
12667
|
}
|
|
12461
12668
|
|
|
12669
|
+
#[allow(clippy::needless_update)]
|
|
12670
|
+
impl From<LlmInFlightLimitConfig> for liter_llm::client::LlmInFlightLimitConfig {
|
|
12671
|
+
fn from(val: LlmInFlightLimitConfig) -> Self {
|
|
12672
|
+
Self {
|
|
12673
|
+
max_in_flight: val.max_in_flight,
|
|
12674
|
+
..Default::default()
|
|
12675
|
+
}
|
|
12676
|
+
}
|
|
12677
|
+
}
|
|
12678
|
+
|
|
12679
|
+
impl From<liter_llm::client::LlmInFlightLimitConfig> for LlmInFlightLimitConfig {
|
|
12680
|
+
fn from(val: liter_llm::client::LlmInFlightLimitConfig) -> Self {
|
|
12681
|
+
Self {
|
|
12682
|
+
max_in_flight: val.max_in_flight,
|
|
12683
|
+
}
|
|
12684
|
+
}
|
|
12685
|
+
}
|
|
12686
|
+
|
|
12462
12687
|
#[allow(clippy::needless_update)]
|
|
12463
12688
|
impl From<LlmProviderConfig> for liter_llm::client::LlmProviderConfig {
|
|
12464
12689
|
fn from(val: LlmProviderConfig) -> Self {
|
|
@@ -12779,6 +13004,14 @@ impl From<liter_llm::CacheConfig> for CacheConfig {
|
|
|
12779
13004
|
}
|
|
12780
13005
|
}
|
|
12781
13006
|
|
|
13007
|
+
impl From<liter_llm::InFlightLimitConfig> for InFlightLimitConfig {
|
|
13008
|
+
fn from(val: liter_llm::InFlightLimitConfig) -> Self {
|
|
13009
|
+
Self {
|
|
13010
|
+
max_in_flight: val.max_in_flight,
|
|
13011
|
+
}
|
|
13012
|
+
}
|
|
13013
|
+
}
|
|
13014
|
+
|
|
12782
13015
|
#[allow(clippy::needless_update)]
|
|
12783
13016
|
impl From<RateLimitConfig> for liter_llm::RateLimitConfig {
|
|
12784
13017
|
fn from(val: RateLimitConfig) -> Self {
|
|
@@ -13169,6 +13402,7 @@ impl From<EmbeddingInput> for liter_llm::types::EmbeddingInput {
|
|
|
13169
13402
|
match val {
|
|
13170
13403
|
EmbeddingInput::Single(_0) => Self::Single(_0),
|
|
13171
13404
|
EmbeddingInput::Multiple(_0) => Self::Multiple(_0.into_iter().collect()),
|
|
13405
|
+
EmbeddingInput::Multimodal(_0) => Self::Multimodal(_0.into_iter().map(Into::into).collect()),
|
|
13172
13406
|
}
|
|
13173
13407
|
}
|
|
13174
13408
|
}
|
|
@@ -13178,6 +13412,37 @@ impl From<liter_llm::types::EmbeddingInput> for EmbeddingInput {
|
|
|
13178
13412
|
match val {
|
|
13179
13413
|
liter_llm::types::EmbeddingInput::Single(_0) => Self::Single(_0),
|
|
13180
13414
|
liter_llm::types::EmbeddingInput::Multiple(_0) => Self::Multiple(_0.into_iter().collect()),
|
|
13415
|
+
liter_llm::types::EmbeddingInput::Multimodal(_0) => {
|
|
13416
|
+
Self::Multimodal(_0.into_iter().map(Into::into).collect())
|
|
13417
|
+
}
|
|
13418
|
+
}
|
|
13419
|
+
}
|
|
13420
|
+
}
|
|
13421
|
+
|
|
13422
|
+
impl From<EmbeddingContentPart> for liter_llm::types::EmbeddingContentPart {
|
|
13423
|
+
fn from(val: EmbeddingContentPart) -> Self {
|
|
13424
|
+
match val {
|
|
13425
|
+
EmbeddingContentPart::Text { text } => Self::Text { text: text },
|
|
13426
|
+
EmbeddingContentPart::ImageUrl { image_url } => Self::ImageUrl {
|
|
13427
|
+
image_url: image_url.into(),
|
|
13428
|
+
},
|
|
13429
|
+
EmbeddingContentPart::ImageBase64 { image_base64 } => Self::ImageBase64 {
|
|
13430
|
+
image_base64: image_base64,
|
|
13431
|
+
},
|
|
13432
|
+
}
|
|
13433
|
+
}
|
|
13434
|
+
}
|
|
13435
|
+
|
|
13436
|
+
impl From<liter_llm::types::EmbeddingContentPart> for EmbeddingContentPart {
|
|
13437
|
+
fn from(val: liter_llm::types::EmbeddingContentPart) -> Self {
|
|
13438
|
+
match val {
|
|
13439
|
+
liter_llm::types::EmbeddingContentPart::Text { text } => Self::Text { text: text.to_string() },
|
|
13440
|
+
liter_llm::types::EmbeddingContentPart::ImageUrl { image_url } => Self::ImageUrl {
|
|
13441
|
+
image_url: image_url.into(),
|
|
13442
|
+
},
|
|
13443
|
+
liter_llm::types::EmbeddingContentPart::ImageBase64 { image_base64 } => Self::ImageBase64 {
|
|
13444
|
+
image_base64: image_base64.to_string(),
|
|
13445
|
+
},
|
|
13181
13446
|
}
|
|
13182
13447
|
}
|
|
13183
13448
|
}
|
|
@@ -14552,6 +14817,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
14552
14817
|
|
|
14553
14818
|
class.define_method("rate_limit", method!(LlmConfig::rate_limit, 0))?;
|
|
14554
14819
|
|
|
14820
|
+
class.define_method("in_flight_limit", method!(LlmConfig::in_flight_limit, 0))?;
|
|
14821
|
+
|
|
14555
14822
|
class.define_method("cost_tracking", method!(LlmConfig::cost_tracking, 0))?;
|
|
14556
14823
|
|
|
14557
14824
|
class.define_method("tracing", method!(LlmConfig::tracing, 0))?;
|
|
@@ -14594,6 +14861,12 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
14594
14861
|
|
|
14595
14862
|
class.define_method("window_seconds", method!(LlmRateLimitConfig::window_seconds, 0))?;
|
|
14596
14863
|
|
|
14864
|
+
let class = module.define_class("LlmInFlightLimitConfig", ruby.class_object())?;
|
|
14865
|
+
|
|
14866
|
+
class.define_singleton_method("new", function!(LlmInFlightLimitConfig::new, -1))?;
|
|
14867
|
+
|
|
14868
|
+
class.define_method("max_in_flight", method!(LlmInFlightLimitConfig::max_in_flight, 0))?;
|
|
14869
|
+
|
|
14597
14870
|
let class = module.define_class("LlmProviderConfig", ruby.class_object())?;
|
|
14598
14871
|
|
|
14599
14872
|
class.define_singleton_method("new", function!(LlmProviderConfig::new, -1))?;
|
|
@@ -14902,6 +15175,12 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
14902
15175
|
|
|
14903
15176
|
let class = module.define_class("SingleflightResult", ruby.class_object())?;
|
|
14904
15177
|
|
|
15178
|
+
let class = module.define_class("InFlightLimitConfig", ruby.class_object())?;
|
|
15179
|
+
|
|
15180
|
+
class.define_singleton_method("new", function!(InFlightLimitConfig::new, -1))?;
|
|
15181
|
+
|
|
15182
|
+
class.define_method("max_in_flight", method!(InFlightLimitConfig::max_in_flight, 0))?;
|
|
15183
|
+
|
|
14905
15184
|
let class = module.define_class("RateLimitConfig", ruby.class_object())?;
|
|
14906
15185
|
|
|
14907
15186
|
class.define_singleton_method("new", function!(RateLimitConfig::new, -1))?;
|
data/lib/liter_llm/native.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# This file is auto-generated by alef — DO NOT EDIT.
|
|
2
|
-
# alef:hash:
|
|
2
|
+
# alef:hash:a963d30e17380908f8f67a9244a29d7e6ad83445dac64977569ca4c3b4b53f6a
|
|
3
3
|
# To regenerate: alef generate
|
|
4
4
|
# To verify freshness: alef verify
|
|
5
5
|
# frozen_string_literal: true
|
|
@@ -556,6 +556,93 @@ module LiterLlm
|
|
|
556
556
|
end
|
|
557
557
|
end
|
|
558
558
|
|
|
559
|
+
module LiterLlm
|
|
560
|
+
# A content part in a multimodal embedding input.
|
|
561
|
+
module EmbeddingContentPart
|
|
562
|
+
extend T::Helpers
|
|
563
|
+
extend T::Sig
|
|
564
|
+
|
|
565
|
+
interface!
|
|
566
|
+
|
|
567
|
+
# Dispatch from a Hash to the appropriate variant constructor.
|
|
568
|
+
# @param hash [Hash] with discriminator field and variant-specific fields
|
|
569
|
+
# @return [variant_class] an instance of the appropriate variant
|
|
570
|
+
sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T.untyped) }
|
|
571
|
+
def self.from_hash(hash)
|
|
572
|
+
discriminator = hash[:type] || hash["type"]
|
|
573
|
+
case discriminator
|
|
574
|
+
when "text" then EmbeddingContentPartText.from_hash(hash)
|
|
575
|
+
when "image_url" then EmbeddingContentPartImageUrl.from_hash(hash)
|
|
576
|
+
when "image_base64" then EmbeddingContentPartImageBase64.from_hash(hash)
|
|
577
|
+
else raise "Unknown discriminator: #{discriminator}"
|
|
578
|
+
end
|
|
579
|
+
end
|
|
580
|
+
end
|
|
581
|
+
## Plain text.
|
|
582
|
+
EmbeddingContentPartText = Data.define(:text) do
|
|
583
|
+
include EmbeddingContentPart
|
|
584
|
+
extend T::Sig
|
|
585
|
+
|
|
586
|
+
# @return [String]
|
|
587
|
+
sig { returns(String) }
|
|
588
|
+
def text = super # rubocop:disable Lint/UselessMethodDefinition
|
|
589
|
+
sig { returns(T::Boolean) }
|
|
590
|
+
def text? = true
|
|
591
|
+
sig { returns(T::Boolean) }
|
|
592
|
+
def image_url? = false
|
|
593
|
+
sig { returns(T::Boolean) }
|
|
594
|
+
def image_base64? = false
|
|
595
|
+
# @param hash [Hash] deserialized from the native extension
|
|
596
|
+
# @return [self]
|
|
597
|
+
sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T.attached_class) }
|
|
598
|
+
def self.from_hash(hash)
|
|
599
|
+
new(text: hash[:text] || hash["text"])
|
|
600
|
+
end
|
|
601
|
+
end
|
|
602
|
+
## Image identified by a data URL or HTTP/HTTPS URL.
|
|
603
|
+
EmbeddingContentPartImageUrl = Data.define(:image_url) do
|
|
604
|
+
include EmbeddingContentPart
|
|
605
|
+
extend T::Sig
|
|
606
|
+
|
|
607
|
+
# @return [ImageUrl]
|
|
608
|
+
sig { returns(ImageUrl) }
|
|
609
|
+
def image_url = super # rubocop:disable Lint/UselessMethodDefinition
|
|
610
|
+
sig { returns(T::Boolean) }
|
|
611
|
+
def text? = false
|
|
612
|
+
sig { returns(T::Boolean) }
|
|
613
|
+
def image_url? = true
|
|
614
|
+
sig { returns(T::Boolean) }
|
|
615
|
+
def image_base64? = false
|
|
616
|
+
# @param hash [Hash] deserialized from the native extension
|
|
617
|
+
# @return [self]
|
|
618
|
+
sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T.attached_class) }
|
|
619
|
+
def self.from_hash(hash)
|
|
620
|
+
new(image_url: hash[:image_url] || hash["image_url"])
|
|
621
|
+
end
|
|
622
|
+
end
|
|
623
|
+
## Image encoded as a complete data URL.
|
|
624
|
+
EmbeddingContentPartImageBase64 = Data.define(:image_base64) do
|
|
625
|
+
include EmbeddingContentPart
|
|
626
|
+
extend T::Sig
|
|
627
|
+
|
|
628
|
+
# @return [String]
|
|
629
|
+
sig { returns(String) }
|
|
630
|
+
def image_base64 = super # rubocop:disable Lint/UselessMethodDefinition
|
|
631
|
+
sig { returns(T::Boolean) }
|
|
632
|
+
def text? = false
|
|
633
|
+
sig { returns(T::Boolean) }
|
|
634
|
+
def image_url? = false
|
|
635
|
+
sig { returns(T::Boolean) }
|
|
636
|
+
def image_base64? = true
|
|
637
|
+
# @param hash [Hash] deserialized from the native extension
|
|
638
|
+
# @return [self]
|
|
639
|
+
sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T.attached_class) }
|
|
640
|
+
def self.from_hash(hash)
|
|
641
|
+
new(image_base64: hash[:image_base64] || hash["image_base64"])
|
|
642
|
+
end
|
|
643
|
+
end
|
|
644
|
+
end
|
|
645
|
+
|
|
559
646
|
module LiterLlm
|
|
560
647
|
# Document input for OCR — either a URL or inline base64 data.
|
|
561
648
|
module OcrDocument
|
data/lib/liter_llm/version.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# This file is auto-generated by alef — DO NOT EDIT.
|
|
2
|
-
# alef:hash:
|
|
2
|
+
# alef:hash:9cad1aa634ead525aea0040c6902c806b7daab37eb7802e5be0d0c5f48aa8847
|
|
3
3
|
# To regenerate: alef generate
|
|
4
4
|
# To verify freshness: alef verify
|
|
5
5
|
# frozen_string_literal: true
|
|
6
6
|
|
|
7
7
|
module LiterLlm
|
|
8
8
|
## The version string for this package.
|
|
9
|
-
VERSION = "1.
|
|
9
|
+
VERSION = "1.18.0"
|
|
10
10
|
end
|
data/lib/liter_llm.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# This file is auto-generated by alef — DO NOT EDIT.
|
|
2
|
-
# alef:hash:
|
|
2
|
+
# alef:hash:b8684376c861ef7e78cc307694871bb74d674153abe531df23adc8a37901a153
|
|
3
3
|
# To regenerate: alef generate
|
|
4
4
|
# To verify freshness: alef verify
|
|
5
5
|
# frozen_string_literal: true
|
data/sig/types.rbs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# This file is auto-generated by alef — DO NOT EDIT.
|
|
2
|
-
# alef:hash:
|
|
2
|
+
# alef:hash:182fb885a8ef562d0a181ae0aadb5dd6e9b1a440c76f7dffbfea998a71b1eb6d
|
|
3
3
|
# To regenerate: alef generate
|
|
4
4
|
# To verify freshness: alef verify
|
|
5
5
|
|
|
@@ -692,13 +692,14 @@ module LiterLlm
|
|
|
692
692
|
attr_reader cache: LlmCacheConfig?
|
|
693
693
|
attr_reader budget: LlmBudgetConfig?
|
|
694
694
|
attr_reader rate_limit: LlmRateLimitConfig?
|
|
695
|
+
attr_reader in_flight_limit: LlmInFlightLimitConfig?
|
|
695
696
|
attr_reader cost_tracking: bool?
|
|
696
697
|
attr_reader tracing: bool?
|
|
697
698
|
attr_reader cooldown_secs: Integer?
|
|
698
699
|
attr_reader health_check_secs: Integer?
|
|
699
700
|
attr_reader bedrock: BedrockConfig?
|
|
700
701
|
|
|
701
|
-
def initialize: (?model: String, ?api_key: String, ?base_url: String, ?timeout_secs: Integer, ?max_retries: Integer, ?temperature: Float, ?max_tokens: Integer, ?load_env: bool, ?headers: Hash[String, String], ?providers: Array[LlmProviderConfig], ?cache: LlmCacheConfig, ?budget: LlmBudgetConfig, ?rate_limit: LlmRateLimitConfig, ?cost_tracking: bool, ?tracing: bool, ?cooldown_secs: Integer, ?health_check_secs: Integer, ?bedrock: BedrockConfig) -> void
|
|
702
|
+
def initialize: (?model: String, ?api_key: String, ?base_url: String, ?timeout_secs: Integer, ?max_retries: Integer, ?temperature: Float, ?max_tokens: Integer, ?load_env: bool, ?headers: Hash[String, String], ?providers: Array[LlmProviderConfig], ?cache: LlmCacheConfig, ?budget: LlmBudgetConfig, ?rate_limit: LlmRateLimitConfig, ?in_flight_limit: LlmInFlightLimitConfig, ?cost_tracking: bool, ?tracing: bool, ?cooldown_secs: Integer, ?health_check_secs: Integer, ?bedrock: BedrockConfig) -> void
|
|
702
703
|
end
|
|
703
704
|
|
|
704
705
|
class LlmCacheConfig
|
|
@@ -726,6 +727,12 @@ module LiterLlm
|
|
|
726
727
|
def initialize: (?rpm: Integer, ?tpm: Integer, ?window_seconds: Integer) -> void
|
|
727
728
|
end
|
|
728
729
|
|
|
730
|
+
class LlmInFlightLimitConfig
|
|
731
|
+
attr_reader max_in_flight: Integer?
|
|
732
|
+
|
|
733
|
+
def initialize: (?max_in_flight: Integer) -> void
|
|
734
|
+
end
|
|
735
|
+
|
|
729
736
|
class LlmProviderConfig
|
|
730
737
|
attr_reader name: String
|
|
731
738
|
attr_reader base_url: String
|
|
@@ -878,6 +885,12 @@ module LiterLlm
|
|
|
878
885
|
class SingleflightResult
|
|
879
886
|
end
|
|
880
887
|
|
|
888
|
+
class InFlightLimitConfig
|
|
889
|
+
attr_reader max_in_flight: Integer?
|
|
890
|
+
|
|
891
|
+
def initialize: (?max_in_flight: Integer) -> void
|
|
892
|
+
end
|
|
893
|
+
|
|
881
894
|
class RateLimitConfig
|
|
882
895
|
attr_reader rpm: Integer?
|
|
883
896
|
attr_reader tpm: Integer?
|
|
@@ -958,6 +971,9 @@ module LiterLlm
|
|
|
958
971
|
class EmbeddingInput
|
|
959
972
|
end
|
|
960
973
|
|
|
974
|
+
class EmbeddingContentPart
|
|
975
|
+
end
|
|
976
|
+
|
|
961
977
|
class ModerationInput
|
|
962
978
|
end
|
|
963
979
|
|
|
@@ -970,7 +986,7 @@ module LiterLlm
|
|
|
970
986
|
end
|
|
971
987
|
|
|
972
988
|
class FilePurpose
|
|
973
|
-
type value = :assistants | :batch | :
|
|
989
|
+
type value = :assistants | :batch | :fine-tune | :vision
|
|
974
990
|
end
|
|
975
991
|
|
|
976
992
|
class BatchStatus
|
|
@@ -985,26 +1001,26 @@ module LiterLlm
|
|
|
985
1001
|
end
|
|
986
1002
|
|
|
987
1003
|
class AuthType
|
|
988
|
-
type value = :bearer | :
|
|
1004
|
+
type value = :bearer | :api-key | :none | :unknown
|
|
989
1005
|
end
|
|
990
1006
|
|
|
991
1007
|
class Enforcement
|
|
992
|
-
type value = :
|
|
1008
|
+
type value = :Hard | :Soft
|
|
993
1009
|
end
|
|
994
1010
|
|
|
995
1011
|
class CacheBackend
|
|
996
1012
|
end
|
|
997
1013
|
|
|
998
1014
|
class CircuitState
|
|
999
|
-
type value = :
|
|
1015
|
+
type value = :Closed | :Open | :HalfOpen
|
|
1000
1016
|
end
|
|
1001
1017
|
|
|
1002
1018
|
class HealthStatus
|
|
1003
|
-
type value = :
|
|
1019
|
+
type value = :Healthy | :Unhealthy
|
|
1004
1020
|
end
|
|
1005
1021
|
|
|
1006
1022
|
class RefreshOutcome
|
|
1007
|
-
type value = :
|
|
1023
|
+
type value = :Disabled | :FromCache | :Fetched
|
|
1008
1024
|
end
|
|
1009
1025
|
|
|
1010
1026
|
def self.create_client: (String api_key, ?String base_url, ?Integer timeout_secs, ?Integer max_retries, ?String model_hint) -> DefaultClient
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: liter_llm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.18.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Na'aman Hirschfeld
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rb_sys
|