liter_llm 2.3.0 → 2.4.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.
@@ -1,5 +1,5 @@
1
1
  // This file is auto-generated by alef. DO NOT EDIT.
2
- // alef:hash:3861ed195f3c3e52018feb23f8f7da4fefbc958be2e63235f137618ed6fec98a
2
+ // alef:hash:f56903f2fe41ec4d6589bdea2776c5b41c4a388341f774d49faee678da6246dc
3
3
  // Re-generate with: alef generate
4
4
  #![allow(dead_code, unused_imports, unused_variables)]
5
5
  #![allow(
@@ -1539,6 +1539,268 @@ impl CatalogInfo {
1539
1539
  }
1540
1540
  }
1541
1541
 
1542
+ #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
1543
+ #[serde(default)]
1544
+ #[magnus::wrap(class = "LiterLlm::CatalogModel")]
1545
+ pub struct CatalogModel {
1546
+ key: String,
1547
+ provider: String,
1548
+ model: String,
1549
+ mode: Option<String>,
1550
+ max_tokens: Option<u64>,
1551
+ max_input_tokens: Option<u64>,
1552
+ max_output_tokens: Option<u64>,
1553
+ supports_vision: Option<bool>,
1554
+ supports_function_calling: Option<bool>,
1555
+ supports_reasoning: Option<bool>,
1556
+ supports_structured_output: Option<bool>,
1557
+ supports_audio_input: Option<bool>,
1558
+ supports_audio_output: Option<bool>,
1559
+ supports_prompt_caching: Option<bool>,
1560
+ }
1561
+
1562
+ unsafe impl IntoValueFromNative for CatalogModel {}
1563
+
1564
+ impl magnus::TryConvert for CatalogModel {
1565
+ fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
1566
+ if let Ok(r) = <&CatalogModel as magnus::TryConvert>::try_convert(val) {
1567
+ return Ok(r.clone());
1568
+ }
1569
+ let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
1570
+ s
1571
+ } else {
1572
+ val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
1573
+ magnus::Error::new(
1574
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1575
+ format!("no implicit conversion into CatalogModel: {}", e),
1576
+ )
1577
+ })?
1578
+ };
1579
+ serde_json::from_str::<CatalogModel>(&json_str).map_err(|e| {
1580
+ magnus::Error::new(
1581
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1582
+ format!("failed to deserialize CatalogModel: {}", e),
1583
+ )
1584
+ })
1585
+ }
1586
+ }
1587
+
1588
+ unsafe impl TryConvertOwned for CatalogModel {}
1589
+
1590
+ impl Default for CatalogModel {
1591
+ fn default() -> Self {
1592
+ liter_llm::CatalogModel::default().into()
1593
+ }
1594
+ }
1595
+
1596
+ impl CatalogModel {
1597
+ fn new(args: &[magnus::Value]) -> Result<Self, magnus::Error> {
1598
+ let ruby = unsafe { magnus::Ruby::get_unchecked() };
1599
+ let args = magnus::scan_args::scan_args::<(), (Option<magnus::RHash>,), (), (), (), ()>(args)?;
1600
+ let (kwargs_opt,) = args.optional;
1601
+ let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
1602
+ Ok(Self {
1603
+ key: match kwargs.get(ruby.to_symbol("key")) {
1604
+ Some(v) => String::try_convert(v).map_err(|e| {
1605
+ magnus::Error::new(
1606
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1607
+ format!("invalid value for `key`: {}", e),
1608
+ )
1609
+ })?,
1610
+ None => Default::default(),
1611
+ },
1612
+ provider: match kwargs.get(ruby.to_symbol("provider")) {
1613
+ Some(v) => String::try_convert(v).map_err(|e| {
1614
+ magnus::Error::new(
1615
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1616
+ format!("invalid value for `provider`: {}", e),
1617
+ )
1618
+ })?,
1619
+ None => Default::default(),
1620
+ },
1621
+ model: match kwargs.get(ruby.to_symbol("model")) {
1622
+ Some(v) => String::try_convert(v).map_err(|e| {
1623
+ magnus::Error::new(
1624
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1625
+ format!("invalid value for `model`: {}", e),
1626
+ )
1627
+ })?,
1628
+ None => Default::default(),
1629
+ },
1630
+ mode: match kwargs.get(ruby.to_symbol("mode")).filter(|v| !v.is_nil()) {
1631
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
1632
+ magnus::Error::new(
1633
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1634
+ format!("invalid value for `mode`: {}", e),
1635
+ )
1636
+ })?),
1637
+ None => None,
1638
+ },
1639
+ max_tokens: match kwargs.get(ruby.to_symbol("max_tokens")).filter(|v| !v.is_nil()) {
1640
+ Some(v) => Some(u64::try_convert(v).map_err(|e| {
1641
+ magnus::Error::new(
1642
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1643
+ format!("invalid value for `max_tokens`: {}", e),
1644
+ )
1645
+ })?),
1646
+ None => None,
1647
+ },
1648
+ max_input_tokens: match kwargs.get(ruby.to_symbol("max_input_tokens")).filter(|v| !v.is_nil()) {
1649
+ Some(v) => Some(u64::try_convert(v).map_err(|e| {
1650
+ magnus::Error::new(
1651
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1652
+ format!("invalid value for `max_input_tokens`: {}", e),
1653
+ )
1654
+ })?),
1655
+ None => None,
1656
+ },
1657
+ max_output_tokens: match kwargs.get(ruby.to_symbol("max_output_tokens")).filter(|v| !v.is_nil()) {
1658
+ Some(v) => Some(u64::try_convert(v).map_err(|e| {
1659
+ magnus::Error::new(
1660
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1661
+ format!("invalid value for `max_output_tokens`: {}", e),
1662
+ )
1663
+ })?),
1664
+ None => None,
1665
+ },
1666
+ supports_vision: match kwargs.get(ruby.to_symbol("supports_vision")).filter(|v| !v.is_nil()) {
1667
+ Some(v) => Some(bool::try_convert(v).map_err(|e| {
1668
+ magnus::Error::new(
1669
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1670
+ format!("invalid value for `supports_vision`: {}", e),
1671
+ )
1672
+ })?),
1673
+ None => None,
1674
+ },
1675
+ supports_function_calling: match kwargs
1676
+ .get(ruby.to_symbol("supports_function_calling"))
1677
+ .filter(|v| !v.is_nil())
1678
+ {
1679
+ Some(v) => Some(bool::try_convert(v).map_err(|e| {
1680
+ magnus::Error::new(
1681
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1682
+ format!("invalid value for `supports_function_calling`: {}", e),
1683
+ )
1684
+ })?),
1685
+ None => None,
1686
+ },
1687
+ supports_reasoning: match kwargs.get(ruby.to_symbol("supports_reasoning")).filter(|v| !v.is_nil()) {
1688
+ Some(v) => Some(bool::try_convert(v).map_err(|e| {
1689
+ magnus::Error::new(
1690
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1691
+ format!("invalid value for `supports_reasoning`: {}", e),
1692
+ )
1693
+ })?),
1694
+ None => None,
1695
+ },
1696
+ supports_structured_output: match kwargs
1697
+ .get(ruby.to_symbol("supports_structured_output"))
1698
+ .filter(|v| !v.is_nil())
1699
+ {
1700
+ Some(v) => Some(bool::try_convert(v).map_err(|e| {
1701
+ magnus::Error::new(
1702
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1703
+ format!("invalid value for `supports_structured_output`: {}", e),
1704
+ )
1705
+ })?),
1706
+ None => None,
1707
+ },
1708
+ supports_audio_input: match kwargs
1709
+ .get(ruby.to_symbol("supports_audio_input"))
1710
+ .filter(|v| !v.is_nil())
1711
+ {
1712
+ Some(v) => Some(bool::try_convert(v).map_err(|e| {
1713
+ magnus::Error::new(
1714
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1715
+ format!("invalid value for `supports_audio_input`: {}", e),
1716
+ )
1717
+ })?),
1718
+ None => None,
1719
+ },
1720
+ supports_audio_output: match kwargs
1721
+ .get(ruby.to_symbol("supports_audio_output"))
1722
+ .filter(|v| !v.is_nil())
1723
+ {
1724
+ Some(v) => Some(bool::try_convert(v).map_err(|e| {
1725
+ magnus::Error::new(
1726
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1727
+ format!("invalid value for `supports_audio_output`: {}", e),
1728
+ )
1729
+ })?),
1730
+ None => None,
1731
+ },
1732
+ supports_prompt_caching: match kwargs
1733
+ .get(ruby.to_symbol("supports_prompt_caching"))
1734
+ .filter(|v| !v.is_nil())
1735
+ {
1736
+ Some(v) => Some(bool::try_convert(v).map_err(|e| {
1737
+ magnus::Error::new(
1738
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1739
+ format!("invalid value for `supports_prompt_caching`: {}", e),
1740
+ )
1741
+ })?),
1742
+ None => None,
1743
+ },
1744
+ })
1745
+ }
1746
+
1747
+ fn key(&self) -> String {
1748
+ self.key.clone()
1749
+ }
1750
+
1751
+ fn provider(&self) -> String {
1752
+ self.provider.clone()
1753
+ }
1754
+
1755
+ fn model(&self) -> String {
1756
+ self.model.clone()
1757
+ }
1758
+
1759
+ fn mode(&self) -> Option<String> {
1760
+ self.mode.clone()
1761
+ }
1762
+
1763
+ fn max_tokens(&self) -> Option<u64> {
1764
+ self.max_tokens
1765
+ }
1766
+
1767
+ fn max_input_tokens(&self) -> Option<u64> {
1768
+ self.max_input_tokens
1769
+ }
1770
+
1771
+ fn max_output_tokens(&self) -> Option<u64> {
1772
+ self.max_output_tokens
1773
+ }
1774
+
1775
+ fn supports_vision(&self) -> Option<bool> {
1776
+ self.supports_vision
1777
+ }
1778
+
1779
+ fn supports_function_calling(&self) -> Option<bool> {
1780
+ self.supports_function_calling
1781
+ }
1782
+
1783
+ fn supports_reasoning(&self) -> Option<bool> {
1784
+ self.supports_reasoning
1785
+ }
1786
+
1787
+ fn supports_structured_output(&self) -> Option<bool> {
1788
+ self.supports_structured_output
1789
+ }
1790
+
1791
+ fn supports_audio_input(&self) -> Option<bool> {
1792
+ self.supports_audio_input
1793
+ }
1794
+
1795
+ fn supports_audio_output(&self) -> Option<bool> {
1796
+ self.supports_audio_output
1797
+ }
1798
+
1799
+ fn supports_prompt_caching(&self) -> Option<bool> {
1800
+ self.supports_prompt_caching
1801
+ }
1802
+ }
1803
+
1542
1804
  #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
1543
1805
  #[serde(default)]
1544
1806
  #[magnus::wrap(class = "LiterLlm::CatalogRefreshConfig")]
@@ -2681,6 +2943,7 @@ pub struct ClientOptions {
2681
2943
  api_key: String,
2682
2944
  base_url: Option<String>,
2683
2945
  timeout_secs: Option<u64>,
2946
+ connect_timeout_secs: Option<u64>,
2684
2947
  max_retries: Option<u32>,
2685
2948
  max_response_bytes: Option<u64>,
2686
2949
  model_hint: Option<String>,
@@ -2759,6 +3022,18 @@ impl ClientOptions {
2759
3022
  })?),
2760
3023
  None => None,
2761
3024
  },
3025
+ connect_timeout_secs: match kwargs
3026
+ .get(ruby.to_symbol("connect_timeout_secs"))
3027
+ .filter(|v| !v.is_nil())
3028
+ {
3029
+ Some(v) => Some(u64::try_convert(v).map_err(|e| {
3030
+ magnus::Error::new(
3031
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3032
+ format!("invalid value for `connect_timeout_secs`: {}", e),
3033
+ )
3034
+ })?),
3035
+ None => None,
3036
+ },
2762
3037
  max_retries: match kwargs.get(ruby.to_symbol("max_retries")).filter(|v| !v.is_nil()) {
2763
3038
  Some(v) => Some(u32::try_convert(v).map_err(|e| {
2764
3039
  magnus::Error::new(
@@ -2801,6 +3076,10 @@ impl ClientOptions {
2801
3076
  self.timeout_secs
2802
3077
  }
2803
3078
 
3079
+ fn connect_timeout_secs(&self) -> Option<u64> {
3080
+ self.connect_timeout_secs
3081
+ }
3082
+
2804
3083
  fn max_retries(&self) -> Option<u32> {
2805
3084
  self.max_retries
2806
3085
  }
@@ -3115,6 +3394,7 @@ pub struct CreateImageRequest {
3115
3394
  style: Option<String>,
3116
3395
  response_format: Option<String>,
3117
3396
  user: Option<String>,
3397
+ extra_body: Option<String>,
3118
3398
  }
3119
3399
 
3120
3400
  unsafe impl IntoValueFromNative for CreateImageRequest {}
@@ -3238,6 +3518,15 @@ impl CreateImageRequest {
3238
3518
  })?),
3239
3519
  None => None,
3240
3520
  },
3521
+ extra_body: match kwargs.get(ruby.to_symbol("extra_body")).filter(|v| !v.is_nil()) {
3522
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3523
+ magnus::Error::new(
3524
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3525
+ format!("invalid value for `extra_body`: {}", e),
3526
+ )
3527
+ })?),
3528
+ None => None,
3529
+ },
3241
3530
  })
