liter_llm 2.1.2 → 2.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29301207ffd2e15e1e4d8dd20408ea956e27c425110399ed515902c5140c071b
4
- data.tar.gz: f4144e677a0e0663b22ee8eb7c1dabe2f2bbb02b32969d619bbbe4cdc04d190a
3
+ metadata.gz: 6b3dc0a9f183e0f7d2e468d519ad911720501e3633f68a67bd0940782e1ff018
4
+ data.tar.gz: 83bac628afe410dc0da63752c7ebae701cdd433b15b0e58522283d677d1e8a59
5
5
  SHA512:
6
- metadata.gz: a02131cb1ac63a9200a6e8b24518e22ef6a2525866148793689891e52376c8f9670152b24e3530f2225a4f717667e42a0f1ee947d344da75a2be40a96b788c87
7
- data.tar.gz: b0ec9e55bceb8776be53be8e33fffd2bf8760e82cfa7ba79e49eea6e9ce9b8ae318b4a61f956b55c6c9bd6fc24428a1e1faf27117bb9cfa8547d57db4372b71a
6
+ metadata.gz: 9d83d1ae3756951a5c819cb6a15d46e6ec08def7161bd5810db59192b62ee875b0b10c459ba1c7f2339c58042ebb2dc53e18a557b5a9b248f564fc8ba0959168
7
+ data.tar.gz: ccdbd3742fa8e71e8b6fbe372a4ac7ff59a5879f240d91249575737e9f317fe28caeb336525f247026281457860cef4a0fa70400ba51627839cd8288b4b1a1be
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <!-- This file is auto-generated by alef — DO NOT EDIT. -->
2
- <!-- alef:hash:bdcf91c6dd61dcdf5cb5a9ed400f53097498b47f4974b6d13171eaeff7d62daa -->
2
+ <!-- alef:hash:7c40d8eb1d087bfcbe645868b4311d50b36fbd38633bc3e137cf5adeb8081fbb -->
3
3
  <!-- To regenerate: alef readme -->
4
4
  <!-- To verify freshness: alef verify -->
5
5
 
@@ -87,7 +87,7 @@
87
87
  </a>
88
88
  </div>
89
89
 
90
- Universal LLM API client for Ruby. Access 165 LLM providers through a single interface with idiomatic Ruby API and native performance.
90
+ Universal LLM API client for Ruby. Access 174 LLM providers through a single interface with idiomatic Ruby API and native performance.
91
91
 
92
92
  ## What This Package Provides
93
93
 
@@ -176,7 +176,7 @@ puts
176
176
 
177
177
  ## Features
178
178
 
179
- ### Supported Providers (165)
179
+ ### Supported Providers (174)
180
180
 
181
181
  Route to any provider using the `provider/model` prefix convention:
182
182
 
@@ -196,7 +196,7 @@ Route to any provider using the `provider/model` prefix convention:
196
196
 
197
197
  ### Key Capabilities
198
198
 
199
- - **Provider Routing** -- Single client for 165 LLM providers via `provider/model` prefix
199
+ - **Provider Routing** -- Single client for 174 LLM providers via `provider/model` prefix
200
200
  - **Local LLMs** — Connect to locally-hosted models via Ollama, LM Studio, vLLM, llama.cpp, and other local inference servers
201
201
  - **Unified API** -- Consistent `chat`, `chat_stream`, `embeddings`, `list_models` interface
202
202
  - **Streaming** -- Real-time token streaming via `chat_stream`
@@ -217,7 +217,7 @@ Built on a compiled Rust core for speed and safety:
217
217
 
218
218
  ## Provider Routing
219
219
 
220
- Route to 165 providers using the `provider/model` prefix convention:
220
+ Route to 174 providers using the `provider/model` prefix convention:
221
221
 
