liter_llm 1.10.1 → 1.11.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: fda7c94bc18cfb3d6186546942c8b857931be441b9ab905420a16d05a38af8e4
4
- data.tar.gz: 2e1dc52df6d3036593c4be0eaa3141e998e90cd41d98b4dd29ccffdc45865cd9
3
+ metadata.gz: 9d411564abe8505e66990b4aef101928d528b7ce3c1c2b0b092f1928c90b6f65
4
+ data.tar.gz: d5bd3c4ec4b52203da86dbfa343834f91fd6bba627be9e285b68880b68a178b5
5
5
  SHA512:
6
- metadata.gz: a2f58f75309ac2ba6c0d3b6dead14bc7fcdd09e1c2debdfc0da834970c154ef2d47b618471676ba31c3d648930372b9c6dbaf67de7fdaa7dff09ae06c1c8efc2
7
- data.tar.gz: 7659b814e9d5bc18665a9c7917000f3596fe542ac4d196e0a020346daef9ac7777a0e0d42d5fb340ee40e81603a532a7ef6cc16b8d71fb1da9d741c8229cbcc9
6
+ metadata.gz: 8618796b18e82208544cb5b9c3b2cc846a8eff3caf5a1417308438b738256ec39e24a726d7189f2f39e8e355d5df94f3caf35d3a177a8db5747e20beb392abd7
7
+ data.tar.gz: aab2c9588ed840b6c4f97856b080fa60e8d8315a3d5f2351a5bf25d4181d8e7563b273c6892e522058fb7d685285ba973f3c1d42e4d37110895604fb75967a27
data/README.md CHANGED
@@ -79,7 +79,7 @@
79
79
  </a>
80
80
  </div>
81
81
 
82
- Universal LLM API client for Ruby. Access 163 LLM providers through a single interface with idiomatic Ruby API and native performance.
82
+ Universal LLM API client for Ruby. Access 165 LLM providers through a single interface with idiomatic Ruby API and native performance.
83
83
 
84
84
  ## What This Package Provides
85
85
 
@@ -168,7 +168,7 @@ puts
168
168
 
169
169
  ## Features
170
170
 
171
- ### Supported Providers (163)
171
+ ### Supported Providers (165)
172
172
 
173
173
  Route to any provider using the `provider/model` prefix convention:
174
174
 
@@ -188,7 +188,7 @@ Route to any provider using the `provider/model` prefix convention:
188
188
 
189
189
  ### Key Capabilities
190
190
 
191
- - **Provider Routing** -- Single client for 163 LLM providers via `provider/model` prefix
191
+ - **Provider Routing** -- Single client for 165 LLM providers via `provider/model` prefix
192
192
  - **Local LLMs** — Connect to locally-hosted models via Ollama, LM Studio, vLLM, llama.cpp, and other local inference servers
193
193
  - **Unified API** -- Consistent `chat`, `chat_stream`, `embeddings`, `list_models` interface
194
194
  - **Streaming** -- Real-time token streaming via `chat_stream`
@@ -209,7 +209,7 @@ Built on a compiled Rust core for speed and safety:
209
209
 
210
210
  ## Provider Routing
211
211
 
212
- Route to 163 providers using the `provider/model` prefix convention:
212
+ Route to 165 providers using the `provider/model` prefix convention:
213
213
 