3242
3531
  }
3243
3532
 
@@ -3272,6 +3561,10 @@ impl CreateImageRequest {
3272
3561
  fn user(&self) -> Option<String> {
3273
3562
  self.user.clone()
3274
3563
  }
3564
+
3565
+ fn extra_body(&self) -> Option<String> {
3566
+ self.extra_body.clone()
3567
+ }
3275
3568
  }
3276
3569
 
3277
3570
  #[derive(Clone, Debug, serde::Serialize)]
@@ -3468,6 +3761,7 @@ pub struct CreateSpeechRequest {
3468
3761
  voice: String,
3469
3762
  response_format: Option<String>,
3470
3763
  speed: Option<f64>,
3764
+ extra_body: Option<String>,
3471
3765
  }
3472
3766
 
3473
3767
  unsafe impl IntoValueFromNative for CreateSpeechRequest {}
@@ -3564,6 +3858,15 @@ impl CreateSpeechRequest {
3564
3858
  })?),
3565
3859
  None => None,
3566
3860
  },
3861
+ extra_body: match kwargs.get(ruby.to_symbol("extra_body")).filter(|v| !v.is_nil()) {
3862
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
3863
+ magnus::Error::new(
3864
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
3865
+ format!("invalid value for `extra_body`: {}", e),
3866
+ )
3867
+ })?),
3868
+ None => None,
3869
+ },
3567
3870
  })
3568
3871
  }
3569
3872
 
@@ -3586,6 +3889,10 @@ impl CreateSpeechRequest {
3586
3889
  fn speed(&self) -> Option<f64> {
3587
3890
  self.speed
3588
3891
  }
3892
+
3893
+ fn extra_body(&self) -> Option<String> {
3894
+ self.extra_body.clone()
3895
+ }
3589
3896
  }
3590
3897
 
3591
3898
  #[derive(Clone, Debug, serde::Serialize)]
@@ -3598,6 +3905,7 @@ pub struct CreateTranscriptionRequest {
3598
3905
  prompt: Option<String>,
3599
3906
  response_format: Option<String>,
3600
3907
  temperature: Option<f64>,
3908
+ extra_body: Option<String>,
3601
3909
  }
3602
3910
 
3603
3911
  unsafe impl IntoValueFromNative for CreateTranscriptionRequest {}
@@ -3703,6 +4011,15 @@ impl CreateTranscriptionRequest {
3703
4011
  })?),
3704
4012
  None => None,
3705
4013
  },
4014
+ extra_body: match kwargs.get(ruby.to_symbol("extra_body")).filter(|v| !v.is_nil()) {
4015
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
4016
+ magnus::Error::new(
4017
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
4018
+ format!("invalid value for `extra_body`: {}", e),
4019
+ )
4020
+ })?),
4021
+ None => None,
4022
+ },
3706
4023
  })
3707
4024
  }
3708
4025
 
@@ -3729,6 +4046,10 @@ impl CreateTranscriptionRequest {
3729
4046
  fn temperature(&self) -> Option<f64> {
3730
4047
  self.temperature
3731
4048
  }
4049
+
4050
+ fn extra_body(&self) -> Option<String> {
4051
+ self.extra_body.clone()
4052
+ }
3732
4053
  }
3733
4054
 
3734
4055
  #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
@@ -3950,18 +4271,10 @@ impl DefaultClient {
3950
4271
  .enable_all()
3951
4272
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
3952
4273
  .build()
3953
- .map_err(|e| {
3954
- magnus::Error::new(
3955
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
3956
- e.to_string(),
3957
- )
3958
- })?;
3959
- let result = rt.block_on(async { inner.chat(req_core).await }).map_err(|e| {
3960
- magnus::Error::new(
3961
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
3962
- e.to_string(),
3963
- )
3964
- })?;
4274
+ .map_err(alef_magnus_err)?;
4275
+ let result = rt
4276
+ .block_on(async { inner.chat(req_core).await })
4277
+ .map_err(alef_magnus_err)?;
3965
4278
  Ok(result.into())
3966
4279
  }
3967
4280
 
@@ -3977,18 +4290,10 @@ impl DefaultClient {
3977
4290
  .enable_all()
3978
4291
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
3979
4292
  .build()
3980
- .map_err(|e| {
3981
- magnus::Error::new(
3982
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
3983
- e.to_string(),
3984
- )
3985
- })?;
3986
- let result = rt.block_on(async { inner.embed(req_core).await }).map_err(|e| {
3987
- magnus::Error::new(
3988
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
3989
- e.to_string(),
3990
- )
3991
- })?;
4293
+ .map_err(alef_magnus_err)?;
4294
+ let result = rt
4295
+ .block_on(async { inner.embed(req_core).await })
4296
+ .map_err(alef_magnus_err)?;
3992
4297
  Ok(result.into())
3993
4298
  }
3994
4299
 
@@ -4003,18 +4308,10 @@ impl DefaultClient {
4003
4308
  .enable_all()
4004
4309
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4005
4310
  .build()
4006
- .map_err(|e| {
4007
- magnus::Error::new(
4008
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4009
- e.to_string(),
4010
- )
4011
- })?;
4012
- let result = rt.block_on(async { inner.list_models().await }).map_err(|e| {
4013
- magnus::Error::new(
4014
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4015
- e.to_string(),
4016
- )
4017
- })?;
4311
+ .map_err(alef_magnus_err)?;
4312
+ let result = rt
4313
+ .block_on(async { inner.list_models().await })
4314
+ .map_err(alef_magnus_err)?;
4018
4315
  Ok(result.into())
4019
4316
  }
4020
4317
 
@@ -4030,20 +4327,10 @@ impl DefaultClient {
4030
4327
  .enable_all()
4031
4328
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4032
4329
  .build()
4033
- .map_err(|e| {
4034
- magnus::Error::new(
4035
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4036
- e.to_string(),
4037
- )
4038
- })?;
4330
+ .map_err(alef_magnus_err)?;
4039
4331
  let result = rt
4040
4332
  .block_on(async { inner.image_generate(req_core).await })
4041
- .map_err(|e| {
4042
- magnus::Error::new(
4043
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4044
- e.to_string(),
4045
- )
4046
- })?;
4333
+ .map_err(alef_magnus_err)?;
4047
4334
  Ok(result.into())
4048
4335
  }
4049
4336
 
@@ -4059,18 +4346,10 @@ impl DefaultClient {
4059
4346
  .enable_all()
4060
4347
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4061
4348
  .build()
4062
- .map_err(|e| {
4063
- magnus::Error::new(
4064
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4065
- e.to_string(),
4066
- )
4067
- })?;
4068
- let result = rt.block_on(async { inner.speech(req_core).await }).map_err(|e| {
4069
- magnus::Error::new(
4070
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4071
- e.to_string(),
4072
- )
4073
- })?;
4349
+ .map_err(alef_magnus_err)?;
4350
+ let result = rt
4351
+ .block_on(async { inner.speech(req_core).await })
4352
+ .map_err(alef_magnus_err)?;
4074
4353
  Ok(result.to_vec())
4075
4354
  }
4076
4355
 
@@ -4086,18 +4365,10 @@ impl DefaultClient {
4086
4365
  .enable_all()
4087
4366
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4088
4367
  .build()
4089
- .map_err(|e| {
4090
- magnus::Error::new(
4091
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4092
- e.to_string(),
4093
- )
4094
- })?;
4095
- let result = rt.block_on(async { inner.transcribe(req_core).await }).map_err(|e| {
4096
- magnus::Error::new(
4097
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4098
- e.to_string(),
4099
- )
4100
- })?;
4368
+ .map_err(alef_magnus_err)?;
4369
+ let result = rt
4370
+ .block_on(async { inner.transcribe(req_core).await })
4371
+ .map_err(alef_magnus_err)?;
4101
4372
  Ok(result.into())
4102
4373
  }
4103
4374
 
@@ -4113,18 +4384,10 @@ impl DefaultClient {
4113
4384
  .enable_all()
4114
4385
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4115
4386
  .build()
4116
- .map_err(|e| {
4117
- magnus::Error::new(
4118
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4119
- e.to_string(),
4120
- )
4121
- })?;
4122
- let result = rt.block_on(async { inner.moderate(req_core).await }).map_err(|e| {
4123
- magnus::Error::new(
4124
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4125
- e.to_string(),
4126
- )
4127
- })?;
4387
+ .map_err(alef_magnus_err)?;
4388
+ let result = rt
4389
+ .block_on(async { inner.moderate(req_core).await })
4390
+ .map_err(alef_magnus_err)?;
4128
4391
  Ok(result.into())
4129
4392
  }
4130
4393
 
@@ -4140,18 +4403,10 @@ impl DefaultClient {
4140
4403
  .enable_all()
4141
4404
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4142
4405
  .build()
4143
- .map_err(|e| {
4144
- magnus::Error::new(
4145
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4146
- e.to_string(),
4147
- )
4148
- })?;
4149
- let result = rt.block_on(async { inner.rerank(req_core).await }).map_err(|e| {
4150
- magnus::Error::new(
4151
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4152
- e.to_string(),
4153
- )
4154
- })?;
4406
+ .map_err(alef_magnus_err)?;
4407
+ let result = rt
4408
+ .block_on(async { inner.rerank(req_core).await })
4409
+ .map_err(alef_magnus_err)?;
4155
4410
  Ok(result.into())
4156
4411
  }
4157
4412
 
@@ -4167,18 +4422,10 @@ impl DefaultClient {
4167
4422
  .enable_all()
4168
4423
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4169
4424
  .build()
4170
- .map_err(|e| {
4171
- magnus::Error::new(
4172
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4173
- e.to_string(),
4174
- )
4175
- })?;
4176
- let result = rt.block_on(async { inner.search(req_core).await }).map_err(|e| {
4177
- magnus::Error::new(
4178
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4179
- e.to_string(),
4180
- )
4181
- })?;
4425
+ .map_err(alef_magnus_err)?;
4426
+ let result = rt
4427
+ .block_on(async { inner.search(req_core).await })
4428
+ .map_err(alef_magnus_err)?;
4182
4429
  Ok(result.into())
4183
4430
  }
4184
4431
 
@@ -4194,18 +4441,10 @@ impl DefaultClient {
4194
4441
  .enable_all()
4195
4442
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4196
4443
  .build()
4197
- .map_err(|e| {
4198
- magnus::Error::new(
4199
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4200
- e.to_string(),
4201
- )
4202
- })?;
4203
- let result = rt.block_on(async { inner.ocr(req_core).await }).map_err(|e| {
4204
- magnus::Error::new(
4205
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4206
- e.to_string(),
4207
- )
4208
- })?;
4444
+ .map_err(alef_magnus_err)?;
4445
+ let result = rt
4446
+ .block_on(async { inner.ocr(req_core).await })
4447
+ .map_err(alef_magnus_err)?;
4209
4448
  Ok(result.into())
4210
4449
  }
4211
4450
 
@@ -4221,18 +4460,10 @@ impl DefaultClient {
4221
4460
  .enable_all()
4222
4461
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4223
4462
  .build()
4224
- .map_err(|e| {
4225
- magnus::Error::new(
4226
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4227
- e.to_string(),
4228
- )
4229
- })?;
4230
- let result = rt.block_on(async { inner.create_file(req_core).await }).map_err(|e| {
4231
- magnus::Error::new(
4232
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4233
- e.to_string(),
4234
- )
4235
- })?;
4463
+ .map_err(alef_magnus_err)?;
4464
+ let result = rt
4465
+ .block_on(async { inner.create_file(req_core).await })
4466
+ .map_err(alef_magnus_err)?;
4236
4467
  Ok(result.into())
4237
4468
  }
4238
4469
 