222
222
  ```text
223
223
  openai/gpt-4o
@@ -253,7 +253,7 @@ To use the MCP server inside a coding agent, install the **liter-llm plugin** fr
253
253
 
254
254
  - **[Documentation](https://docs.liter-llm.xberg.io)** -- Full docs and API reference
255
255
  - **[GitHub Repository](https://github.com/xberg-io/liter-llm)** -- Source, issues, and discussions
256
- - **[Provider Registry](https://github.com/xberg-io/liter-llm/blob/main/schemas/providers.json)** -- 165 supported providers
256
+ - **[Provider Registry](https://github.com/xberg-io/liter-llm/blob/main/schemas/providers.json)** -- 174 supported providers
257
257
 
258
258
  ## Part of Xberg.io
259
259
 
@@ -261,7 +261,7 @@ To use the MCP server inside a coding agent, install the **liter-llm plugin** fr
261
261
  - [Xberg Enterprise](https://github.com/xberg-io/xberg-enterprise) — managed extraction API with SDKs, dashboards, and observability.
262
262
  - [crawlberg](https://github.com/xberg-io/crawlberg) — web crawling and scraping with HTML→Markdown and headless-Chrome fallback.
263
263
  - [html-to-markdown](https://github.com/xberg-io/html-to-markdown) — fast, lossless HTML→Markdown engine.
264
- - [liter-llm](https://github.com/xberg-io/liter-llm) — universal LLM API client with native bindings for 14 languages and 165 providers.
264
+ - [liter-llm](https://github.com/xberg-io/liter-llm) — universal LLM API client with native bindings for 14 languages and 174 providers.
265
265
  - [tree-sitter-language-pack](https://github.com/xberg-io/tree-sitter-language-pack) — tree-sitter grammars and code-intelligence primitives.
266
266
  - [alef](https://github.com/xberg-io/alef) — the polyglot binding generator that produces every per-language binding across the 5 polyglot repos.
267
267
  - [Discord](https://discord.gg/xt9WY3GnKR) — community, roadmap, announcements.
@@ -69,9 +69,9 @@ checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
69
69
 
70
70
  [[package]]
71
71
  name = "async-compression"
72
- version = "0.4.49"
72
+ version = "0.4.50"
73
73
  source = "registry+https://github.com/rust-lang/crates.io-index"
74
- checksum = "a3789ca2cd1c4e8ce71fe9bd6312566014e20ff3016fc87bc71c59ff93b5fa61"
74
+ checksum = "ee19bd99b43e3691acbad4e840420a4881cea6c0b66a208125a824f8fd53f5a1"
75
75
  dependencies = [
76
76
  "compression-codecs",
77
77
  "compression-core",
@@ -387,9 +387,9 @@ dependencies = [
387
387
 
388
388
  [[package]]
389
389
  name = "cc"
390
- version = "1.5.1"
390
+ version = "1.6.0"
391
391
  source = "registry+https://github.com/rust-lang/crates.io-index"
392
- checksum = "f360145194ee8e21db5ee7f3fcd4fe52210864c75c985dae33218202c8bbe040"
392
+ checksum = "f74872d07caf508b30a21f6836e7d7016a2eaf7d9ff4f48deaa58cd8a0407630"
393
393
  dependencies = [
394
394
  "find-msvc-tools",
395
395
  "shlex 2.0.1",
@@ -489,9 +489,9 @@ dependencies = [
489
489
 
490
490
  [[package]]
491
491
  name = "compression-codecs"
492
- version = "0.4.44"
492
+ version = "0.4.45"
493
493
  source = "registry+https://github.com/rust-lang/crates.io-index"
494
- checksum = "5f018b36ac50598f7bfb0aa6094281e253e6b3cbc507a69652d2fb963a326d8d"
494
+ checksum = "98fc98460ba0ad5317075d3632b8dfc45d0be8c4a49347c2a38272019717614a"
495
495
  dependencies = [
496
496
  "compression-core",
497
497
  "flate2",
@@ -1660,9 +1660,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
1660
1660
 
1661
1661
  [[package]]
1662
1662
  name = "libc"
1663
- version = "0.2.189"
1663
+ version = "0.2.190"
1664
1664
  source = "registry+https://github.com/rust-lang/crates.io-index"
1665
- checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
1665
+ checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78"
1666
1666
 
1667
1667
  [[package]]
1668
1668
  name = "libloading"
@@ -1697,9 +1697,9 @@ checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae"
1697
1697
 
1698
1698
  [[package]]
1699
1699
  name = "liter-llm"
1700
- version = "2.1.2"
1700
+ version = "2.2.0"
1701
1701
  source = "registry+https://github.com/rust-lang/crates.io-index"
1702
- checksum = "195beed58c0db82dd1159f4f5a5ba80847f9be9dc1d583faf02f98ac67233aba"
1702
+ checksum = "8638e8a77817d0debb8944de890ad736f80e1a46c2c53b8d75a303f59307fa68"
1703
1703
  dependencies = [
1704
1704
  "ahash",
1705
1705
  "arc-swap",
@@ -1742,7 +1742,7 @@ dependencies = [
1742
1742
 
1743
1743
  [[package]]
1744
1744
  name = "liter-llm-rb"
1745
- version = "2.1.2"
1745
+ version = "2.2.0"
1746
1746
  dependencies = [
1747
1747
  "futures",
1748
1748
  "liter-llm",
@@ -1786,9 +1786,9 @@ checksum = "fc04a4c58212d57930a24bf47d3fa87485264a3a054e9c10e042eb373573ad3c"
1786
1786
 
1787
1787
  [[package]]
1788
1788
  name = "magnus"
1789
- version = "0.9.1"
1789
+ version = "0.9.2"
1790
1790
  source = "registry+https://github.com/rust-lang/crates.io-index"
1791
- checksum = "4c01bef153b8d0f086991f0e166474a1d57b738221f9a9c11405d498ac95a44d"
1791
+ checksum = "b9068710e00d21be762edca59b9c4c8946dbdb29820d4f76ad559afea07982c9"
1792
1792
  dependencies = [
1793
1793
  "magnus-macros",
1794
1794
  "rb-sys",
@@ -1867,9 +1867,9 @@ dependencies = [
1867
1867
 
1868
1868
  [[package]]
1869
1869
  name = "mio"
1870
- version = "1.2.3"
1870
+ version = "1.2.4"
1871
1871
  source = "registry+https://github.com/rust-lang/crates.io-index"
1872
- checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8"
1872
+ checksum = "1788edb87fdc09c7e26304471e2f5be8cdefb1b6930d6e3985fc02ff53bf86ee"
1873
1873
  dependencies = [
1874
1874
  "libc",
1875
1875
  "wasi",
@@ -1983,9 +1983,9 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
1983
1983
 
1984
1984
  [[package]]
1985
1985
  name = "opendal"
1986
- version = "0.59.3"
1986
+ version = "0.59.4"
1987
1987
  source = "registry+https://github.com/rust-lang/crates.io-index"
1988
- checksum = "ef16fe6b19b73b49ce39e3e0f4cec27e54789eee5d5f752cb2d26bd3e9449686"
1988
+ checksum = "3cbd193aec6d62efaff87611dfae52c132aed650bb3cb0c684c0a9394f09a42a"
1989
1989
  dependencies = [
1990
1990
  "opendal-core",
1991
1991
  "opendal-service-fs",
@@ -1995,9 +1995,9 @@ dependencies = [
1995
1995
 
1996
1996
  [[package]]
1997
1997
  name = "opendal-core"
1998
- version = "0.59.3"
1998
+ version = "0.59.4"
1999
1999
  source = "registry+https://github.com/rust-lang/crates.io-index"
2000
- checksum = "ddff5c648dcb3922c2bec71e0d26e881ddf9c367cb7c9a59ed7f2d39a4f38218"
2000
+ checksum = "54b5555d753dd6a6383dc0891254b72f3cdc40c011ba0372b560e0ae5aa29f5c"
2001
2001
  dependencies = [
2002
2002
  "anyhow",
2003
2003
  "asyncband",
@@ -2021,9 +2021,9 @@ dependencies = [
2021
2021
 
2022
2022
  [[package]]
2023
2023
  name = "opendal-http-transport-reqwest"
2024
- version = "0.59.3"
2024
+ version = "0.59.4"
2025
2025
  source = "registry+https://github.com/rust-lang/crates.io-index"
2026
- checksum = "56fcee7ac4b4b815d38346ceb4f3a5d7ef18869c369e000cc7f622b51bcfa938"
2026
+ checksum = "4d6588678f3040a3eab1819364dcbc6a746a8286d1ceb23a70a6614faa01dc6c"
2027
2027
  dependencies = [
2028
2028
  "bytes",
2029
2029
  "futures",
@@ -2035,9 +2035,9 @@ dependencies = [
2035
2035
 
2036
2036
  [[package]]
2037
2037
  name = "opendal-service-fs"
2038
- version = "0.59.3"
2038
+ version = "0.59.4"
2039
2039
  source = "registry+https://github.com/rust-lang/crates.io-index"
2040
- checksum = "c14b25aa288453e1b9ed9b3c9024b467676ce4a3fed456441c9d6af8aa2643f3"
2040
+ checksum = "ec5c16fe91b77c0364f66546a1c32b2999e9c3c3c75c2e908a282268e0890bac"
2041
2041
  dependencies = [
2042
2042
  "bytes",
2043
2043
  "log",
@@ -2049,9 +2049,9 @@ dependencies = [
2049
2049
 
2050
2050
  [[package]]
2051
2051
  name = "opendal-service-redis"
2052
- version = "0.59.3"
2052
+ version = "0.59.4"
2053
2053
  source = "registry+https://github.com/rust-lang/crates.io-index"
2054
- checksum = "0c9882dff1e78bde3aabacebdc6fc49a41368cb158cd3e1c2b6d9db8ea8e414b"
2054
+ checksum = "67bdcf0db50dafddb62b3a62c21bd81e8e6ae200852b1887d594ce722d052570"
2055
2055
  dependencies = [
2056
2056
  "asyncband",
2057
2057
  "bytes",
@@ -2064,9 +2064,9 @@ dependencies = [
2064
2064
 
2065
2065
  [[package]]
2066
2066
  name = "opendal-service-s3"
2067
- version = "0.59.3"
2067
+ version = "0.59.4"
2068
2068
  source = "registry+https://github.com/rust-lang/crates.io-index"
2069
- checksum = "9de51cba3b83c8130e211045fd2b9d454c4b73f557ad88b71244c2ab943b2b05"
2069
+ checksum = "1d83e716c25a81fe2ca701894b8e14b9966acca3812af250e50132accb19da02"
2070
2070
  dependencies = [
2071
2071
  "base64 0.23.1",
2072
2072
  "bytes",
@@ -2283,9 +2283,9 @@ dependencies = [
2283
2283
 
2284
2284
  [[package]]
2285
2285
  name = "powerfmt"
2286
- version = "0.2.0"
2286
+ version = "0.2.1"
2287
2287
  source = "registry+https://github.com/rust-lang/crates.io-index"
2288
- checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
2288
+ checksum = "4a6394b9e965e73d0a289ee54f589087e2c676aedf60885baf52c76b771e4958"
2289
2289
 
2290
2290
  [[package]]
2291
2291
  name = "ppv-lite86"
@@ -3318,9 +3318,9 @@ dependencies = [
3318
3318
 
3319
3319
  [[package]]
3320
3320
  name = "tokio"
3321
- version = "1.53.1"
3321
+ version = "1.53.2"
3322
3322
  source = "registry+https://github.com/rust-lang/crates.io-index"
3323
- checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
3323
+ checksum = "e95f91fcc7a621e8b030f6aa23c71fe9838ae2fb4d8118b75602a328f5144044"
3324
3324
  dependencies = [
3325
3325
  "bytes",
3326
3326
  "libc",
@@ -3680,9 +3680,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
3680
3680
 
3681
3681
  [[package]]
3682
3682
  name = "uuid"
3683
- version = "1.26.1"
3683
+ version = "1.27.0"
3684
3684
  source = "registry+https://github.com/rust-lang/crates.io-index"
3685
- checksum = "2ef6dac1e96601b4fb3acccccff2139741fcb757cb9a36089bf5be91cfb285ce"
3685
+ checksum = "97277d36b9c3ace13e58fa6e753f8b0bbbf302a18dd193240d70f9e29681059a"
3686
3686
  dependencies = [
3687
3687
  "getrandom 0.4.3",
3688
3688
  "js-sys",
@@ -4170,9 +4170,9 @@ dependencies = [
4170
4170
 
4171
4171
  [[package]]
4172
4172
  name = "yoke-derive"
4173
- version = "0.8.3"
4173
+ version = "0.8.4"
4174
4174
  source = "registry+https://github.com/rust-lang/crates.io-index"
4175
- checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78"
4175
+ checksum = "ec8ebde2db3681e8c9980cc27822030e68752690ddfa9473e739aeb4dbde6d71"
4176
4176
  dependencies = [
4177
4177
  "proc-macro2",
4178
4178
  "quote",
@@ -1,11 +1,11 @@
1
1
  # This file is auto-generated by alef — DO NOT EDIT.
2
- # alef:hash:38b83c8e4282935c69a322684e3def267a864dc82d26fc8322f6f8ed27b65e4e
2
+ # alef:hash:c521ecc32356e04cfe9a166fa28268f2f087a83ad433544f00ab20701f293372
3
3
  # To regenerate: alef generate
4
4
  # To verify freshness: alef verify
5
5
 
6
6
  [package]
7
7
  name = "liter-llm-rb"
8
- version = "2.1.2"
8
+ version = "2.2.0"
9
9
  edition = "2024"
10
10
  license = "MIT"
11
11
  description = "Universal LLM API client with Rust-powered polyglot bindings."
@@ -31,7 +31,7 @@ wasm-http = ["liter-llm/wasm-http"]
31
31
 
32
32
  [dependencies]
33
33
  futures = "0.3"
34
- liter-llm = { version = "2.1.2", features = ["native-http", "full"] }
34
+ liter-llm = { version = "2.2.0", features = ["native-http", "full"] }
35
35
  magnus = "0.9"
36
36
  rb-sys = ">=0.9.130, <0.10"
37
37
  serde = { version = "1", features = ["derive"] }
@@ -1,5 +1,5 @@
1
1
  // This file is auto-generated by alef. DO NOT EDIT.
2
- // alef:hash:3d67a161923134ed4b5f9771327dbb7dcd88240d3e2dd0bf458a0ea4302cfb6b
2
+ // alef:hash:a471cf0303320780d0a56e0d907d0c97856c0d95870f41e3b9e70df6bb9db85c
3
3
  // Re-generate with: alef generate
4
4
  #![allow(dead_code, unused_imports, unused_variables)]
5
5
  #![allow(
@@ -2538,6 +2538,79 @@ impl Choice {
2538
2538
  }
2539
2539
  }
2540
2540
 
2541
+ #[derive(Clone, Debug, serde::Serialize)]
2542
+ #[serde(default)]
2543
+ #[magnus::wrap(class = "LiterLlm::CompletionTokensDetails")]
2544
+ pub struct CompletionTokensDetails {
2545
+ reasoning_tokens: u64,
2546
+ }
2547
+
2548
+ unsafe impl IntoValueFromNative for CompletionTokensDetails {}
2549
+
2550
+ impl magnus::TryConvert for CompletionTokensDetails {
2551
+ fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
2552
+ if let Ok(r) = <&CompletionTokensDetails as magnus::TryConvert>::try_convert(val) {
2553
+ return Ok(r.clone());
2554
+ }
2555
+ let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
2556
+ s
2557
+ } else {
2558
+ val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
2559
+ magnus::Error::new(
2560
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2561
+ format!("no implicit conversion into CompletionTokensDetails: {}", e),
2562
+ )
2563
+ })?
2564
+ };
2565
+ serde_json::from_str::<CompletionTokensDetails>(&json_str).map_err(|e| {
2566
+ magnus::Error::new(
2567
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2568
+ format!("failed to deserialize CompletionTokensDetails: {}", e),
2569
+ )
2570
+ })
2571
+ }
2572
+ }
2573
+
2574
+ unsafe impl TryConvertOwned for CompletionTokensDetails {}
2575
+ impl<'de> serde::Deserialize<'de> for CompletionTokensDetails {
2576
+ fn deserialize<D>(deserializer: D) -> ::core::result::Result<Self, D::Error>
2577
+ where
2578
+ D: serde::Deserializer<'de>,
2579
+ {
2580
+ <liter_llm::types::CompletionTokensDetails as serde::Deserialize>::deserialize(deserializer).map(Into::into)
2581
+ }
2582
+ }
2583
+
2584
+ impl Default for CompletionTokensDetails {
2585
+ fn default() -> Self {
2586
+ liter_llm::types::CompletionTokensDetails::default().into()
2587
+ }
2588
+ }
2589
+
2590
+ impl CompletionTokensDetails {
2591
+ fn new(args: &[magnus::Value]) -> Result<Self, magnus::Error> {
2592
+ let ruby = unsafe { magnus::Ruby::get_unchecked() };
2593
+ let args = magnus::scan_args::scan_args::<(), (Option<magnus::RHash>,), (), (), (), ()>(args)?;
2594
+ let (kwargs_opt,) = args.optional;
2595
+ let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
2596
+ Ok(Self {
2597
+ reasoning_tokens: match kwargs.get(ruby.to_symbol("reasoning_tokens")) {
2598
+ Some(v) => u64::try_convert(v).map_err(|e| {
2599
+ magnus::Error::new(
2600
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
2601
+ format!("invalid value for `reasoning_tokens`: {}", e),
2602
+ )
2603
+ })?,
2604
+ None => Default::default(),
2605
+ },
2606
+ })
2607
+ }
2608
+
2609
+ fn reasoning_tokens(&self) -> u64 {
2610
+ self.reasoning_tokens
2611
+ }
2612
+ }
2613
+
2541
2614
  #[derive(Clone, Debug, serde::Serialize)]
2542
2615
  #[serde(default)]
2543
2616
  #[magnus::wrap(class = "LiterLlm::CreateBatchRequest")]
@@ -11703,6 +11776,7 @@ pub struct Usage {
11703
11776
  completion_tokens: u64,
11704
11777
  total_tokens: u64,
11705
11778
  prompt_tokens_details: Option<PromptTokensDetails>,
11779
+ completion_tokens_details: Option<CompletionTokensDetails>,
11706
11780
  }
11707
11781
 
11708
11782
  unsafe impl IntoValueFromNative for Usage {}
@@ -11793,6 +11867,18 @@ impl Usage {
11793
11867
  })?),
11794
11868
  None => None,
11795
11869
  },
11870
+ completion_tokens_details: match kwargs
11871
+ .get(ruby.to_symbol("completion_tokens_details"))
11872
+ .filter(|v| !v.is_nil())
11873
+ {
11874
+ Some(v) => Some(CompletionTokensDetails::try_convert(v).map_err(|e| {
11875
+ magnus::Error::new(
11876
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
11877
+ format!("invalid value for `completion_tokens_details`: {}", e),
11878
+ )
11879
+ })?),
11880
+ None => None,
11881
+ },
11796
11882
  })
11797
11883
  }
11798
11884
 
@@ -11811,6 +11897,10 @@ impl Usage {
11811
11897
  fn prompt_tokens_details(&self) -> Option<PromptTokensDetails> {
11812
11898
  self.prompt_tokens_details.clone()
11813
11899
  }
11900
+
11901
+ fn completion_tokens_details(&self) -> Option<CompletionTokensDetails> {
11902
+ self.completion_tokens_details.clone()
11903
+ }
11814
11904
  }
11815
11905
 
11816
11906
  #[derive(Clone, Debug, serde::Serialize)]
@@ -14532,6 +14622,24 @@ impl From<liter_llm::types::Choice> for Choice {
14532
14622
  }
14533
14623
  }
14534
14624
 
14625
+ #[allow(clippy::needless_update)]
14626
+ impl From<CompletionTokensDetails> for liter_llm::types::CompletionTokensDetails {
14627
+ fn from(val: CompletionTokensDetails) -> Self {
14628
+ Self {
14629
+ reasoning_tokens: val.reasoning_tokens,
14630
+ ..Default::default()
14631
+ }
14632
+ }
14633
+ }
14634
+
14635
+ impl From<liter_llm::types::CompletionTokensDetails> for CompletionTokensDetails {
14636
+ fn from(val: liter_llm::types::CompletionTokensDetails) -> Self {
14637
+ Self {
14638
+ reasoning_tokens: val.reasoning_tokens,
14639
+ }
14640
+ }
14641
+ }
14642
+
14535
14643
  #[allow(clippy::needless_update)]
14536
14644
  #[allow(clippy::redundant_closure)]
14537
14645
  impl From<CreateBatchRequest> for liter_llm::types::CreateBatchRequest {
@@ -16319,6 +16427,7 @@ impl From<Usage> for liter_llm::types::Usage {
16319
16427
  completion_tokens: val.completion_tokens,
16320
16428
  total_tokens: val.total_tokens,
16321
16429
  prompt_tokens_details: val.prompt_tokens_details.map(Into::into),
16430
+ completion_tokens_details: val.completion_tokens_details.map(Into::into),
16322
16431
  ..Default::default()
16323
16432
  }
16324
16433
  }
@@ -16332,6 +16441,7 @@ impl From<liter_llm::types::Usage> for Usage {
16332
16441
  completion_tokens: val.completion_tokens,
16333
16442
  total_tokens: val.total_tokens,
16334
16443
  prompt_tokens_details: val.prompt_tokens_details.map(Into::into),
16444
+ completion_tokens_details: val.completion_tokens_details.map(Into::into),
16335
16445
  }
16336
16446
  }
16337
16447
  }
@@ -17019,16 +17129,16 @@ impl From<liter_llm::types::UserContent> for UserContent {
17019
17129
  }
17020
17130
  }
17021
17131
 
17022
- /// Convert a `liter_llm::cost::refresh::CatalogRefreshError` error to a Magnus runtime error.
17132
+ /// Convert a `liter_llm::CatalogRefreshError` error to a Magnus runtime error.
17023
17133
  #[allow(dead_code)]
17024
- fn catalog_refresh_error_to_magnus_err(e: liter_llm::cost::refresh::CatalogRefreshError) -> magnus::Error {
17134
+ fn catalog_refresh_error_to_magnus_err(e: liter_llm::CatalogRefreshError) -> magnus::Error {
17025
17135
  let msg = e.to_string();
17026
17136
  magnus::Error::new(unsafe { magnus::Ruby::get_unchecked() }.exception_runtime_error(), msg)
17027
17137
  }
17028
17138
 
17029
- /// Convert a `liter_llm::error::LiterLlmError` error to a Magnus runtime error.
17139
+ /// Convert a `liter_llm::LiterLlmError` error to a Magnus runtime error.
17030
17140
  #[allow(dead_code)]
17031
- fn liter_llm_error_to_magnus_err(e: liter_llm::error::LiterLlmError) -> magnus::Error {
17141
+ fn liter_llm_error_to_magnus_err(e: liter_llm::LiterLlmError) -> magnus::Error {
17032
17142
  let msg = e.to_string();
17033
17143
  magnus::Error::new(unsafe { magnus::Ruby::get_unchecked() }.exception_runtime_error(), msg)
17034
17144
  }
@@ -17036,14 +17146,16 @@ fn liter_llm_error_to_magnus_err(e: liter_llm::error::LiterLlmError) -> magnus::
17036
17146
  #[magnus::wrap(class = "LiterLlmErrorInfo", free_immediately, size)]
17037
17147
  pub struct LiterLlmErrorInfo {
17038
17148
  status_code: u16,
17149
+ retry_after: Option<u64>,
17039
17150
  is_transient: bool,
17040
17151
  error_type: String,
17041
17152
  }
17042
17153
 
17043
17154
  #[allow(dead_code)]
17044
- fn liter_llm_error_info(e: &liter_llm::error::LiterLlmError) -> LiterLlmErrorInfo {
17155
+ fn liter_llm_error_info(e: &liter_llm::LiterLlmError) -> LiterLlmErrorInfo {
17045
17156
  LiterLlmErrorInfo {
17046
17157
  status_code: e.status_code(),
17158
+ retry_after: e.retry_after().map(|d| d.as_millis() as u64),
17047
17159
  is_transient: e.is_transient(),
17048
17160
  error_type: e.error_type().to_string(),
17049
17161
  }
@@ -17055,6 +17167,11 @@ impl LiterLlmErrorInfo {
17055
17167
  self.status_code
17056
17168
  }
17057
17169
 
17170
+ /// `retry_after` in whole milliseconds (nil when absent).
17171
+ pub fn retry_after(&self) -> Option<u64> {
17172
+ self.retry_after
17173
+ }
17174
+
17058
17175
  /// Returns `true` if the error is transient and a retry may succeed.
17059
17176
  pub fn transient(&self) -> bool {
17060
17177
  self.is_transient
@@ -17460,6 +17577,15 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
17460
17577
 
17461
17578
  class.define_method("logprobs", method!(Choice::logprobs, 0))?;
17462
17579
 
17580
+ let class = module.define_class("CompletionTokensDetails", ruby.class_object())?;
17581
+
17582
+ class.define_singleton_method("new", function!(CompletionTokensDetails::new, -1))?;
17583
+
17584
+ class.define_method(
17585
+ "reasoning_tokens",
17586
+ method!(CompletionTokensDetails::reasoning_tokens, 0),
17587
+ )?;
17588
+
17463
17589
  let class = module.define_class("CreateBatchRequest", ruby.class_object())?;
17464
17590
 
17465
17591
  class.define_singleton_method("new", function!(CreateBatchRequest::new, -1))?;
@@ -18536,6 +18662,11 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
18536
18662
 
18537
18663
  class.define_method("prompt_tokens_details", method!(Usage::prompt_tokens_details, 0))?;
18538
18664
 
18665
+ class.define_method(
18666
+ "completion_tokens_details",
18667
+ method!(Usage::completion_tokens_details, 0),
18668
+ )?;
18669
+
18539
18670
  let class = module.define_class("UserMessage", ruby.class_object())?;
18540
18671
 
18541
18672
  class.define_singleton_method("new", function!(UserMessage::new, -1))?;
@@ -18637,6 +18768,7 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
18637
18768
 
18638
18769
  let liter_llm_error_info_class = module.define_class("LiterLlmErrorInfo", ruby.class_object())?;
18639
18770
  liter_llm_error_info_class.define_method("status_code", magnus::method!(LiterLlmErrorInfo::status_code, 0))?;
18771
+ liter_llm_error_info_class.define_method("retry_after", magnus::method!(LiterLlmErrorInfo::retry_after, 0))?;
18640
18772
  liter_llm_error_info_class.define_method("transient?", magnus::method!(LiterLlmErrorInfo::transient, 0))?;
18641
18773
  liter_llm_error_info_class.define_method("error_type", magnus::method!(LiterLlmErrorInfo::error_type, 0))?;
18642
18774
 
@@ -1,10 +1,10 @@
1
1
  # This file is auto-generated by alef — DO NOT EDIT.
2
- # alef:hash:835c72f66a33857e5cde5ce9bf834c4e062a440d6f44fbef5ea1e6ce8572a293
2
+ # alef:hash:88d843936a293d3dbc8d7b28247e23b849ade6bdaec311f512475702e7f6d5d3
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 = "2.1.2"
9
+ VERSION = "2.2.0"
10
10
  end
data/sig/types.rbs CHANGED
@@ -1,5 +1,5 @@
1
1
  # This file is auto-generated by alef — DO NOT EDIT.
2
- # alef:hash:7da61d9dc1d0d9879fe5db611ee4b5a2abf07cd3f806331e8137f8385bba9527
2
+ # alef:hash:d586cd0ed89b7c23a36a35404031b0152d6e4bb331734e021b41b776a7a22706
3
3
  # To regenerate: alef generate
4
4
  # To verify freshness: alef verify
5
5
 
@@ -195,6 +195,12 @@ module LiterLlm
195
195
  def initialize: (?index: Integer, ?message: AssistantMessage, ?finish_reason: enum_FinishReason, ?logprobs: String) -> void
196
196
  end
197
197
 
198
+ class CompletionTokensDetails
199
+ attr_reader reasoning_tokens: Integer
200
+
201
+ def initialize: (?reasoning_tokens: Integer) -> void
202
+ end
203
+
198
204
  class CreateBatchRequest
199
205
  attr_reader input_file_id: String
200
206
  attr_reader endpoint: String
@@ -277,31 +283,31 @@ module LiterLlm
277
283
  end
278
284
 
279
285
  class DefaultClient
280
- def chat: (ChatCompletionRequest req) -> ChatCompletionResponse
286
+ def chat_async: (ChatCompletionRequest req) -> ChatCompletionResponse
281
287
  def chat_stream: (ChatCompletionRequest req) -> Enumerator[ChatCompletionChunk]
282
- def embed: (EmbeddingRequest req) -> EmbeddingResponse
283
- def list_models: () -> ModelsListResponse
284
- def image_generate: (CreateImageRequest req) -> ImagesResponse
285
- def speech: (CreateSpeechRequest req) -> String
286
- def transcribe: (CreateTranscriptionRequest req) -> TranscriptionResponse
287
- def moderate: (ModerationRequest req) -> ModerationResponse
288
- def rerank: (RerankRequest req) -> RerankResponse
289
- def search: (SearchRequest req) -> SearchResponse
290
- def ocr: (OcrRequest req) -> OcrResponse
291
- def create_file: (CreateFileRequest req) -> FileObject
292
- def retrieve_file: (String file_id) -> FileObject
293
- def delete_file: (String file_id) -> DeleteResponse
294
- def list_files: (?FileListQuery query) -> FileListResponse
295
- def file_content: (String file_id) -> String
296
- def create_batch: (CreateBatchRequest req) -> BatchObject
297
- def retrieve_batch: (String batch_id) -> BatchObject
298
- def list_batches: (?BatchListQuery query) -> BatchListResponse
299
- def cancel_batch: (String batch_id) -> BatchObject
300
- def fetch_batch_for_polling: (String batch_id) -> BatchObject
301
- def wait_for_batch: (String batch_id, WaitForBatchConfig config) -> BatchObject
302
- def create_response: (CreateResponseRequest req) -> ResponseObject
303
- def retrieve_response: (String response_id) -> ResponseObject
304
- def cancel_response: (String response_id) -> ResponseObject
288
+ def embed_async: (EmbeddingRequest req) -> EmbeddingResponse
289
+ def list_models_async: () -> ModelsListResponse
290
+ def image_generate_async: (CreateImageRequest req) -> ImagesResponse
291
+ def speech_async: (CreateSpeechRequest req) -> String
292
+ def transcribe_async: (CreateTranscriptionRequest req) -> TranscriptionResponse
293
+ def moderate_async: (ModerationRequest req) -> ModerationResponse
294
+ def rerank_async: (RerankRequest req) -> RerankResponse
295
+ def search_async: (SearchRequest req) -> SearchResponse
296
+ def ocr_async: (OcrRequest req) -> OcrResponse
297
+ def create_file_async: (CreateFileRequest req) -> FileObject
298
+ def retrieve_file_async: (String file_id) -> FileObject
299
+ def delete_file_async: (String file_id) -> DeleteResponse
300
+ def list_files_async: (?FileListQuery query) -> FileListResponse
301
+ def file_content_async: (String file_id) -> String
302
+ def create_batch_async: (CreateBatchRequest req) -> BatchObject
303
+ def retrieve_batch_async: (String batch_id) -> BatchObject
304
+ def list_batches_async: (?BatchListQuery query) -> BatchListResponse
305
+ def cancel_batch_async: (String batch_id) -> BatchObject
306
+ def fetch_batch_for_polling_async: (String batch_id) -> BatchObject
307
+ def wait_for_batch_async: (String batch_id, WaitForBatchConfig config) -> BatchObject
308
+ def create_response_async: (CreateResponseRequest req) -> ResponseObject
309
+ def retrieve_response_async: (String response_id) -> ResponseObject
310
+ def cancel_response_async: (String response_id) -> ResponseObject
305
311
  end
306
312
 
307
313
  class DeleteResponse
@@ -896,8 +902,9 @@ module LiterLlm
896
902
  attr_reader completion_tokens: Integer
897
903
  attr_reader total_tokens: Integer
898
904
  attr_reader prompt_tokens_details: PromptTokensDetails?
905
+ attr_reader completion_tokens_details: CompletionTokensDetails?
899
906
 
900
- def initialize: (?prompt_tokens: Integer, ?completion_tokens: Integer, ?total_tokens: Integer, ?prompt_tokens_details: PromptTokensDetails) -> void
907
+ def initialize: (?prompt_tokens: Integer, ?completion_tokens: Integer, ?total_tokens: Integer, ?prompt_tokens_details: PromptTokensDetails, ?completion_tokens_details: CompletionTokensDetails) -> void
901
908
  end
902
909
 
903
910
  class UserMessage
@@ -1041,6 +1048,7 @@ module LiterLlm
1041
1048
 
1042
1049
  class LiterLlmErrorInfo
1043
1050
  def status_code: () -> Integer
1051
+ def retry_after: () -> Integer?
1044
1052
  def transient?: () -> bool
1045
1053
  def error_type: () -> String
1046
1054
  end
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: 2.1.2
4
+ version: 2.2.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-09-30 00:00:00.000000000 Z
11
+ date: 2026-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rb_sys