214
214
  ```text
215
215
  openai/gpt-4o
@@ -244,7 +244,7 @@ To use the MCP server inside a coding agent, install the **liter-llm plugin** fr
244
244
 
245
245
  - **[Documentation](https://docs.liter-llm.xberg.io)** -- Full docs and API reference
246
246
  - **[GitHub Repository](https://github.com/xberg-io/liter-llm)** -- Source, issues, and discussions
247
- - **[Provider Registry](https://github.com/xberg-io/liter-llm/blob/main/schemas/providers.json)** -- 163 supported providers
247
+ - **[Provider Registry](https://github.com/xberg-io/liter-llm/blob/main/schemas/providers.json)** -- 165 supported providers
248
248
 
249
249
  ## Part of Xberg.io
250
250
 
@@ -252,7 +252,7 @@ To use the MCP server inside a coding agent, install the **liter-llm plugin** fr
252
252
  - [Xberg Enterprise](https://github.com/xberg-io/xberg-enterprise) — managed extraction API with SDKs, dashboards, and observability.
253
253
  - [crawlberg](https://github.com/xberg-io/crawlberg) — web crawling and scraping with HTML→Markdown and headless-Chrome fallback.
254
254
  - [html-to-markdown](https://github.com/xberg-io/html-to-markdown) — fast, lossless HTML→Markdown engine.
255
- - [liter-llm](https://github.com/xberg-io/liter-llm) — universal LLM API client with native bindings for 14 languages and 163 providers.
255
+ - [liter-llm](https://github.com/xberg-io/liter-llm) — universal LLM API client with native bindings for 14 languages and 165 providers.
256
256
  - [tree-sitter-language-pack](https://github.com/xberg-io/tree-sitter-language-pack) — tree-sitter grammars and code-intelligence primitives.
257
257
  - [alef](https://github.com/xberg-io/alef) — the polyglot binding generator that produces every per-language binding across the 5 polyglot repos.
258
258
  - [Discord](https://discord.gg/xt9WY3GnKR) — community, roadmap, announcements.
@@ -1838,9 +1838,9 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
1838
1838
 
1839
1839
  [[package]]
1840
1840
  name = "liter-llm"
1841
- version = "1.10.1"
1841
+ version = "1.11.0"
1842
1842
  source = "registry+https://github.com/rust-lang/crates.io-index"
1843
- checksum = "c69b78084d1eed21747ab8352bbdedb0462724ff46e03986241aa71d326a81fa"
1843
+ checksum = "016fbd9e5fc66d4cb10eb5faa45242e54add93101816926fe9348bcfb0cb051a"
1844
1844
  dependencies = [
1845
1845
  "ahash 0.8.12",
1846
1846
  "arc-swap",
@@ -1881,7 +1881,7 @@ dependencies = [
1881
1881
 
1882
1882
  [[package]]
1883
1883
  name = "liter-llm-rb"
1884
- version = "1.10.1"
1884
+ version = "1.11.0"
1885
1885
  dependencies = [
1886
1886
  "futures",
1887
1887
  "liter-llm",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "liter-llm-rb"
3
- version = "1.10.1"
3
+ version = "1.11.0"
4
4
  edition = "2024"
5
5
  license = "MIT"
6
6
  description = "Universal LLM API client with Rust-powered polyglot bindings."
@@ -24,7 +24,7 @@ wasm-http = ["liter-llm/wasm-http"]
24
24
 
25
25
  [dependencies]
26
26
  futures = "0.3"
27
- liter-llm = { version = "1.10.1", features = ["native-http", "full"] }
27
+ liter-llm = { version = "1.11.0", features = ["native-http", "full"] }
28
28
  magnus = "0.8"
29
29
  rb-sys = ">=0.9, <0.9.128"
30
30
  serde = { version = "1", features = ["derive"] }
@@ -1,5 +1,5 @@
1
1
  // This file is auto-generated by alef. DO NOT EDIT.
2
- // alef:hash:f2d02d39ed23b63568387f22c991c70fd7b0d5c8f2f92cc028dcbaff825ca583
2
+ // alef:hash:c7947a41084f71e69944233535fbeda5cd13b37144078f1895b6b57a7802d3fe
3
3
  // Re-generate with: alef generate
4
4
  #![allow(dead_code, unused_imports, unused_variables)]
5
5
  #![allow(
@@ -415,6 +415,7 @@ pub struct AssistantMessage {
415
415
  tool_calls: Option<Vec<ToolCall>>,
416
416
  refusal: Option<String>,
417
417
  function_call: Option<FunctionCall>,
418
+ reasoning_content: Option<String>,
418
419
  }
419
420
 
420
421
  unsafe impl IntoValueFromNative for AssistantMessage {}
@@ -473,6 +474,9 @@ impl AssistantMessage {
473
474
  function_call: kwargs
474
475
  .get(ruby.to_symbol("function_call"))
475
476
  .and_then(|v| FunctionCall::try_convert(v).ok()),
477
+ reasoning_content: kwargs
478
+ .get(ruby.to_symbol("reasoning_content"))
479
+ .and_then(|v| String::try_convert(v).ok()),
476
480
  })
477
481
  }
478
482
 
@@ -496,6 +500,10 @@ impl AssistantMessage {
496
500
  self.function_call.clone()
497
501
  }
498
502
 
503
+ fn reasoning_content(&self) -> Option<String> {
504
+ self.reasoning_content.clone()
505
+ }
506
+
499
507
  fn text(&self) -> Option<String> {
500
508
  #[allow(clippy::needless_update)]
501
509
  let core_self = liter_llm::types::AssistantMessage {
@@ -509,6 +517,8 @@ impl AssistantMessage {
509
517
 
510
518
  function_call: self.function_call.clone().map(Into::into),
511
519
 
520
+ reasoning_content: self.reasoning_content.clone(),
521
+
512
522
  ..Default::default()
513
523
  };
514
524
  core_self.text()
@@ -527,11 +537,33 @@ impl AssistantMessage {
527
537
 
528
538
  function_call: self.function_call.clone().map(Into::into),
529
539
 
540
+ reasoning_content: self.reasoning_content.clone(),
541
+
530
542
  ..Default::default()
531
543
  };
532
544
  core_self.refusal_text().map(|v| v.to_owned())
533
545
  }
534
546
 
547
+ fn reasoning_text(&self) -> Option<String> {
548
+ #[allow(clippy::needless_update)]
549
+ let core_self = liter_llm::types::AssistantMessage {
550
+ content: self.content.clone().map(Into::into),
551
+
552
+ name: self.name.clone(),
553
+
554
+ tool_calls: self.tool_calls.clone().map(|v| v.into_iter().map(Into::into).collect()),
555
+
556
+ refusal: self.refusal.clone(),
557
+
558
+ function_call: self.function_call.clone().map(Into::into),
559
+
560
+ reasoning_content: self.reasoning_content.clone(),
561
+
562
+ ..Default::default()
563
+ };
564
+ core_self.reasoning_text().map(|v| v.to_owned())
565
+ }
566
+
535
567
  fn output_images(&self) -> Vec<ImageUrl> {
536
568
  #[allow(clippy::needless_update)]
537
569
  let core_self = liter_llm::types::AssistantMessage {
@@ -545,6 +577,8 @@ impl AssistantMessage {
545
577
 
546
578
  function_call: self.function_call.clone().map(Into::into),
547
579
 
580
+ reasoning_content: self.reasoning_content.clone(),
581
+
548
582
  ..Default::default()
549
583
  };
550
584
  core_self.output_images().into_iter().map(Into::into).collect()
@@ -563,6 +597,8 @@ impl AssistantMessage {
563
597
 
564
598
  function_call: self.function_call.clone().map(Into::into),
565
599
 
600
+ reasoning_content: self.reasoning_content.clone(),
601
+
566
602
  ..Default::default()
567
603
  };
568
604
  core_self.output_audio().into_iter().map(Into::into).collect()
@@ -2151,6 +2187,7 @@ pub struct StreamDelta {
2151
2187
  tool_calls: Option<Vec<StreamToolCall>>,
2152
2188
  function_call: Option<StreamFunctionCall>,
2153
2189
  refusal: Option<String>,
2190
+ reasoning_content: Option<String>,
2154
2191
  }
2155
2192
 
2156
2193
  unsafe impl IntoValueFromNative for StreamDelta {}
@@ -2209,6 +2246,9 @@ impl StreamDelta {
2209
2246
  refusal: kwargs
2210
2247
  .get(ruby.to_symbol("refusal"))
2211
2248
  .and_then(|v| String::try_convert(v).ok()),
2249
+ reasoning_content: kwargs
2250
+ .get(ruby.to_symbol("reasoning_content"))
2251
+ .and_then(|v| String::try_convert(v).ok()),
2212
2252
  })
2213
2253
  }
2214
2254
 
@@ -2232,6 +2272,10 @@ impl StreamDelta {
2232
2272
  self.refusal.clone()
2233
2273
  }
2234
2274
 
2275
+ fn reasoning_content(&self) -> Option<String> {
2276
+ self.reasoning_content.clone()
2277
+ }
2278
+
2235
2279
  #[allow(clippy::should_implement_trait)]
2236
2280
  fn to_s(&self) -> String {
2237
2281
  self.content.clone().unwrap_or_default()
@@ -2576,7 +2620,7 @@ impl EmbeddingResponse {
2576
2620
  #[magnus::wrap(class = "LiterLlm::EmbeddingObject")]
2577
2621
  pub struct EmbeddingObject {
2578
2622
  object: String,
2579
- embedding: Vec<f64>,
2623
+ embedding: Vec<f32>,
2580
2624
  index: u32,
2581
2625
  }
2582
2626
 
@@ -2621,7 +2665,7 @@ impl EmbeddingObject {
2621
2665
  .unwrap_or_default(),
2622
2666
  embedding: kwargs
2623
2667
  .get(ruby.to_symbol("embedding"))
2624
- .and_then(|v| <Vec<f64>>::try_convert(v).ok())
2668
+ .and_then(|v| <Vec<f32>>::try_convert(v).ok())
2625
2669
  .unwrap_or_default(),
2626
2670
  index: kwargs
2627
2671
  .get(ruby.to_symbol("index"))
@@ -2634,7 +2678,7 @@ impl EmbeddingObject {
2634
2678
  self.object.clone()
2635
2679
  }
2636
2680
 
2637
- fn embedding(&self) -> Vec<f64> {
2681
+ fn embedding(&self) -> Vec<f32> {
2638
2682
  self.embedding.clone()
2639
2683
  }
2640
2684
 
@@ -9945,6 +9989,7 @@ impl From<AssistantMessage> for liter_llm::types::AssistantMessage {
9945
9989
  tool_calls: val.tool_calls.map(|v| v.into_iter().map(Into::into).collect()),
9946
9990
  refusal: val.refusal,
9947
9991
  function_call: val.function_call.map(Into::into),
9992
+ reasoning_content: val.reasoning_content,
9948
9993
  ..Default::default()
9949
9994
  }
9950
9995
  }
@@ -9959,6 +10004,7 @@ impl From<liter_llm::types::AssistantMessage> for AssistantMessage {
9959
10004
  tool_calls: val.tool_calls.map(|v| v.into_iter().map(Into::into).collect()),
9960
10005
  refusal: val.refusal.map(|v| v.to_string()),
9961
10006
  function_call: val.function_call.map(Into::into),
10007
+ reasoning_content: val.reasoning_content.map(|v| v.to_string()),
9962
10008
  }
9963
10009
  }
9964
10010
  }
@@ -10407,6 +10453,7 @@ impl From<liter_llm::types::StreamDelta> for StreamDelta {
10407
10453
  tool_calls: val.tool_calls.map(|v| v.into_iter().map(Into::into).collect()),
10408
10454
  function_call: val.function_call.map(Into::into),
10409
10455
  refusal: val.refusal.map(|v| v.to_string()),
10456
+ reasoning_content: val.reasoning_content.map(|v| v.to_string()),
10410
10457
  }
10411
10458
  }
10412
10459
  }
@@ -12707,10 +12754,14 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
12707
12754
 
12708
12755
  class.define_method("function_call", method!(AssistantMessage::function_call, 0))?;
12709
12756
 
12757
+ class.define_method("reasoning_content", method!(AssistantMessage::reasoning_content, 0))?;
12758
+
12710
12759
  class.define_method("text", method!(AssistantMessage::text, 0))?;
12711
12760
 
12712
12761
  class.define_method("refusal_text", method!(AssistantMessage::refusal_text, 0))?;
12713
12762
 
12763
+ class.define_method("reasoning_text", method!(AssistantMessage::reasoning_text, 0))?;
12764
+
12714
12765
  class.define_method("output_images", method!(AssistantMessage::output_images, 0))?;
12715
12766
 
12716
12767
  class.define_method("output_audio", method!(AssistantMessage::output_audio, 0))?;
@@ -12969,6 +13020,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
12969
13020
 
12970
13021
  class.define_method("refusal", method!(StreamDelta::refusal, 0))?;
12971
13022
 
13023
+ class.define_method("reasoning_content", method!(StreamDelta::reasoning_content, 0))?;
13024
+
12972
13025
  class.define_method("to_s", method!(StreamDelta::to_s, 0))?;
12973
13026
 
12974
13027
  let class = module.define_class("StreamToolCall", ruby.class_object())?;
@@ -1,12 +1,39 @@
1
1
  # This file is auto-generated by alef — DO NOT EDIT.
2
- # alef:hash:f2d02d39ed23b63568387f22c991c70fd7b0d5c8f2f92cc028dcbaff825ca583
2
+ # alef:hash:c7947a41084f71e69944233535fbeda5cd13b37144078f1895b6b57a7802d3fe
3
3
  # To regenerate: alef generate
4
4
  # To verify freshness: alef verify --exit-code
5
5
  # frozen_string_literal: true
6
6
 
7
7
  require "json"
8
8
  require "sorbet-runtime"
9
- require "liter_llm_rb"
9
+ require "rbconfig"
10
+
11
+ extension_name = "liter_llm_rb"
12
+ # Ruby may expose more than one shared-library extension via DLEXT/DLEXT2.
13
+ dlexts = [RbConfig::CONFIG["DLEXT"], RbConfig::CONFIG["DLEXT2"]].compact.uniq
14
+ ruby_abi = RbConfig::CONFIG.fetch("ruby_version")
15
+
16
+ library_candidates = dlexts.flat_map do |dlext|
17
+ [
18
+ File.join(__dir__, "..", extension_name, ruby_abi, "#{extension_name}.#{dlext}"),
19
+ File.join(__dir__, "..", extension_name, ruby_abi, "lib#{extension_name}.#{dlext}"),
20
+ File.join(__dir__, "..", "#{extension_name}.#{dlext}"),
21
+ File.join(__dir__, "..", "lib#{extension_name}.#{dlext}"),
22
+ ]
23
+ end
24
+
25
+ expanded_candidates = library_candidates.map { |path| File.expand_path(path) }
26
+ native_extension = expanded_candidates.find { |path| File.file?(path) }
27
+
28
+ unless native_extension
29
+ raise(
30
+ LoadError,
31
+ "cannot find #{extension_name} native extension for Ruby ABI #{ruby_abi}; " \
32
+ "searched: #{expanded_candidates.join(", ")}"
33
+ )
34
+ end
35
+
36
+ require native_extension
10
37
  module LiterLlm
11
38
  # A chat message in a conversation.
12
39
  module Message
@@ -1,10 +1,10 @@
1
1
  # This file is auto-generated by alef — DO NOT EDIT.
2
- # alef:hash:f2d02d39ed23b63568387f22c991c70fd7b0d5c8f2f92cc028dcbaff825ca583
2
+ # alef:hash:c7947a41084f71e69944233535fbeda5cd13b37144078f1895b6b57a7802d3fe
3
3
  # To regenerate: alef generate
4
4
  # To verify freshness: alef verify --exit-code
5
5
  # frozen_string_literal: true
6
6
 
7
7
  module LiterLlm
8
8
  ## The version string for this package.
9
- VERSION = "1.10.1"
9
+ VERSION = "1.11.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:f2d02d39ed23b63568387f22c991c70fd7b0d5c8f2f92cc028dcbaff825ca583
2
+ # alef:hash:c7947a41084f71e69944233535fbeda5cd13b37144078f1895b6b57a7802d3fe
3
3
  # To regenerate: alef generate
4
4
  # To verify freshness: alef verify --exit-code
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:f2d02d39ed23b63568387f22c991c70fd7b0d5c8f2f92cc028dcbaff825ca583
2
+ # alef:hash:c7947a41084f71e69944233535fbeda5cd13b37144078f1895b6b57a7802d3fe
3
3
  # To regenerate: alef generate
4
4
  # To verify freshness: alef verify --exit-code
5
5
 
@@ -50,10 +50,12 @@ module LiterLlm
50
50
  attr_accessor tool_calls: Array[ToolCall]?
51
51
  attr_accessor refusal: String?
52
52
  attr_accessor function_call: FunctionCall?
53
+ attr_accessor reasoning_content: String?
53
54
 
54
- def initialize: (?content: AssistantContent, ?name: String, ?tool_calls: Array[ToolCall], ?refusal: String, ?function_call: FunctionCall) -> void
55
+ def initialize: (?content: AssistantContent, ?name: String, ?tool_calls: Array[ToolCall], ?refusal: String, ?function_call: FunctionCall, ?reasoning_content: String) -> void
55
56
  def text: () -> String?
56
57
  def refusal_text: () -> String?
58
+ def reasoning_text: () -> String?
57
59
  def output_images: () -> Array[ImageUrl]
58
60
  def output_audio: () -> Array[AudioContent]
59
61
  end
@@ -229,8 +231,9 @@ module LiterLlm
229
231
  attr_accessor tool_calls: Array[StreamToolCall]?
230
232
  attr_accessor function_call: StreamFunctionCall?
231
233
  attr_accessor refusal: String?
234
+ attr_accessor reasoning_content: String?
232
235
 
233
- def initialize: (?role: String, ?content: String, ?tool_calls: Array[StreamToolCall], ?function_call: StreamFunctionCall, ?refusal: String) -> void
236
+ def initialize: (?role: String, ?content: String, ?tool_calls: Array[StreamToolCall], ?function_call: StreamFunctionCall, ?refusal: String, ?reasoning_content: String) -> void
234
237
  end
235
238
 
236
239
  class StreamToolCall
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.10.1
4
+ version: 1.11.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-07-20 00:00:00.000000000 Z
11
+ date: 2026-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rb_sys