@@ -4247,20 +4478,10 @@ impl DefaultClient {
4247
4478
  .enable_all()
4248
4479
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4249
4480
  .build()
4250
- .map_err(|e| {
4251
- magnus::Error::new(
4252
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4253
- e.to_string(),
4254
- )
4255
- })?;
4481
+ .map_err(alef_magnus_err)?;
4256
4482
  let result = rt
4257
4483
  .block_on(async { inner.retrieve_file(&file_id).await })
4258
- .map_err(|e| {
4259
- magnus::Error::new(
4260
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4261
- e.to_string(),
4262
- )
4263
- })?;
4484
+ .map_err(alef_magnus_err)?;
4264
4485
  Ok(result.into())
4265
4486
  }
4266
4487
 
@@ -4275,18 +4496,10 @@ impl DefaultClient {
4275
4496
  .enable_all()
4276
4497
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4277
4498
  .build()
4278
- .map_err(|e| {
4279
- magnus::Error::new(
4280
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4281
- e.to_string(),
4282
- )
4283
- })?;
4284
- let result = rt.block_on(async { inner.delete_file(&file_id).await }).map_err(|e| {
4285
- magnus::Error::new(
4286
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4287
- e.to_string(),
4288
- )
4289
- })?;
4499
+ .map_err(alef_magnus_err)?;
4500
+ let result = rt
4501
+ .block_on(async { inner.delete_file(&file_id).await })
4502
+ .map_err(alef_magnus_err)?;
4290
4503
  Ok(result.into())
4291
4504
  }
4292
4505
 
@@ -4302,18 +4515,10 @@ impl DefaultClient {
4302
4515
  .enable_all()
4303
4516
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4304
4517
  .build()
4305
- .map_err(|e| {
4306
- magnus::Error::new(
4307
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4308
- e.to_string(),
4309
- )
4310
- })?;
4311
- let result = rt.block_on(async { inner.list_files(query_core).await }).map_err(|e| {
4312
- magnus::Error::new(
4313
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4314
- e.to_string(),
4315
- )
4316
- })?;
4518
+ .map_err(alef_magnus_err)?;
4519
+ let result = rt
4520
+ .block_on(async { inner.list_files(query_core).await })
4521
+ .map_err(alef_magnus_err)?;
4317
4522
  Ok(result.into())
4318
4523
  }
4319
4524
 
@@ -4328,18 +4533,10 @@ impl DefaultClient {
4328
4533
  .enable_all()
4329
4534
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4330
4535
  .build()
4331
- .map_err(|e| {
4332
- magnus::Error::new(
4333
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4334
- e.to_string(),
4335
- )
4336
- })?;
4337
- let result = rt.block_on(async { inner.file_content(&file_id).await }).map_err(|e| {
4338
- magnus::Error::new(
4339
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4340
- e.to_string(),
4341
- )
4342
- })?;
4536
+ .map_err(alef_magnus_err)?;
4537
+ let result = rt
4538
+ .block_on(async { inner.file_content(&file_id).await })
4539
+ .map_err(alef_magnus_err)?;
4343
4540
  Ok(result.to_vec())
4344
4541
  }
4345
4542
 
@@ -4355,18 +4552,10 @@ impl DefaultClient {
4355
4552
  .enable_all()
4356
4553
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4357
4554
  .build()
4358
- .map_err(|e| {
4359
- magnus::Error::new(
4360
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4361
- e.to_string(),
4362
- )
4363
- })?;
4364
- let result = rt.block_on(async { inner.create_batch(req_core).await }).map_err(|e| {
4365
- magnus::Error::new(
4366
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4367
- e.to_string(),
4368
- )
4369
- })?;
4555
+ .map_err(alef_magnus_err)?;
4556
+ let result = rt
4557
+ .block_on(async { inner.create_batch(req_core).await })
4558
+ .map_err(alef_magnus_err)?;
4370
4559
  Ok(result.into())
4371
4560
  }
4372
4561
 
@@ -4381,20 +4570,10 @@ impl DefaultClient {
4381
4570
  .enable_all()
4382
4571
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4383
4572
  .build()
4384
- .map_err(|e| {
4385
- magnus::Error::new(
4386
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4387
- e.to_string(),
4388
- )
4389
- })?;
4573
+ .map_err(alef_magnus_err)?;
4390
4574
  let result = rt
4391
4575
  .block_on(async { inner.retrieve_batch(&batch_id).await })
4392
- .map_err(|e| {
4393
- magnus::Error::new(
4394
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4395
- e.to_string(),
4396
- )
4397
- })?;
4576
+ .map_err(alef_magnus_err)?;
4398
4577
  Ok(result.into())
4399
4578
  }
4400
4579
 
@@ -4410,20 +4589,10 @@ impl DefaultClient {
4410
4589
  .enable_all()
4411
4590
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4412
4591
  .build()
4413
- .map_err(|e| {
4414
- magnus::Error::new(
4415
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4416
- e.to_string(),
4417
- )
4418
- })?;
4592
+ .map_err(alef_magnus_err)?;
4419
4593
  let result = rt
4420
4594
  .block_on(async { inner.list_batches(query_core).await })
4421
- .map_err(|e| {
4422
- magnus::Error::new(
4423
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4424
- e.to_string(),
4425
- )
4426
- })?;
4595
+ .map_err(alef_magnus_err)?;
4427
4596
  Ok(result.into())
4428
4597
  }
4429
4598
 
@@ -4438,20 +4607,10 @@ impl DefaultClient {
4438
4607
  .enable_all()
4439
4608
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4440
4609
  .build()
4441
- .map_err(|e| {
4442
- magnus::Error::new(
4443
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4444
- e.to_string(),
4445
- )
4446
- })?;
4610
+ .map_err(alef_magnus_err)?;
4447
4611
  let result = rt
4448
4612
  .block_on(async { inner.cancel_batch(&batch_id).await })
4449
- .map_err(|e| {
4450
- magnus::Error::new(
4451
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4452
- e.to_string(),
4453
- )
4454
- })?;
4613
+ .map_err(alef_magnus_err)?;
4455
4614
  Ok(result.into())
4456
4615
  }
4457
4616
 
@@ -4466,20 +4625,10 @@ impl DefaultClient {
4466
4625
  .enable_all()
4467
4626
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4468
4627
  .build()
4469
- .map_err(|e| {
4470
- magnus::Error::new(
4471
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4472
- e.to_string(),
4473
- )
4474
- })?;
4628
+ .map_err(alef_magnus_err)?;
4475
4629
  let result = rt
4476
4630
  .block_on(async { inner.fetch_batch_for_polling(&batch_id).await })
4477
- .map_err(|e| {
4478
- magnus::Error::new(
4479
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4480
- e.to_string(),
4481
- )
4482
- })?;
4631
+ .map_err(alef_magnus_err)?;
4483
4632
  Ok(result.into())
4484
4633
  }
4485
4634
 
@@ -4492,23 +4641,13 @@ impl DefaultClient {
4492
4641
  // stack overflow aborts the process with SIGBUS instead of raising a catchable panic.
4493
4642
  const ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES: usize = 16 * 1024 * 1024;
4494
4643
  let rt = tokio::runtime::Builder::new_multi_thread()
4495
- .enable_all()
4496
- .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4497
- .build()
4498
- .map_err(|e| {
4499
- magnus::Error::new(
4500
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4501
- e.to_string(),
4502
- )
4503
- })?;
4644
+ .enable_all()
4645
+ .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4646
+ .build()
4647
+ .map_err(alef_magnus_err)?;
4504
4648
  let result = rt
4505
4649
  .block_on(async { inner.wait_for_batch(&batch_id, config_core).await })
4506
- .map_err(|e| {
4507
- magnus::Error::new(
4508
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4509
- e.to_string(),
4510
- )
4511
- })?;
4650
+ .map_err(alef_magnus_err)?;
4512
4651
  Ok(result.into())
4513
4652
  }
4514
4653
 
@@ -4524,20 +4663,10 @@ impl DefaultClient {
4524
4663
  .enable_all()
4525
4664
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4526
4665
  .build()
4527
- .map_err(|e| {
4528
- magnus::Error::new(
4529
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4530
- e.to_string(),
4531
- )
4532
- })?;
4666
+ .map_err(alef_magnus_err)?;
4533
4667
  let result = rt
4534
4668
  .block_on(async { inner.create_response(req_core).await })
4535
- .map_err(|e| {
4536
- magnus::Error::new(
4537
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4538
- e.to_string(),
4539
- )
4540
- })?;
4669
+ .map_err(alef_magnus_err)?;
4541
4670
  Ok(result.into())
4542
4671
  }
4543
4672
 
@@ -4552,20 +4681,10 @@ impl DefaultClient {
4552
4681
  .enable_all()
4553
4682
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4554
4683
  .build()
4555
- .map_err(|e| {
4556
- magnus::Error::new(
4557
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4558
- e.to_string(),
4559
- )
4560
- })?;
4684
+ .map_err(alef_magnus_err)?;
4561
4685
  let result = rt
4562
4686
  .block_on(async { inner.retrieve_response(&response_id).await })
4563
- .map_err(|e| {
4564
- magnus::Error::new(
4565
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4566
- e.to_string(),
4567
- )
4568
- })?;
4687
+ .map_err(alef_magnus_err)?;
4569
4688
  Ok(result.into())
4570
4689
  }
4571
4690
 
@@ -4580,20 +4699,10 @@ impl DefaultClient {
4580
4699
  .enable_all()
4581
4700
  .thread_stack_size(ASYNC_METHOD_RUNTIME_STACK_SIZE_BYTES)
4582
4701
  .build()
4583
- .map_err(|e| {
4584
- magnus::Error::new(
4585
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4586
- e.to_string(),
4587
- )
4588
- })?;
4702
+ .map_err(alef_magnus_err)?;
4589
4703
  let result = rt
4590
4704
  .block_on(async { inner.cancel_response(&response_id).await })
4591
- .map_err(|e| {
4592
- magnus::Error::new(
4593
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4594
- e.to_string(),
4595
- )
4596
- })?;
4705
+ .map_err(alef_magnus_err)?;
4597
4706
  Ok(result.into())
4598
4707
  }
4599
4708
  }
@@ -4626,12 +4735,7 @@ impl DefaultClient {
4626
4735
  );
4627
4736
  let stream = runtime
4628
4737
  .block_on(async { inner.chat_stream(core_req).await })
4629
- .map_err(|e| {
4630
- magnus::Error::new(
4631
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
4632
- e.to_string(),
4633
- )
4634
- })?;
4738
+ .map_err(alef_magnus_err)?;
4635
4739
  let iterator = ChatStreamIterator {
4636
4740
  inner: Arc::new(tokio::sync::Mutex::new(Some(stream))),
4637
4741
  runtime,
@@ -5006,6 +5110,7 @@ pub struct EmbeddingRequest {
5006
5110
  encoding_format: Option<EmbeddingFormat>,
5007
5111
  dimensions: Option<u32>,
5008
5112
  user: Option<String>,
5113
+ extra_body: Option<String>,
5009
5114
  }
5010
5115
 
5011
5116
  unsafe impl IntoValueFromNative for EmbeddingRequest {}
@@ -5107,6 +5212,15 @@ impl EmbeddingRequest {
5107
5212
  })?),
5108
5213
  None => None,
5109
5214
  },
5215
+ extra_body: match kwargs.get(ruby.to_symbol("extra_body")).filter(|v| !v.is_nil()) {
5216
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
5217
+ magnus::Error::new(
5218
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
5219
+ format!("invalid value for `extra_body`: {}", e),
5220
+ )
5221
+ })?),
5222
+ None => None,
5223
+ },
5110
5224
  })
5111
5225
  }
5112
5226
 
@@ -5129,6 +5243,10 @@ impl EmbeddingRequest {
5129
5243
  fn user(&self) -> Option<String> {
5130
5244
  self.user.clone()
5131
5245
  }
5246
+
5247
+ fn extra_body(&self) -> Option<String> {
5248
+ self.extra_body.clone()
5249
+ }
5132
5250
  }
5133
5251
 
5134
5252
  #[derive(Clone, Debug, serde::Serialize)]
@@ -6652,6 +6770,7 @@ pub struct LlmConfig {
6652
6770
  api_key: Option<String>,
6653
6771
  base_url: Option<String>,
6654
6772
  timeout_secs: Option<u64>,
6773
+ connect_timeout_secs: Option<u64>,
6655
6774
  max_retries: Option<u32>,
6656
6775
  temperature: Option<f64>,
6657
6776
  max_tokens: Option<u64>,
@@ -6754,6 +6873,18 @@ impl LlmConfig {
6754
6873
  })?),
6755
6874
  None => None,
6756
6875
  },
6876
+ connect_timeout_secs: match kwargs
6877
+ .get(ruby.to_symbol("connect_timeout_secs"))
6878
+ .filter(|v| !v.is_nil())
6879
+ {
6880
+ Some(v) => Some(u64::try_convert(v).map_err(|e| {
6881
+ magnus::Error::new(
6882
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
6883
+ format!("invalid value for `connect_timeout_secs`: {}", e),
6884
+ )
6885
+ })?),
6886
+ None => None,
6887
+ },
6757
6888
  max_retries: match kwargs.get(ruby.to_symbol("max_retries")).filter(|v| !v.is_nil()) {
6758
6889
  Some(v) => Some(u32::try_convert(v).map_err(|e| {
6759
6890
  magnus::Error::new(
@@ -6908,6 +7039,10 @@ impl LlmConfig {
6908
7039
  self.timeout_secs
6909
7040
  }
6910
7041
 
7042
+ fn connect_timeout_secs(&self) -> Option<u64> {
7043
+ self.connect_timeout_secs
7044
+ }
7045
+
6911
7046
  fn max_retries(&self) -> Option<u32> {
6912
7047
  self.max_retries
6913
7048
  }
@@ -8473,6 +8608,7 @@ impl ModerationCategoryScores {
8473
8608
  pub struct ModerationRequest {
8474
8609
  input: ModerationInput,
8475
8610
  model: Option<String>,
8611
+ extra_body: Option<String>,
8476
8612
  }
8477
8613
 
8478
8614
  unsafe impl IntoValueFromNative for ModerationRequest {}
@@ -8547,6 +8683,15 @@ impl ModerationRequest {
8547
8683
  })?),
8548
8684
  None => None,
8549
8685
  },
8686
+ extra_body: match kwargs.get(ruby.to_symbol("extra_body")).filter(|v| !v.is_nil()) {
8687
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
8688
+ magnus::Error::new(
8689
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
8690
+ format!("invalid value for `extra_body`: {}", e),
8691
+ )
8692
+ })?),
8693
+ None => None,
8694
+ },
8550
8695
  })
8551
8696
  }
8552
8697
 
@@ -8557,6 +8702,10 @@ impl ModerationRequest {
8557
8702
  fn model(&self) -> Option<String> {
8558
8703
  self.model.clone()
8559
8704
  }
8705
+
8706
+ fn extra_body(&self) -> Option<String> {
8707
+ self.extra_body.clone()
8708
+ }
8560
8709
  }
8561
8710
 
8562
8711
  #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
@@ -8957,6 +9106,7 @@ pub struct OcrRequest {
8957
9106
  document: OcrDocument,
8958
9107
  pages: Option<Vec<u32>>,
8959
9108
  include_image_base64: Option<bool>,
9109
+ extra_body: Option<String>,
8960
9110
  }
8961
9111
 
8962
9112
  unsafe impl IntoValueFromNative for OcrRequest {}
@@ -9052,6 +9202,15 @@ impl OcrRequest {
9052
9202
  })?),
9053
9203
  None => None,
9054
9204
  },
9205
+ extra_body: match kwargs.get(ruby.to_symbol("extra_body")).filter(|v| !v.is_nil()) {
9206
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
9207
+ magnus::Error::new(
9208
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
9209
+ format!("invalid value for `extra_body`: {}", e),
9210
+ )
9211
+ })?),
9212
+ None => None,
9213
+ },
9055
9214
  })
9056
9215
  }
9057
9216
 
@@ -9070,6 +9229,10 @@ impl OcrRequest {
9070
9229
  fn include_image_base64(&self) -> Option<bool> {
9071
9230
  self.include_image_base64
9072
9231
  }
9232
+
9233
+ fn extra_body(&self) -> Option<String> {
9234
+ self.extra_body.clone()
9235
+ }
9073
9236
  }
9074
9237
 
9075
9238
  #[derive(Clone, Debug, serde::Serialize)]
@@ -9748,6 +9911,7 @@ pub struct RerankRequest {
9748
9911
  documents: Vec<RerankDocument>,
9749
9912
  top_n: Option<u32>,
9750
9913
  return_documents: Option<bool>,
9914
+ extra_body: Option<String>,
9751
9915
  }
9752
9916
 
9753
9917
  unsafe impl IntoValueFromNative for RerankRequest {}
@@ -9844,6 +10008,15 @@ impl RerankRequest {
9844
10008
  })?),
9845
10009
  None => None,
9846
10010
  },
10011
+ extra_body: match kwargs.get(ruby.to_symbol("extra_body")).filter(|v| !v.is_nil()) {
10012
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
10013
+ magnus::Error::new(
10014
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
10015
+ format!("invalid value for `extra_body`: {}", e),
10016
+ )
10017
+ })?),
10018
+ None => None,
10019
+ },
9847
10020
  })
9848
10021
  }
9849
10022
 
@@ -9866,6 +10039,10 @@ impl RerankRequest {
9866
10039
  fn return_documents(&self) -> Option<bool> {
9867
10040
  self.return_documents
9868
10041
  }
10042
+
10043
+ fn extra_body(&self) -> Option<String> {
10044
+ self.extra_body.clone()
10045
+ }
9869
10046
  }
9870
10047
 
9871
10048
  #[derive(Clone, Debug, serde::Serialize)]
@@ -10583,6 +10760,7 @@ pub struct SearchRequest {
10583
10760
  max_results: Option<u32>,
10584
10761
  search_domain_filter: Option<Vec<String>>,
10585
10762
  country: Option<String>,
10763
+ extra_body: Option<String>,
10586
10764
  }
10587
10765
 
10588
10766
  unsafe impl IntoValueFromNative for SearchRequest {}
@@ -10682,6 +10860,15 @@ impl SearchRequest {
10682
10860
  })?),
10683
10861
  None => None,
10684
10862
  },
10863
+ extra_body: match kwargs.get(ruby.to_symbol("extra_body")).filter(|v| !v.is_nil()) {
10864
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
10865
+ magnus::Error::new(
10866
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
10867
+ format!("invalid value for `extra_body`: {}", e),
10868
+ )
10869
+ })?),
10870
+ None => None,
10871
+ },
10685
10872
  })
10686
10873
  }
10687
10874
 
@@ -10704,6 +10891,10 @@ impl SearchRequest {
10704
10891
  fn country(&self) -> Option<String> {
10705
10892
  self.country.clone()
10706
10893
  }
10894
+
10895
+ fn extra_body(&self) -> Option<String> {
10896
+ self.extra_body.clone()
10897
+ }
10707
10898
  }
10708
10899
 
10709
10900
  #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
@@ -13639,6 +13830,7 @@ pub enum ReasoningEffort {
13639
13830
  High,
13640
13831
  Minimal,
13641
13832
  Max,
13833
+ None,
13642
13834
  }
13643
13835
 
13644
13836
  impl Default for ReasoningEffort {
@@ -13655,6 +13847,7 @@ impl magnus::IntoValue for ReasoningEffort {
13655
13847
  ReasoningEffort::High => "high",
13656
13848
  ReasoningEffort::Minimal => "minimal",
13657
13849
  ReasoningEffort::Max => "max",
13850
+ ReasoningEffort::None => "none",
13658
13851
  };
13659
13852
  handle.to_symbol(sym).into_value_with(handle)
13660
13853
  }
@@ -13679,6 +13872,7 @@ impl magnus::TryConvert for ReasoningEffort {
13679
13872
  "high" | "High" => Ok(ReasoningEffort::High),
13680
13873
  "minimal" | "Minimal" => Ok(ReasoningEffort::Minimal),
13681
13874
  "max" | "Max" => Ok(ReasoningEffort::Max),
13875
+ "none" | "None" => Ok(ReasoningEffort::None),
13682
13876
  other => Err(magnus::Error::new(
13683
13877
  unsafe { Ruby::get_unchecked() }.exception_arg_error(),
13684
13878
  format!("invalid ReasoningEffort value: {other}"),
@@ -13917,6 +14111,7 @@ unsafe impl TryConvertOwned for StopSequence {}
13917
14111
  pub enum StreamFormat {
13918
14112
  Sse,
13919
14113
  AwsEventStream,
14114
+ Ndjson,
13920
14115
  }
13921
14116
 
13922
14117
  impl Default for StreamFormat {
@@ -13930,6 +14125,7 @@ impl magnus::IntoValue for StreamFormat {
13930
14125
  let sym = match self {
13931
14126
  StreamFormat::Sse => "sse",
13932
14127
  StreamFormat::AwsEventStream => "aws_event_stream",
14128
+ StreamFormat::Ndjson => "ndjson",
13933
14129
  };
13934
14130
  handle.to_symbol(sym).into_value_with(handle)
13935
14131
  }
@@ -13951,6 +14147,7 @@ impl magnus::TryConvert for StreamFormat {
13951
14147
  match s.as_str() {
13952
14148
  "sse" | "Sse" => Ok(StreamFormat::Sse),
13953
14149
  "aws_event_stream" | "AwsEventStream" => Ok(StreamFormat::AwsEventStream),
14150
+ "ndjson" | "Ndjson" => Ok(StreamFormat::Ndjson),
13954
14151
  other => Err(magnus::Error::new(
13955
14152
  unsafe { Ruby::get_unchecked() }.exception_arg_error(),
13956
14153
  format!("invalid StreamFormat value: {other}"),
@@ -14182,12 +14379,7 @@ unsafe impl IntoValueFromNative for UserContent {}
14182
14379
  unsafe impl TryConvertOwned for UserContent {}
14183
14380
 
14184
14381
  fn all_providers() -> Result<Vec<ProviderConfig>, Error> {
14185
- let result = liter_llm::provider::all_providers().map_err(|e| {
14186
- magnus::Error::new(
14187
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
14188
- e.to_string(),
14189
- )
14190
- })?;
14382
+ let result = liter_llm::provider::all_providers().map_err(alef_magnus_err)?;
14191
14383
  Ok(result.iter().map(|v| v.clone().into()).collect())
14192
14384
  }
14193
14385
 
@@ -14200,12 +14392,8 @@ fn catalog_info() -> Option<CatalogInfo> {
14200
14392
  }
14201
14393
 
14202
14394
  fn check_bound(context: String, current_len: usize, incoming: usize, limit: usize) -> Result<(), Error> {
14203
- let result = liter_llm::util::bounds::check_bound(&context, current_len, incoming, limit).map_err(|e| {
14204
- magnus::Error::new(
14205
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
14206
- e.to_string(),
14207
- )
14208
- })?;
14395
+ let result =
14396
+ liter_llm::util::bounds::check_bound(&context, current_len, incoming, limit).map_err(alef_magnus_err)?;
14209
14397
  Ok(result)
14210
14398
  }
14211
14399
 
@@ -14247,12 +14435,7 @@ fn completion_cost_with_cache_details(
14247
14435
  }
14248
14436
 
14249
14437
  fn complex_provider_names() -> Result<Vec<String>, Error> {
14250
- let result = liter_llm::provider::complex_provider_names().map_err(|e| {
14251
- magnus::Error::new(
14252
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
14253
- e.to_string(),
14254
- )
14255
- })?;
14438
+ let result = liter_llm::provider::complex_provider_names().map_err(alef_magnus_err)?;
14256
14439
  Ok(result.iter().map(|s| s.to_string()).collect())
14257
14440
  }
14258
14441
 
@@ -14275,23 +14458,13 @@ fn count_request_tokens(args: &[magnus::Value]) -> Result<usize, Error> {
14275
14458
  }
14276
14459
  _ => Default::default(),
14277
14460
  };
14278
- let result = liter_llm::count_request_tokens(&model, &req_core).map_err(|e| {
14279
- magnus::Error::new(
14280
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
14281
- e.to_string(),
14282
- )
14283
- })?;
14461
+ let result = liter_llm::count_request_tokens(&model, &req_core).map_err(alef_magnus_err)?;
14284
14462
  Ok(result)
14285
14463
  }
14286
14464
 
14287
14465
  #[cfg(feature = "tokenizer")]
14288
14466
  fn count_tokens(model: String, text: String) -> Result<usize, Error> {
14289
- let result = liter_llm::count_tokens(&model, &text).map_err(|e| {
14290
- magnus::Error::new(
14291
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
14292
- e.to_string(),
14293
- )
14294
- })?;
14467
+ let result = liter_llm::count_tokens(&model, &text).map_err(alef_magnus_err)?;
14295
14468
  Ok(result)
14296
14469
  }
14297
14470
 
@@ -14299,7 +14472,12 @@ fn count_tokens(model: String, text: String) -> Result<usize, Error> {
14299
14472
  fn create_client(args: &[magnus::Value]) -> Result<DefaultClient, Error> {
14300
14473
  let args = magnus::scan_args::scan_args::<
14301
14474
  (String,),
14302
- (Option<magnus::Value>, Option<u64>, Option<u32>, Option<magnus::Value>),
14475
+ (
14476
+ Option<magnus::Value>,
14477
+ Option<magnus::Value>,
14478
+ Option<magnus::Value>,
14479
+ Option<magnus::Value>,
14480
+ ),
14303
14481
  (),
14304
14482
  (),
14305
14483
  (),
@@ -14309,28 +14487,28 @@ fn create_client(args: &[magnus::Value]) -> Result<DefaultClient, Error> {
14309
14487
 
14310
14488
  let (base_url, timeout_secs, max_retries, model_hint) = args.optional;
14311
14489
 
14312
- let base_url: Option<String> = base_url.and_then(|v| {
14313
- if v.is_nil() {
14314
- None
14315
- } else {
14316
- Some(String::try_convert(v).unwrap_or_default())
14317
- }
14318
- });
14490
+ let base_url: Option<String> = match base_url {
14491
+ Some(v) if !v.is_nil() => Some(String::try_convert(v)?),
14492
+ _ => None,
14493
+ };
14319
14494
 
14320
- let model_hint: Option<String> = model_hint.and_then(|v| {
14321
- if v.is_nil() {
14322
- None
14323
- } else {
14324
- Some(String::try_convert(v).unwrap_or_default())
14325
- }
14326
- });
14495
+ let timeout_secs: Option<u64> = match timeout_secs {
14496
+ Some(v) if !v.is_nil() => Some(u64::try_convert(v)?),
14497
+ _ => None,
14498
+ };
14499
+
14500
+ let max_retries: Option<u32> = match max_retries {
14501
+ Some(v) if !v.is_nil() => Some(u32::try_convert(v)?),
14502
+ _ => None,
14503
+ };
14504
+
14505
+ let model_hint: Option<String> = match model_hint {
14506
+ Some(v) if !v.is_nil() => Some(String::try_convert(v)?),
14507
+ _ => None,
14508
+ };
14327
14509
 
14328
- let result = liter_llm::create_client(api_key, base_url, timeout_secs, max_retries, model_hint).map_err(|e| {
14329
- magnus::Error::new(
14330
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
14331
- e.to_string(),
14332
- )
14333
- })?;
14510
+ let result =
14511
+ liter_llm::create_client(api_key, base_url, timeout_secs, max_retries, model_hint).map_err(alef_magnus_err)?;
14334
14512
  Ok(DefaultClient {
14335
14513
  inner: Arc::new(result),
14336
14514
  })
@@ -14338,12 +14516,7 @@ fn create_client(args: &[magnus::Value]) -> Result<DefaultClient, Error> {
14338
14516
 
14339
14517
  #[cfg(any(feature = "native-http", feature = "wasm-http"))]
14340
14518
  fn create_client_from_json(json: String) -> Result<DefaultClient, Error> {
14341
- let result = liter_llm::create_client_from_json(&json).map_err(|e| {
14342
- magnus::Error::new(
14343
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
14344
- e.to_string(),
14345
- )
14346
- })?;
14519
+ let result = liter_llm::create_client_from_json(&json).map_err(alef_magnus_err)?;
14347
14520
  Ok(DefaultClient {
14348
14521
  inner: Arc::new(result),
14349
14522
  })
@@ -14363,12 +14536,7 @@ fn create_client_with_options(args: &[magnus::Value]) -> Result<DefaultClient, E
14363
14536
  }
14364
14537
  _ => Default::default(),
14365
14538
  };
14366
- let result = liter_llm::create_client_with_options(options.into()).map_err(|e| {
14367
- magnus::Error::new(
14368
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
14369
- e.to_string(),
14370
- )
14371
- })?;
14539
+ let result = liter_llm::create_client_with_options(options.into()).map_err(alef_magnus_err)?;
14372
14540
  Ok(DefaultClient {
14373
14541
  inner: Arc::new(result),
14374
14542
  })
@@ -14384,13 +14552,10 @@ fn encode_data_url(args: &[magnus::Value]) -> Result<String, Error> {
14384
14552
 
14385
14553
  let (mime,) = args.optional;
14386
14554
 
14387
- let mime: Option<String> = mime.and_then(|v| {
14388
- if v.is_nil() {
14389
- None
14390
- } else {
14391
- Some(String::try_convert(v).unwrap_or_default())
14392
- }
14393
- });
14555
+ let mime: Option<String> = match mime {
14556
+ Some(v) if !v.is_nil() => Some(String::try_convert(v)?),
14557
+ _ => None,
14558
+ };
14394
14559
 
14395
14560
  Ok(liter_llm::image::encode_data_url(&bytes, mime.as_deref()))
14396
14561
  }
@@ -14408,15 +14573,25 @@ fn exact_model_info(model: String) -> Option<ModelInfo> {
14408
14573
  }
14409
14574
 
14410
14575
  fn install_catalog_overlay_from_str(catalog_json: String) -> Result<(), Error> {
14411
- let result = liter_llm::install_catalog_overlay_from_str(&catalog_json).map_err(|e| {
14412
- magnus::Error::new(
14413
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
14414
- e.to_string(),
14415
- )
14416
- })?;
14576
+ let result = liter_llm::install_catalog_overlay_from_str(&catalog_json).map_err(alef_magnus_err)?;
14417
14577
  Ok(result)
14418
14578
  }
14419
14579
 
14580
+ fn list_catalog_models(args: &[magnus::Value]) -> Result<Vec<CatalogModel>, Error> {
14581
+ let args = magnus::scan_args::scan_args::<(), (Option<magnus::Value>,), (), (), (), ()>(args)?;
14582
+ let (provider,) = args.optional;
14583
+
14584
+ let provider: Option<String> = match provider {
14585
+ Some(v) if !v.is_nil() => Some(String::try_convert(v)?),
14586
+ _ => None,
14587
+ };
14588
+
14589
+ Ok(liter_llm::list_catalog_models(provider.as_deref())
14590
+ .into_iter()
14591
+ .map(Into::into)
14592
+ .collect())
14593
+ }
14594
+
14420
14595
  fn model_info(model: String) -> Option<ModelInfo> {
14421
14596
  liter_llm::model_info(&model).map(Into::into)
14422
14597
  }
@@ -14447,11 +14622,11 @@ fn refresh_catalog(args: &[magnus::Value]) -> Result<RefreshOutcome, Error> {
14447
14622
  .enable_all()
14448
14623
  .build()
14449
14624
  .map_err(|e| e.to_string())?;
14450
- rt.block_on(async { liter_llm::refresh_catalog(&config_core).await })
14451
- .map_err(|e| e.to_string())
14625
+ Ok(rt.block_on(async { liter_llm::refresh_catalog(&config_core).await }))
14452
14626
  });
14453
14627
  let result = async_result
14454
14628
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
14629
+ let result = result.map_err(alef_magnus_err)?;
14455
14630
  Ok(result.into())
14456
14631
  }
14457
14632
 
@@ -14476,11 +14651,11 @@ fn refresh_catalog_async(args: &[magnus::Value]) -> Result<RefreshOutcome, Error
14476
14651
  .enable_all()
14477
14652
  .build()
14478
14653
  .map_err(|e| e.to_string())?;
14479
- rt.block_on(async { liter_llm::refresh_catalog(&config_core).await })
14480
- .map_err(|e| e.to_string())
14654
+ Ok(rt.block_on(async { liter_llm::refresh_catalog(&config_core).await }))
14481
14655
  });
14482
14656
  let result = async_result
14483
14657
  .map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
14658
+ let result = result.map_err(alef_magnus_err)?;
14484
14659
  Ok(result.into())
14485
14660
  }
14486
14661
 
@@ -14490,22 +14665,12 @@ fn register_custom_provider(config: magnus::Value) -> Result<(), Error> {
14490
14665
  .map_err(|e| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_type_error(), e.to_string()))?;
14491
14666
  binding_val.into()
14492
14667
  };
14493
- let result = liter_llm::provider::custom::register_custom_provider(config.into()).map_err(|e| {
14494
- magnus::Error::new(
14495
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
14496
- e.to_string(),
14497
- )
14498
- })?;
14668
+ let result = liter_llm::provider::custom::register_custom_provider(config.into()).map_err(alef_magnus_err)?;
14499
14669
  Ok(result)
14500
14670
  }
14501
14671
 
14502
14672
  fn unregister_custom_provider(name: String) -> Result<bool, Error> {
14503
- let result = liter_llm::provider::custom::unregister_custom_provider(&name).map_err(|e| {
14504
- magnus::Error::new(
14505
- unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
14506
- e.to_string(),
14507
- )
14508
- })?;
14673
+ let result = liter_llm::provider::custom::unregister_custom_provider(&name).map_err(alef_magnus_err)?;
14509
14674
  Ok(result)
14510
14675
  }
14511
14676
 
@@ -14807,6 +14972,51 @@ impl From<liter_llm::CatalogInfo> for CatalogInfo {
14807
14972
  }
14808
14973
  }
14809
14974
 
14975
+ #[allow(clippy::needless_update)]
14976
+ impl From<CatalogModel> for liter_llm::CatalogModel {
14977
+ fn from(val: CatalogModel) -> Self {
14978
+ Self {
14979
+ key: val.key,
14980
+ provider: val.provider,
14981
+ model: val.model,
14982
+ mode: val.mode,
14983
+ max_tokens: val.max_tokens,
14984
+ max_input_tokens: val.max_input_tokens,
14985
+ max_output_tokens: val.max_output_tokens,
14986
+ supports_vision: val.supports_vision,
14987
+ supports_function_calling: val.supports_function_calling,
14988
+ supports_reasoning: val.supports_reasoning,
14989
+ supports_structured_output: val.supports_structured_output,
14990
+ supports_audio_input: val.supports_audio_input,
14991
+ supports_audio_output: val.supports_audio_output,
14992
+ supports_prompt_caching: val.supports_prompt_caching,
14993
+ ..Default::default()
14994
+ }
14995
+ }
14996
+ }
14997
+
14998
+ #[allow(clippy::redundant_closure)]
14999
+ impl From<liter_llm::CatalogModel> for CatalogModel {
15000
+ fn from(val: liter_llm::CatalogModel) -> Self {
15001
+ Self {
15002
+ key: val.key.to_string(),
15003
+ provider: val.provider.to_string(),
15004
+ model: val.model.to_string(),
15005
+ mode: val.mode.map(|v| v.to_string()),
15006
+ max_tokens: val.max_tokens,
15007
+ max_input_tokens: val.max_input_tokens,
15008
+ max_output_tokens: val.max_output_tokens,
15009
+ supports_vision: val.supports_vision,
15010
+ supports_function_calling: val.supports_function_calling,
15011
+ supports_reasoning: val.supports_reasoning,
15012
+ supports_structured_output: val.supports_structured_output,
15013
+ supports_audio_input: val.supports_audio_input,
15014
+ supports_audio_output: val.supports_audio_output,
15015
+ supports_prompt_caching: val.supports_prompt_caching,
15016
+ }
15017
+ }
15018
+ }
15019
+
14810
15020
  #[allow(clippy::needless_update)]
14811
15021
  impl From<CatalogRefreshConfig> for liter_llm::CatalogRefreshConfig {
14812
15022
  fn from(val: CatalogRefreshConfig) -> Self {
@@ -15039,6 +15249,7 @@ impl From<ClientOptions> for liter_llm::ClientOptions {
15039
15249
  api_key: val.api_key,
15040
15250
  base_url: val.base_url,
15041
15251
  timeout_secs: val.timeout_secs,
15252
+ connect_timeout_secs: val.connect_timeout_secs,
15042
15253
  max_retries: val.max_retries,
15043
15254
  max_response_bytes: val.max_response_bytes,
15044
15255
  model_hint: val.model_hint,
@@ -15055,6 +15266,7 @@ impl From<liter_llm::ClientOptions> for ClientOptions {
15055
15266
  api_key: val.api_key.to_string(),
15056
15267
  base_url: val.base_url.map(|v| v.to_string()),
15057
15268
  timeout_secs: val.timeout_secs,
15269
+ connect_timeout_secs: val.connect_timeout_secs,
15058
15270
  max_retries: val.max_retries,
15059
15271
  max_response_bytes: val.max_response_bytes,
15060
15272
  model_hint: val.model_hint.map(|v| v.to_string()),
@@ -15130,6 +15342,7 @@ impl From<liter_llm::types::CreateFileRequest> for CreateFileRequest {
15130
15342
  }
15131
15343
 
15132
15344
  #[allow(clippy::needless_update)]
15345
+ #[allow(clippy::redundant_closure)]
15133
15346
  impl From<CreateImageRequest> for liter_llm::types::CreateImageRequest {
15134
15347
  fn from(val: CreateImageRequest) -> Self {
15135
15348
  Self {
@@ -15141,6 +15354,7 @@ impl From<CreateImageRequest> for liter_llm::types::CreateImageRequest {
15141
15354
  style: val.style,
15142
15355
  response_format: val.response_format,
15143
15356
  user: val.user,
15357
+ extra_body: val.extra_body.as_ref().and_then(|s| serde_json::from_str(s).ok()),
15144
15358
  ..Default::default()
15145
15359
  }
15146
15360
  }
@@ -15158,6 +15372,7 @@ impl From<liter_llm::types::CreateImageRequest> for CreateImageRequest {
15158
15372
  style: val.style.map(|v| v.to_string()),
15159
15373
  response_format: val.response_format.map(|v| v.to_string()),
15160
15374
  user: val.user.map(|v| v.to_string()),
15375
+ extra_body: val.extra_body.as_ref().map(ToString::to_string),
15161
15376
  }
15162
15377
  }
15163
15378
  }
@@ -15199,6 +15414,7 @@ impl From<liter_llm::types::CreateResponseRequest> for CreateResponseRequest {
15199
15414
  }
15200
15415
 
15201
15416
  #[allow(clippy::needless_update)]
15417
+ #[allow(clippy::redundant_closure)]
15202
15418
  impl From<CreateSpeechRequest> for liter_llm::types::CreateSpeechRequest {
15203
15419
  fn from(val: CreateSpeechRequest) -> Self {
15204
15420
  Self {
@@ -15207,6 +15423,7 @@ impl From<CreateSpeechRequest> for liter_llm::types::CreateSpeechRequest {
15207
15423
  voice: val.voice,
15208
15424
  response_format: val.response_format,
15209
15425
  speed: val.speed,
15426
+ extra_body: val.extra_body.as_ref().and_then(|s| serde_json::from_str(s).ok()),
15210
15427
  ..Default::default()
15211
15428
  }
15212
15429
  }
@@ -15221,11 +15438,13 @@ impl From<liter_llm::types::CreateSpeechRequest> for CreateSpeechRequest {
15221
15438
  voice: val.voice.to_string(),
15222
15439
  response_format: val.response_format.map(|v| v.to_string()),
15223
15440
  speed: val.speed,
15441
+ extra_body: val.extra_body.as_ref().map(ToString::to_string),
15224
15442
  }
15225
15443
  }
15226
15444
  }
15227
15445
 
15228
15446
  #[allow(clippy::needless_update)]
15447
+ #[allow(clippy::redundant_closure)]
15229
15448
  impl From<CreateTranscriptionRequest> for liter_llm::types::CreateTranscriptionRequest {
15230
15449
  fn from(val: CreateTranscriptionRequest) -> Self {
15231
15450
  Self {
@@ -15235,6 +15454,7 @@ impl From<CreateTranscriptionRequest> for liter_llm::types::CreateTranscriptionR
15235
15454
  prompt: val.prompt,
15236
15455
  response_format: val.response_format,
15237
15456
  temperature: val.temperature,
15457
+ extra_body: val.extra_body.as_ref().and_then(|s| serde_json::from_str(s).ok()),
15238
15458
  ..Default::default()
15239
15459
  }
15240
15460
  }
@@ -15250,6 +15470,7 @@ impl From<liter_llm::types::CreateTranscriptionRequest> for CreateTranscriptionR
15250
15470
  prompt: val.prompt.map(|v| v.to_string()),
15251
15471
  response_format: val.response_format.map(|v| v.to_string()),
15252
15472
  temperature: val.temperature,
15473
+ extra_body: val.extra_body.as_ref().map(ToString::to_string),
15253
15474
  }
15254
15475
  }
15255
15476
  }
@@ -15384,7 +15605,7 @@ impl From<liter_llm::types::EmbeddingObject> for EmbeddingObject {
15384
15605
  }
15385
15606
 
15386
15607
  #[allow(clippy::needless_update)]
15387
- #[allow(clippy::useless_conversion)]
15608
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
15388
15609
  impl From<EmbeddingRequest> for liter_llm::types::EmbeddingRequest {
15389
15610
  fn from(val: EmbeddingRequest) -> Self {
15390
15611
  Self {
@@ -15393,6 +15614,7 @@ impl From<EmbeddingRequest> for liter_llm::types::EmbeddingRequest {
15393
15614
  encoding_format: val.encoding_format.map(Into::into),
15394
15615
  dimensions: val.dimensions,
15395
15616
  user: val.user,
15617
+ extra_body: val.extra_body.as_ref().and_then(|s| serde_json::from_str(s).ok()),
15396
15618
  ..Default::default()
15397
15619
  }
15398
15620
  }
@@ -15407,6 +15629,7 @@ impl From<liter_llm::types::EmbeddingRequest> for EmbeddingRequest {
15407
15629
  encoding_format: val.encoding_format.map(Into::into),
15408
15630
  dimensions: val.dimensions,
15409
15631
  user: val.user.map(|v| v.to_string()),
15632
+ extra_body: val.extra_body.as_ref().map(ToString::to_string),
15410
15633
  }
15411
15634
  }
15412
15635
  }
@@ -15749,6 +15972,7 @@ impl From<liter_llm::client::LlmConfig> for LlmConfig {
15749
15972
  api_key: val.api_key.map(|v| v.to_string()),
15750
15973
  base_url: val.base_url.map(|v| v.to_string()),
15751
15974
  timeout_secs: val.timeout_secs,
15975
+ connect_timeout_secs: val.connect_timeout_secs,
15752
15976
  max_retries: val.max_retries,
15753
15977
  temperature: val.temperature,
15754
15978
  max_tokens: val.max_tokens,
@@ -16052,12 +16276,13 @@ impl From<liter_llm::types::ModerationCategoryScores> for ModerationCategoryScor
16052
16276
  }
16053
16277
 
16054
16278
  #[allow(clippy::needless_update)]
16055
- #[allow(clippy::useless_conversion)]
16279
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
16056
16280
  impl From<ModerationRequest> for liter_llm::types::ModerationRequest {
16057
16281
  fn from(val: ModerationRequest) -> Self {
16058
16282
  Self {
16059
16283
  input: val.input.into(),
16060
16284
  model: val.model,
16285
+ extra_body: val.extra_body.as_ref().and_then(|s| serde_json::from_str(s).ok()),
16061
16286
  ..Default::default()
16062
16287
  }
16063
16288
  }
@@ -16069,6 +16294,7 @@ impl From<liter_llm::types::ModerationRequest> for ModerationRequest {
16069
16294
  Self {
16070
16295
  input: val.input.into(),
16071
16296
  model: val.model.map(|v| v.to_string()),
16297
+ extra_body: val.extra_body.as_ref().map(ToString::to_string),
16072
16298
  }
16073
16299
  }
16074
16300
  }
@@ -16169,6 +16395,7 @@ impl From<OcrRequest> for liter_llm::types::OcrRequest {
16169
16395
  document: val.document.into(),
16170
16396
  pages: val.pages.map(|v| v.into_iter().collect()),
16171
16397
  include_image_base64: val.include_image_base64,
16398
+ extra_body: val.extra_body.as_ref().and_then(|s| serde_json::from_str(s).ok()),
16172
16399
  ..Default::default()
16173
16400
  }
16174
16401
  }
@@ -16182,6 +16409,7 @@ impl From<liter_llm::types::OcrRequest> for OcrRequest {
16182
16409
  document: val.document.into(),
16183
16410
  pages: val.pages.map(|v| v.into_iter().collect()),
16184
16411
  include_image_base64: val.include_image_base64,
16412
+ extra_body: val.extra_body.as_ref().map(ToString::to_string),
16185
16413
  }
16186
16414
  }
16187
16415
  }
@@ -16337,7 +16565,7 @@ impl From<liter_llm::RateLimitConfig> for RateLimitConfig {
16337
16565
  }
16338
16566
 
16339
16567
  #[allow(clippy::needless_update)]
16340
- #[allow(clippy::useless_conversion)]
16568
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
16341
16569
  impl From<RerankRequest> for liter_llm::types::RerankRequest {
16342
16570
  fn from(val: RerankRequest) -> Self {
16343
16571
  Self {
@@ -16346,6 +16574,7 @@ impl From<RerankRequest> for liter_llm::types::RerankRequest {
16346
16574
  documents: val.documents.into_iter().map(Into::into).collect(),
16347
16575
  top_n: val.top_n,
16348
16576
  return_documents: val.return_documents,
16577
+ extra_body: val.extra_body.as_ref().and_then(|s| serde_json::from_str(s).ok()),
16349
16578
  ..Default::default()
16350
16579
  }
16351
16580
  }
@@ -16360,6 +16589,7 @@ impl From<liter_llm::types::RerankRequest> for RerankRequest {
16360
16589
  documents: val.documents.into_iter().map(Into::into).collect(),
16361
16590
  top_n: val.top_n,
16362
16591
  return_documents: val.return_documents,
16592
+ extra_body: val.extra_body.as_ref().map(ToString::to_string),
16363
16593
  }
16364
16594
  }
16365
16595
  }
@@ -16528,6 +16758,7 @@ impl From<SearchRequest> for liter_llm::types::SearchRequest {
16528
16758
  max_results: val.max_results,
16529
16759
  search_domain_filter: val.search_domain_filter.map(|v| v.into_iter().collect()),
16530
16760
  country: val.country,
16761
+ extra_body: val.extra_body.as_ref().and_then(|s| serde_json::from_str(s).ok()),
16531
16762
  ..Default::default()
16532
16763
  }
16533
16764
  }
@@ -16542,6 +16773,7 @@ impl From<liter_llm::types::SearchRequest> for SearchRequest {
16542
16773
  max_results: val.max_results,
16543
16774
  search_domain_filter: val.search_domain_filter.map(|v| v.into_iter().collect()),
16544
16775
  country: val.country.map(|v| v.to_string()),
16776
+ extra_body: val.extra_body.as_ref().map(ToString::to_string),
16545
16777
  }
16546
16778
  }
16547
16779
  }
@@ -17400,6 +17632,7 @@ impl From<ReasoningEffort> for liter_llm::types::ReasoningEffort {
17400
17632
  ReasoningEffort::High => Self::High,
17401
17633
  ReasoningEffort::Minimal => Self::Minimal,
17402
17634
  ReasoningEffort::Max => Self::Max,
17635
+ ReasoningEffort::None => Self::None,
17403
17636
  }
17404
17637
  }
17405
17638
  }
@@ -17412,6 +17645,7 @@ impl From<liter_llm::types::ReasoningEffort> for ReasoningEffort {
17412
17645
  liter_llm::types::ReasoningEffort::High => Self::High,
17413
17646
  liter_llm::types::ReasoningEffort::Minimal => Self::Minimal,
17414
17647
  liter_llm::types::ReasoningEffort::Max => Self::Max,
17648
+ liter_llm::types::ReasoningEffort::None => Self::None,
17415
17649
  }
17416
17650
  }
17417
17651
  }
@@ -17501,6 +17735,7 @@ impl From<liter_llm::provider::StreamFormat> for StreamFormat {
17501
17735
  match val {
17502
17736
  liter_llm::provider::StreamFormat::Sse => Self::Sse,
17503
17737
  liter_llm::provider::StreamFormat::AwsEventStream => Self::AwsEventStream,
17738
+ liter_llm::provider::StreamFormat::Ndjson => Self::Ndjson,
17504
17739
  }
17505
17740
  }
17506
17741
  }
@@ -17577,18 +17812,99 @@ impl From<liter_llm::types::UserContent> for UserContent {
17577
17812
  }
17578
17813
  }
17579
17814
 
17580
- /// Convert a `liter_llm::CatalogRefreshError` error to a Magnus runtime error.
17815
+ /// Convert the error a core call returned into the typed Ruby exception of its family. An error
17816
+ /// of a type with no converter becomes a `RuntimeError` with the message.
17817
+ #[allow(dead_code)]
17818
+ fn alef_magnus_err<E: std::fmt::Display + 'static>(e: E) -> magnus::Error {
17819
+ let message = e.to_string();
17820
+ #[allow(unused_variables)]
17821
+ let any: Box<dyn std::any::Any> = Box::new(e);
17822
+ let any = match any.downcast::<liter_llm::CatalogRefreshError>() {
17823
+ Ok(typed) => return catalog_refresh_error_to_magnus_err(*typed),
17824
+ Err(any) => any,
17825
+ };
17826
+ let any = match any.downcast::<liter_llm::LiterLlmError>() {
17827
+ Ok(typed) => return liter_llm_error_to_magnus_err(*typed),
17828
+ Err(any) => any,
17829
+ };
17830
+ let _ = any;
17831
+ magnus::Error::new(
17832
+ unsafe { magnus::Ruby::get_unchecked() }.exception_runtime_error(),
17833
+ message,
17834
+ )
17835
+ }
17836
+
17837
+ /// Convert a `liter_llm::CatalogRefreshError` error to a typed Ruby exception.
17581
17838
  #[allow(dead_code)]
17582
17839
  fn catalog_refresh_error_to_magnus_err(e: liter_llm::CatalogRefreshError) -> magnus::Error {
17583
- let msg = e.to_string();
17584
- magnus::Error::new(unsafe { magnus::Ruby::get_unchecked() }.exception_runtime_error(), msg)
17840
+ use magnus::prelude::*;
17841
+ let message = e.to_string();
17842
+ let ruby = unsafe { magnus::Ruby::get_unchecked() };
17843
+ #[allow(unreachable_patterns)]
17844
+ let class_name = match &e {
17845
+ liter_llm::CatalogRefreshError::Disabled => "DisabledError",
17846
+ liter_llm::CatalogRefreshError::InsecureUrl { .. } => "InsecureUrlError",
17847
+ liter_llm::CatalogRefreshError::Fetch { .. } => "FetchError",
17848
+ liter_llm::CatalogRefreshError::Parse { .. } => "ParseError",
17849
+ liter_llm::CatalogRefreshError::Cache { .. } => "CacheError",
17850
+ liter_llm::CatalogRefreshError::Integrity { .. } => "IntegrityError",
17851
+ _ => "CatalogRefreshError",
17852
+ };
17853
+ let build = || -> Result<magnus::Error, magnus::Error> {
17854
+ let module = ruby.define_module("LiterLlm")?;
17855
+ let class: magnus::ExceptionClass = module.const_get(class_name)?;
17856
+ let exception = class.new_instance((message.as_str(),))?;
17857
+ Ok(magnus::Error::from(exception))
17858
+ };
17859
+ build().unwrap_or_else(|_| magnus::Error::new(ruby.exception_runtime_error(), message))
17585
17860
  }
17586
17861
 
17587
- /// Convert a `liter_llm::LiterLlmError` error to a Magnus runtime error.
17862
+ /// Convert a `liter_llm::LiterLlmError` error to a typed Ruby exception.
17588
17863
  #[allow(dead_code)]
17589
17864
  fn liter_llm_error_to_magnus_err(e: liter_llm::LiterLlmError) -> magnus::Error {
17590
- let msg = e.to_string();
17591
- magnus::Error::new(unsafe { magnus::Ruby::get_unchecked() }.exception_runtime_error(), msg)
17865
+ use magnus::prelude::*;
17866
+ let message = e.to_string();
17867
+ let ruby = unsafe { magnus::Ruby::get_unchecked() };
17868
+ #[allow(unreachable_patterns)]
17869
+ let class_name = match &e {
17870
+ liter_llm::LiterLlmError::Authentication { .. } => "AuthenticationError",
17871
+ liter_llm::LiterLlmError::RateLimited { .. } => "RateLimitedError",
17872
+ liter_llm::LiterLlmError::BadRequest { .. } => "BadRequestError",
17873
+ liter_llm::LiterLlmError::ContextWindowExceeded { .. } => "ContextWindowExceededError",
17874
+ liter_llm::LiterLlmError::ContentPolicy { .. } => "ContentPolicyError",
17875
+ liter_llm::LiterLlmError::NotFound { .. } => "NotFoundError",
17876
+ liter_llm::LiterLlmError::ServerError { .. } => "ServerError",
17877
+ liter_llm::LiterLlmError::ServiceUnavailable { .. } => "ServiceUnavailableError",
17878
+ liter_llm::LiterLlmError::Timeout => "LiterLlmTimeoutError",
17879
+ liter_llm::LiterLlmError::Network { .. } => "NetworkError",
17880
+ liter_llm::LiterLlmError::Streaming { .. } => "StreamingError",
17881
+ liter_llm::LiterLlmError::EndpointNotSupported { .. } => "EndpointNotSupportedError",
17882
+ liter_llm::LiterLlmError::InvalidHeader { .. } => "InvalidHeaderError",
17883
+ liter_llm::LiterLlmError::Serialization(..) => "SerializationError",
17884
+ liter_llm::LiterLlmError::BudgetExceeded { .. } => "BudgetExceededError",
17885
+ liter_llm::LiterLlmError::HookRejected { .. } => "HookRejectedError",
17886
+ liter_llm::LiterLlmError::InternalError { .. } => "InternalError",
17887
+ liter_llm::LiterLlmError::OutboundForbidden { .. } => "OutboundForbiddenError",
17888
+ liter_llm::LiterLlmError::IdempotencyConflict { .. } => "IdempotencyConflictError",
17889
+ liter_llm::LiterLlmError::IdempotencyInFlight { .. } => "IdempotencyInFlightError",
17890
+ liter_llm::LiterLlmError::ProviderQuotaExceeded { .. } => "ProviderQuotaExceededError",
17891
+ _ => "LiterLlmError",
17892
+ };
17893
+ let build = || -> Result<magnus::Error, magnus::Error> {
17894
+ let module = ruby.define_module("LiterLlm")?;
17895
+ let class: magnus::ExceptionClass = module.const_get(class_name)?;
17896
+ let exception = class.new_instance((message.as_str(),))?;
17897
+ exception.funcall::<_, _, magnus::Value>("instance_variable_set", ("@status_code", e.status_code()))?;
17898
+ exception.funcall::<_, _, magnus::Value>(
17899
+ "instance_variable_set",
17900
+ ("@retry_after", e.retry_after().map(|d| d.as_millis() as i64)),
17901
+ )?;
17902
+ exception.funcall::<_, _, magnus::Value>("instance_variable_set", ("@is_transient", e.is_transient()))?;
17903
+ exception
17904
+ .funcall::<_, _, magnus::Value>("instance_variable_set", ("@error_type", e.error_type().to_string()))?;
17905
+ Ok(magnus::Error::from(exception))
17906
+ };
17907
+ build().unwrap_or_else(|_| magnus::Error::new(ruby.exception_runtime_error(), message))
17592
17908
  }
17593
17909
 
17594
17910
  #[magnus::wrap(class = "LiterLlmErrorInfo", free_immediately, size)]
@@ -17679,7 +17995,7 @@ impl ChatStreamIterator {
17679
17995
  let binding: ChatCompletionChunk = chunk.into();
17680
17996
  Ok(binding.into_value_with(&ruby))
17681
17997
  }
17682
- Some(Err(e)) => Err(Error::new(ruby.exception_runtime_error(), e.to_string())),
17998
+ Some(Err(e)) => Err(alef_magnus_err(e)),
17683
17999
  None => {
17684
18000
  // Drop the stream to release any resources.
17685
18001
  let inner = self.inner.clone();
@@ -17887,6 +18203,47 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
17887
18203
 
17888
18204
  class.define_method("origin", method!(CatalogInfo::origin, 0))?;
17889
18205
 
18206
+ let class = module.define_class("CatalogModel", ruby.class_object())?;
18207
+
18208
+ class.define_singleton_method("new", function!(CatalogModel::new, -1))?;
18209
+
18210
+ class.define_method("key", method!(CatalogModel::key, 0))?;
18211
+
18212
+ class.define_method("provider", method!(CatalogModel::provider, 0))?;
18213
+
18214
+ class.define_method("model", method!(CatalogModel::model, 0))?;
18215
+
18216
+ class.define_method("mode", method!(CatalogModel::mode, 0))?;
18217
+
18218
+ class.define_method("max_tokens", method!(CatalogModel::max_tokens, 0))?;
18219
+
18220
+ class.define_method("max_input_tokens", method!(CatalogModel::max_input_tokens, 0))?;
18221
+
18222
+ class.define_method("max_output_tokens", method!(CatalogModel::max_output_tokens, 0))?;
18223
+
18224
+ class.define_method("supports_vision", method!(CatalogModel::supports_vision, 0))?;
18225
+
18226
+ class.define_method(
18227
+ "supports_function_calling",
18228
+ method!(CatalogModel::supports_function_calling, 0),
18229
+ )?;
18230
+
18231
+ class.define_method("supports_reasoning", method!(CatalogModel::supports_reasoning, 0))?;
18232
+
18233
+ class.define_method(
18234
+ "supports_structured_output",
18235
+ method!(CatalogModel::supports_structured_output, 0),
18236
+ )?;
18237
+
18238
+ class.define_method("supports_audio_input", method!(CatalogModel::supports_audio_input, 0))?;
18239
+
18240
+ class.define_method("supports_audio_output", method!(CatalogModel::supports_audio_output, 0))?;
18241
+
18242
+ class.define_method(
18243
+ "supports_prompt_caching",
18244
+ method!(CatalogModel::supports_prompt_caching, 0),
18245
+ )?;
18246
+
17890
18247
  let class = module.define_class("CatalogRefreshConfig", ruby.class_object())?;
17891
18248
 
17892
18249
  class.define_singleton_method("new", function!(CatalogRefreshConfig::new, -1))?;
@@ -18055,6 +18412,9 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
18055
18412
  #[cfg(any(feature = "native-http", feature = "wasm-http"))]
18056
18413
  class.define_method("timeout_secs", method!(ClientOptions::timeout_secs, 0))?;
18057
18414
 
18415
+ #[cfg(any(feature = "native-http", feature = "wasm-http"))]
18416
+ class.define_method("connect_timeout_secs", method!(ClientOptions::connect_timeout_secs, 0))?;
18417
+
18058
18418
  #[cfg(any(feature = "native-http", feature = "wasm-http"))]
18059
18419
  class.define_method("max_retries", method!(ClientOptions::max_retries, 0))?;
18060
18420
 
@@ -18115,6 +18475,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
18115
18475
 
18116
18476
  class.define_method("user", method!(CreateImageRequest::user, 0))?;
18117
18477
 
18478
+ class.define_method("extra_body", method!(CreateImageRequest::extra_body, 0))?;
18479
+
18118
18480
  let class = module.define_class("CreateResponseRequest", ruby.class_object())?;
18119
18481
 
18120
18482
  class.define_singleton_method("new", function!(CreateResponseRequest::new, -1))?;
@@ -18154,6 +18516,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
18154
18516
 
18155
18517
  class.define_method("speed", method!(CreateSpeechRequest::speed, 0))?;
18156
18518
 
18519
+ class.define_method("extra_body", method!(CreateSpeechRequest::extra_body, 0))?;
18520
+
18157
18521
  let class = module.define_class("CreateTranscriptionRequest", ruby.class_object())?;
18158
18522
 
18159
18523
  class.define_singleton_method("new", function!(CreateTranscriptionRequest::new, -1))?;
@@ -18173,6 +18537,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
18173
18537
 
18174
18538
  class.define_method("temperature", method!(CreateTranscriptionRequest::temperature, 0))?;
18175
18539
 
18540
+ class.define_method("extra_body", method!(CreateTranscriptionRequest::extra_body, 0))?;
18541
+
18176
18542
  let class = module.define_class("CustomProviderConfig", ruby.class_object())?;
18177
18543
 
18178
18544
  class.define_singleton_method("new", function!(CustomProviderConfig::new, -1))?;
@@ -18333,6 +18699,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
18333
18699
 
18334
18700
  class.define_method("user", method!(EmbeddingRequest::user, 0))?;
18335
18701
 
18702
+ class.define_method("extra_body", method!(EmbeddingRequest::extra_body, 0))?;
18703
+
18336
18704
  let class = module.define_class("EmbeddingResponse", ruby.class_object())?;
18337
18705
 
18338
18706
  class.define_singleton_method("new", function!(EmbeddingResponse::new, -1))?;
@@ -18507,6 +18875,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
18507
18875
 
18508
18876
  class.define_method("timeout_secs", method!(LlmConfig::timeout_secs, 0))?;
18509
18877
 
18878
+ class.define_method("connect_timeout_secs", method!(LlmConfig::connect_timeout_secs, 0))?;
18879
+
18510
18880
  class.define_method("max_retries", method!(LlmConfig::max_retries, 0))?;
18511
18881
 
18512
18882
  class.define_method("temperature", method!(LlmConfig::temperature, 0))?;
@@ -18773,6 +19143,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
18773
19143
 
18774
19144
  class.define_method("model", method!(ModerationRequest::model, 0))?;
18775
19145
 
19146
+ class.define_method("extra_body", method!(ModerationRequest::extra_body, 0))?;
19147
+
18776
19148
  let class = module.define_class("ModerationResponse", ruby.class_object())?;
18777
19149
 
18778
19150
  class.define_singleton_method("new", function!(ModerationResponse::new, -1))?;
@@ -18825,6 +19197,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
18825
19197
 
18826
19198
  class.define_method("include_image_base64", method!(OcrRequest::include_image_base64, 0))?;
18827
19199
 
19200
+ class.define_method("extra_body", method!(OcrRequest::extra_body, 0))?;
19201
+
18828
19202
  let class = module.define_class("OcrResponse", ruby.class_object())?;
18829
19203
 
18830
19204
  class.define_singleton_method("new", function!(OcrResponse::new, -1))?;
@@ -18920,6 +19294,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
18920
19294
 
18921
19295
  class.define_method("return_documents", method!(RerankRequest::return_documents, 0))?;
18922
19296
 
19297
+ class.define_method("extra_body", method!(RerankRequest::extra_body, 0))?;
19298
+
18923
19299
  let class = module.define_class("RerankResponse", ruby.class_object())?;
18924
19300
 
18925
19301
  class.define_singleton_method("new", function!(RerankResponse::new, -1))?;
@@ -19006,6 +19382,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
19006
19382
 
19007
19383
  class.define_method("country", method!(SearchRequest::country, 0))?;
19008
19384
 
19385
+ class.define_method("extra_body", method!(SearchRequest::extra_body, 0))?;
19386
+
19009
19387
  let class = module.define_class("SearchResponse", ruby.class_object())?;
19010
19388
 
19011
19389
  class.define_singleton_method("new", function!(SearchResponse::new, -1))?;
@@ -19263,6 +19641,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
19263
19641
  function!(install_catalog_overlay_from_str, 1),
19264
19642
  )?;
19265
19643
 
19644
+ module.define_module_function("list_catalog_models", function!(list_catalog_models, -1))?;
19645
+
19266
19646
  module.define_module_function("model_info", function!(model_info, 1))?;
19267
19647
 
19268
19648
  #[cfg(feature = "tower")]
@@ -19276,6 +19656,147 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
19276
19656
 
19277
19657
  module.define_module_function("chat_stream", function!(chat_stream, 2))?;
19278
19658
 
19659
+ let catalog_refresh_error_class = module.define_error("CatalogRefreshError", ruby.exception_standard_error())?;
19660
+ let disabled_error_class = module.define_error("DisabledError", catalog_refresh_error_class)?;
19661
+ let insecure_url_error_class = module.define_error("InsecureUrlError", catalog_refresh_error_class)?;
19662
+ let fetch_error_class = module.define_error("FetchError", catalog_refresh_error_class)?;
19663
+ let parse_error_class = module.define_error("ParseError", catalog_refresh_error_class)?;
19664
+ let cache_error_class = module.define_error("CacheError", catalog_refresh_error_class)?;
19665
+ let integrity_error_class = module.define_error("IntegrityError", catalog_refresh_error_class)?;
19666
+ let liter_llm_error_class = module.define_error("LiterLlmError", ruby.exception_standard_error())?;
19667
+ liter_llm_error_class.define_attr("status_code", magnus::Attr::Read)?;
19668
+ liter_llm_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19669
+ liter_llm_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19670
+ liter_llm_error_class.define_alias("transient?", "is_transient")?;
19671
+ liter_llm_error_class.define_attr("error_type", magnus::Attr::Read)?;
19672
+ let authentication_error_class = module.define_error("AuthenticationError", liter_llm_error_class)?;
19673
+ authentication_error_class.define_attr("status_code", magnus::Attr::Read)?;
19674
+ authentication_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19675
+ authentication_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19676
+ authentication_error_class.define_alias("transient?", "is_transient")?;
19677
+ authentication_error_class.define_attr("error_type", magnus::Attr::Read)?;
19678
+ let rate_limited_error_class = module.define_error("RateLimitedError", liter_llm_error_class)?;
19679
+ rate_limited_error_class.define_attr("status_code", magnus::Attr::Read)?;
19680
+ rate_limited_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19681
+ rate_limited_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19682
+ rate_limited_error_class.define_alias("transient?", "is_transient")?;
19683
+ rate_limited_error_class.define_attr("error_type", magnus::Attr::Read)?;
19684
+ let bad_request_error_class = module.define_error("BadRequestError", liter_llm_error_class)?;
19685
+ bad_request_error_class.define_attr("status_code", magnus::Attr::Read)?;
19686
+ bad_request_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19687
+ bad_request_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19688
+ bad_request_error_class.define_alias("transient?", "is_transient")?;
19689
+ bad_request_error_class.define_attr("error_type", magnus::Attr::Read)?;
19690
+ let context_window_exceeded_error_class =
19691
+ module.define_error("ContextWindowExceededError", liter_llm_error_class)?;
19692
+ context_window_exceeded_error_class.define_attr("status_code", magnus::Attr::Read)?;
19693
+ context_window_exceeded_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19694
+ context_window_exceeded_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19695
+ context_window_exceeded_error_class.define_alias("transient?", "is_transient")?;
19696
+ context_window_exceeded_error_class.define_attr("error_type", magnus::Attr::Read)?;
19697
+ let content_policy_error_class = module.define_error("ContentPolicyError", liter_llm_error_class)?;
19698
+ content_policy_error_class.define_attr("status_code", magnus::Attr::Read)?;
19699
+ content_policy_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19700
+ content_policy_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19701
+ content_policy_error_class.define_alias("transient?", "is_transient")?;
19702
+ content_policy_error_class.define_attr("error_type", magnus::Attr::Read)?;
19703
+ let not_found_error_class = module.define_error("NotFoundError", liter_llm_error_class)?;
19704
+ not_found_error_class.define_attr("status_code", magnus::Attr::Read)?;
19705
+ not_found_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19706
+ not_found_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19707
+ not_found_error_class.define_alias("transient?", "is_transient")?;
19708
+ not_found_error_class.define_attr("error_type", magnus::Attr::Read)?;
19709
+ let server_error_class = module.define_error("ServerError", liter_llm_error_class)?;
19710
+ server_error_class.define_attr("status_code", magnus::Attr::Read)?;
19711
+ server_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19712
+ server_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19713
+ server_error_class.define_alias("transient?", "is_transient")?;
19714
+ server_error_class.define_attr("error_type", magnus::Attr::Read)?;
19715
+ let service_unavailable_error_class = module.define_error("ServiceUnavailableError", liter_llm_error_class)?;
19716
+ service_unavailable_error_class.define_attr("status_code", magnus::Attr::Read)?;
19717
+ service_unavailable_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19718
+ service_unavailable_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19719
+ service_unavailable_error_class.define_alias("transient?", "is_transient")?;
19720
+ service_unavailable_error_class.define_attr("error_type", magnus::Attr::Read)?;
19721
+ let liter_llm_timeout_error_class = module.define_error("LiterLlmTimeoutError", liter_llm_error_class)?;
19722
+ liter_llm_timeout_error_class.define_attr("status_code", magnus::Attr::Read)?;
19723
+ liter_llm_timeout_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19724
+ liter_llm_timeout_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19725
+ liter_llm_timeout_error_class.define_alias("transient?", "is_transient")?;
19726
+ liter_llm_timeout_error_class.define_attr("error_type", magnus::Attr::Read)?;
19727
+ let network_error_class = module.define_error("NetworkError", liter_llm_error_class)?;
19728
+ network_error_class.define_attr("status_code", magnus::Attr::Read)?;
19729
+ network_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19730
+ network_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19731
+ network_error_class.define_alias("transient?", "is_transient")?;
19732
+ network_error_class.define_attr("error_type", magnus::Attr::Read)?;
19733
+ let streaming_error_class = module.define_error("StreamingError", liter_llm_error_class)?;
19734
+ streaming_error_class.define_attr("status_code", magnus::Attr::Read)?;
19735
+ streaming_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19736
+ streaming_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19737
+ streaming_error_class.define_alias("transient?", "is_transient")?;
19738
+ streaming_error_class.define_attr("error_type", magnus::Attr::Read)?;
19739
+ let endpoint_not_supported_error_class = module.define_error("EndpointNotSupportedError", liter_llm_error_class)?;
19740
+ endpoint_not_supported_error_class.define_attr("status_code", magnus::Attr::Read)?;
19741
+ endpoint_not_supported_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19742
+ endpoint_not_supported_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19743
+ endpoint_not_supported_error_class.define_alias("transient?", "is_transient")?;
19744
+ endpoint_not_supported_error_class.define_attr("error_type", magnus::Attr::Read)?;
19745
+ let invalid_header_error_class = module.define_error("InvalidHeaderError", liter_llm_error_class)?;
19746
+ invalid_header_error_class.define_attr("status_code", magnus::Attr::Read)?;
19747
+ invalid_header_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19748
+ invalid_header_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19749
+ invalid_header_error_class.define_alias("transient?", "is_transient")?;
19750
+ invalid_header_error_class.define_attr("error_type", magnus::Attr::Read)?;
19751
+ let serialization_error_class = module.define_error("SerializationError", liter_llm_error_class)?;
19752
+ serialization_error_class.define_attr("status_code", magnus::Attr::Read)?;
19753
+ serialization_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19754
+ serialization_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19755
+ serialization_error_class.define_alias("transient?", "is_transient")?;
19756
+ serialization_error_class.define_attr("error_type", magnus::Attr::Read)?;
19757
+ let budget_exceeded_error_class = module.define_error("BudgetExceededError", liter_llm_error_class)?;
19758
+ budget_exceeded_error_class.define_attr("status_code", magnus::Attr::Read)?;
19759
+ budget_exceeded_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19760
+ budget_exceeded_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19761
+ budget_exceeded_error_class.define_alias("transient?", "is_transient")?;
19762
+ budget_exceeded_error_class.define_attr("error_type", magnus::Attr::Read)?;
19763
+ let hook_rejected_error_class = module.define_error("HookRejectedError", liter_llm_error_class)?;
19764
+ hook_rejected_error_class.define_attr("status_code", magnus::Attr::Read)?;
19765
+ hook_rejected_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19766
+ hook_rejected_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19767
+ hook_rejected_error_class.define_alias("transient?", "is_transient")?;
19768
+ hook_rejected_error_class.define_attr("error_type", magnus::Attr::Read)?;
19769
+ let internal_error_class = module.define_error("InternalError", liter_llm_error_class)?;
19770
+ internal_error_class.define_attr("status_code", magnus::Attr::Read)?;
19771
+ internal_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19772
+ internal_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19773
+ internal_error_class.define_alias("transient?", "is_transient")?;
19774
+ internal_error_class.define_attr("error_type", magnus::Attr::Read)?;
19775
+ let outbound_forbidden_error_class = module.define_error("OutboundForbiddenError", liter_llm_error_class)?;
19776
+ outbound_forbidden_error_class.define_attr("status_code", magnus::Attr::Read)?;
19777
+ outbound_forbidden_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19778
+ outbound_forbidden_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19779
+ outbound_forbidden_error_class.define_alias("transient?", "is_transient")?;
19780
+ outbound_forbidden_error_class.define_attr("error_type", magnus::Attr::Read)?;
19781
+ let idempotency_conflict_error_class = module.define_error("IdempotencyConflictError", liter_llm_error_class)?;
19782
+ idempotency_conflict_error_class.define_attr("status_code", magnus::Attr::Read)?;
19783
+ idempotency_conflict_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19784
+ idempotency_conflict_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19785
+ idempotency_conflict_error_class.define_alias("transient?", "is_transient")?;
19786
+ idempotency_conflict_error_class.define_attr("error_type", magnus::Attr::Read)?;
19787
+ let idempotency_in_flight_error_class = module.define_error("IdempotencyInFlightError", liter_llm_error_class)?;
19788
+ idempotency_in_flight_error_class.define_attr("status_code", magnus::Attr::Read)?;
19789
+ idempotency_in_flight_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19790
+ idempotency_in_flight_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19791
+ idempotency_in_flight_error_class.define_alias("transient?", "is_transient")?;
19792
+ idempotency_in_flight_error_class.define_attr("error_type", magnus::Attr::Read)?;
19793
+ let provider_quota_exceeded_error_class =
19794
+ module.define_error("ProviderQuotaExceededError", liter_llm_error_class)?;
19795
+ provider_quota_exceeded_error_class.define_attr("status_code", magnus::Attr::Read)?;
19796
+ provider_quota_exceeded_error_class.define_attr("retry_after", magnus::Attr::Read)?;
19797
+ provider_quota_exceeded_error_class.define_attr("is_transient", magnus::Attr::Read)?;
19798
+ provider_quota_exceeded_error_class.define_alias("transient?", "is_transient")?;
19799
+ provider_quota_exceeded_error_class.define_attr("error_type", magnus::Attr::Read)?;
19279
19800
  let liter_llm_error_info_class = module.define_class("LiterLlmErrorInfo", ruby.class_object())?;
19280
19801
  liter_llm_error_info_class.define_method("status_code", magnus::method!(LiterLlmErrorInfo::status_code, 0))?;
19281
19802
  liter_llm_error_info_class.define_method("retry_after", magnus::method!(LiterLlmErrorInfo::retry_after, 0))?;