liter_llm 1.9.3 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  // This file is auto-generated by alef. DO NOT EDIT.
2
- // alef:hash:b34f5dac0a6af082b71cab3b75e126050fd38402a73d6d3ff06130b6fe7d8875
2
+ // alef:hash:c7947a41084f71e69944233535fbeda5cd13b37144078f1895b6b57a7802d3fe
3
3
  // Re-generate with: alef generate
4
4
  #![allow(dead_code, unused_imports, unused_variables)]
5
5
  #![allow(
@@ -415,6 +415,7 @@ pub struct AssistantMessage {
415
415
  tool_calls: Option<Vec<ToolCall>>,
416
416
  refusal: Option<String>,
417
417
  function_call: Option<FunctionCall>,
418
+ reasoning_content: Option<String>,
418
419
  }
419
420
 
420
421
  unsafe impl IntoValueFromNative for AssistantMessage {}
@@ -473,6 +474,9 @@ impl AssistantMessage {
473
474
  function_call: kwargs
474
475
  .get(ruby.to_symbol("function_call"))
475
476
  .and_then(|v| FunctionCall::try_convert(v).ok()),
477
+ reasoning_content: kwargs
478
+ .get(ruby.to_symbol("reasoning_content"))
479
+ .and_then(|v| String::try_convert(v).ok()),
476
480
  })
477
481
  }
478
482
 
@@ -496,7 +500,12 @@ impl AssistantMessage {
496
500
  self.function_call.clone()
497
501
  }
498
502
 
503
+ fn reasoning_content(&self) -> Option<String> {
504
+ self.reasoning_content.clone()
505
+ }
506
+
499
507
  fn text(&self) -> Option<String> {
508
+ #[allow(clippy::needless_update)]
500
509
  let core_self = liter_llm::types::AssistantMessage {
501
510
  content: self.content.clone().map(Into::into),
502
511
 
@@ -507,11 +516,16 @@ impl AssistantMessage {
507
516
  refusal: self.refusal.clone(),
508
517
 
509
518
  function_call: self.function_call.clone().map(Into::into),
519
+
520
+ reasoning_content: self.reasoning_content.clone(),
521
+
522
+ ..Default::default()
510
523
  };
511
524
  core_self.text()
512
525
  }
513
526
 
514
527
  fn refusal_text(&self) -> Option<String> {
528
+ #[allow(clippy::needless_update)]
515
529
  let core_self = liter_llm::types::AssistantMessage {
516
530
  content: self.content.clone().map(Into::into),
517
531
 
@@ -522,11 +536,36 @@ impl AssistantMessage {
522
536
  refusal: self.refusal.clone(),
523
537
 
524
538
  function_call: self.function_call.clone().map(Into::into),
539
+
540
+ reasoning_content: self.reasoning_content.clone(),
541
+
542
+ ..Default::default()
525
543
  };
526
544
  core_self.refusal_text().map(|v| v.to_owned())
527
545
  }
528
546
 
547
+ fn reasoning_text(&self) -> Option<String> {
548
+ #[allow(clippy::needless_update)]
549
+ let core_self = liter_llm::types::AssistantMessage {
550
+ content: self.content.clone().map(Into::into),
551
+
552
+ name: self.name.clone(),
553
+
554
+ tool_calls: self.tool_calls.clone().map(|v| v.into_iter().map(Into::into).collect()),
555
+
556
+ refusal: self.refusal.clone(),
557
+
558
+ function_call: self.function_call.clone().map(Into::into),
559
+
560
+ reasoning_content: self.reasoning_content.clone(),
561
+
562
+ ..Default::default()
563
+ };
564
+ core_self.reasoning_text().map(|v| v.to_owned())
565
+ }
566
+
529
567
  fn output_images(&self) -> Vec<ImageUrl> {
568
+ #[allow(clippy::needless_update)]
530
569
  let core_self = liter_llm::types::AssistantMessage {
531
570
  content: self.content.clone().map(Into::into),
532
571
 
@@ -537,11 +576,16 @@ impl AssistantMessage {
537
576
  refusal: self.refusal.clone(),
538
577
 
539
578
  function_call: self.function_call.clone().map(Into::into),
579
+
580
+ reasoning_content: self.reasoning_content.clone(),
581
+
582
+ ..Default::default()
540
583
  };
541
584
  core_self.output_images().into_iter().map(Into::into).collect()
542
585
  }
543
586
 
544
587
  fn output_audio(&self) -> Vec<AudioContent> {
588
+ #[allow(clippy::needless_update)]
545
589
  let core_self = liter_llm::types::AssistantMessage {
546
590
  content: self.content.clone().map(Into::into),
547
591
 
@@ -552,6 +596,10 @@ impl AssistantMessage {
552
596
  refusal: self.refusal.clone(),
553
597
 
554
598
  function_call: self.function_call.clone().map(Into::into),
599
+
600
+ reasoning_content: self.reasoning_content.clone(),
601
+
602
+ ..Default::default()
555
603
  };
556
604
  core_self.output_audio().into_iter().map(Into::into).collect()
557
605
  }
@@ -2139,6 +2187,7 @@ pub struct StreamDelta {
2139
2187
  tool_calls: Option<Vec<StreamToolCall>>,
2140
2188
  function_call: Option<StreamFunctionCall>,
2141
2189
  refusal: Option<String>,
2190
+ reasoning_content: Option<String>,
2142
2191
  }
2143
2192
 
2144
2193
  unsafe impl IntoValueFromNative for StreamDelta {}
@@ -2197,6 +2246,9 @@ impl StreamDelta {
2197
2246
  refusal: kwargs
2198
2247
  .get(ruby.to_symbol("refusal"))
2199
2248
  .and_then(|v| String::try_convert(v).ok()),
2249
+ reasoning_content: kwargs
2250
+ .get(ruby.to_symbol("reasoning_content"))
2251
+ .and_then(|v| String::try_convert(v).ok()),
2200
2252
  })
2201
2253
  }
2202
2254
 
@@ -2220,6 +2272,10 @@ impl StreamDelta {
2220
2272
  self.refusal.clone()
2221
2273
  }
2222
2274
 
2275
+ fn reasoning_content(&self) -> Option<String> {
2276
+ self.reasoning_content.clone()
2277
+ }
2278
+
2223
2279
  #[allow(clippy::should_implement_trait)]
2224
2280
  fn to_s(&self) -> String {
2225
2281
  self.content.clone().unwrap_or_default()
@@ -2564,7 +2620,7 @@ impl EmbeddingResponse {
2564
2620
  #[magnus::wrap(class = "LiterLlm::EmbeddingObject")]
2565
2621
  pub struct EmbeddingObject {
2566
2622
  object: String,
2567
- embedding: Vec<f64>,
2623
+ embedding: Vec<f32>,
2568
2624
  index: u32,
2569
2625
  }
2570
2626
 
@@ -2609,7 +2665,7 @@ impl EmbeddingObject {
2609
2665
  .unwrap_or_default(),
2610
2666
  embedding: kwargs
2611
2667
  .get(ruby.to_symbol("embedding"))
2612
- .and_then(|v| <Vec<f64>>::try_convert(v).ok())
2668
+ .and_then(|v| <Vec<f32>>::try_convert(v).ok())
2613
2669
  .unwrap_or_default(),
2614
2670
  index: kwargs
2615
2671
  .get(ruby.to_symbol("index"))
@@ -2622,7 +2678,7 @@ impl EmbeddingObject {
2622
2678
  self.object.clone()
2623
2679
  }
2624
2680
 
2625
- fn embedding(&self) -> Vec<f64> {
2681
+ fn embedding(&self) -> Vec<f32> {
2626
2682
  self.embedding.clone()
2627
2683
  }
2628
2684
 
@@ -7249,6 +7305,330 @@ impl AuthConfig {
7249
7305
  }
7250
7306
  }
7251
7307
 
7308
+ #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
7309
+ #[serde(default)]
7310
+ #[magnus::wrap(class = "LiterLlm::ModelInfo")]
7311
+ pub struct ModelInfo {
7312
+ input_cost_per_token: f64,
7313
+ output_cost_per_token: f64,
7314
+ cache_read_input_token_cost: Option<f64>,
7315
+ cache_creation_input_token_cost: Option<f64>,
7316
+ input_cost_per_audio_token: Option<f64>,
7317
+ output_cost_per_audio_token: Option<f64>,
7318
+ output_cost_per_reasoning_token: Option<f64>,
7319
+ max_tokens: Option<u64>,
7320
+ max_input_tokens: Option<u64>,
7321
+ max_output_tokens: Option<u64>,
7322
+ mode: Option<String>,
7323
+ supports_vision: Option<bool>,
7324
+ supports_function_calling: Option<bool>,
7325
+ supports_reasoning: Option<bool>,
7326
+ supports_structured_output: Option<bool>,
7327
+ supports_audio_input: Option<bool>,
7328
+ supports_audio_output: Option<bool>,
7329
+ supports_prompt_caching: Option<bool>,
7330
+ tiers: Vec<ModelTier>,
7331
+ }
7332
+
7333
+ unsafe impl IntoValueFromNative for ModelInfo {}
7334
+
7335
+ impl magnus::TryConvert for ModelInfo {
7336
+ fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
7337
+ if let Ok(r) = <&ModelInfo as magnus::TryConvert>::try_convert(val) {
7338
+ return Ok(r.clone());
7339
+ }
7340
+ let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
7341
+ s
7342
+ } else {
7343
+ val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
7344
+ magnus::Error::new(
7345
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7346
+ format!("no implicit conversion into ModelInfo: {}", e),
7347
+ )
7348
+ })?
7349
+ };
7350
+ serde_json::from_str::<ModelInfo>(&json_str).map_err(|e| {
7351
+ magnus::Error::new(
7352
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7353
+ format!("failed to deserialize ModelInfo: {}", e),
7354
+ )
7355
+ })
7356
+ }
7357
+ }
7358
+
7359
+ unsafe impl TryConvertOwned for ModelInfo {}
7360
+
7361
+ impl Default for ModelInfo {
7362
+ fn default() -> Self {
7363
+ liter_llm::ModelInfo::default().into()
7364
+ }
7365
+ }
7366
+
7367
+ impl ModelInfo {
7368
+ fn new(args: &[magnus::Value]) -> Result<Self, magnus::Error> {
7369
+ let ruby = unsafe { magnus::Ruby::get_unchecked() };
7370
+ let args = magnus::scan_args::scan_args::<(), (Option<magnus::RHash>,), (), (), (), ()>(args)?;
7371
+ let (kwargs_opt,) = args.optional;
7372
+ let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
7373
+ Ok(Self {
7374
+ input_cost_per_token: kwargs
7375
+ .get(ruby.to_symbol("input_cost_per_token"))
7376
+ .and_then(|v| f64::try_convert(v).ok())
7377
+ .unwrap_or_default(),
7378
+ output_cost_per_token: kwargs
7379
+ .get(ruby.to_symbol("output_cost_per_token"))
7380
+ .and_then(|v| f64::try_convert(v).ok())
7381
+ .unwrap_or_default(),
7382
+ cache_read_input_token_cost: kwargs
7383
+ .get(ruby.to_symbol("cache_read_input_token_cost"))
7384
+ .and_then(|v| f64::try_convert(v).ok()),
7385
+ cache_creation_input_token_cost: kwargs
7386
+ .get(ruby.to_symbol("cache_creation_input_token_cost"))
7387
+ .and_then(|v| f64::try_convert(v).ok()),
7388
+ input_cost_per_audio_token: kwargs
7389
+ .get(ruby.to_symbol("input_cost_per_audio_token"))
7390
+ .and_then(|v| f64::try_convert(v).ok()),
7391
+ output_cost_per_audio_token: kwargs
7392
+ .get(ruby.to_symbol("output_cost_per_audio_token"))
7393
+ .and_then(|v| f64::try_convert(v).ok()),
7394
+ output_cost_per_reasoning_token: kwargs
7395
+ .get(ruby.to_symbol("output_cost_per_reasoning_token"))
7396
+ .and_then(|v| f64::try_convert(v).ok()),
7397
+ max_tokens: kwargs
7398
+ .get(ruby.to_symbol("max_tokens"))
7399
+ .and_then(|v| u64::try_convert(v).ok()),
7400
+ max_input_tokens: kwargs
7401
+ .get(ruby.to_symbol("max_input_tokens"))
7402
+ .and_then(|v| u64::try_convert(v).ok()),
7403
+ max_output_tokens: kwargs
7404
+ .get(ruby.to_symbol("max_output_tokens"))
7405
+ .and_then(|v| u64::try_convert(v).ok()),
7406
+ mode: kwargs
7407
+ .get(ruby.to_symbol("mode"))
7408
+ .and_then(|v| String::try_convert(v).ok()),
7409
+ supports_vision: kwargs
7410
+ .get(ruby.to_symbol("supports_vision"))
7411
+ .and_then(|v| bool::try_convert(v).ok()),
7412
+ supports_function_calling: kwargs
7413
+ .get(ruby.to_symbol("supports_function_calling"))
7414
+ .and_then(|v| bool::try_convert(v).ok()),
7415
+ supports_reasoning: kwargs
7416
+ .get(ruby.to_symbol("supports_reasoning"))
7417
+ .and_then(|v| bool::try_convert(v).ok()),
7418
+ supports_structured_output: kwargs
7419
+ .get(ruby.to_symbol("supports_structured_output"))
7420
+ .and_then(|v| bool::try_convert(v).ok()),
7421
+ supports_audio_input: kwargs
7422
+ .get(ruby.to_symbol("supports_audio_input"))
7423
+ .and_then(|v| bool::try_convert(v).ok()),
7424
+ supports_audio_output: kwargs
7425
+ .get(ruby.to_symbol("supports_audio_output"))
7426
+ .and_then(|v| bool::try_convert(v).ok()),
7427
+ supports_prompt_caching: kwargs
7428
+ .get(ruby.to_symbol("supports_prompt_caching"))
7429
+ .and_then(|v| bool::try_convert(v).ok()),
7430
+ tiers: kwargs
7431
+ .get(ruby.to_symbol("tiers"))
7432
+ .and_then(|v| <Vec<ModelTier>>::try_convert(v).ok())
7433
+ .unwrap_or_default(),
7434
+ })
7435
+ }
7436
+
7437
+ fn input_cost_per_token(&self) -> f64 {
7438
+ self.input_cost_per_token
7439
+ }
7440
+
7441
+ fn output_cost_per_token(&self) -> f64 {
7442
+ self.output_cost_per_token
7443
+ }
7444
+
7445
+ fn cache_read_input_token_cost(&self) -> Option<f64> {
7446
+ self.cache_read_input_token_cost
7447
+ }
7448
+
7449
+ fn cache_creation_input_token_cost(&self) -> Option<f64> {
7450
+ self.cache_creation_input_token_cost
7451
+ }
7452
+
7453
+ fn input_cost_per_audio_token(&self) -> Option<f64> {
7454
+ self.input_cost_per_audio_token
7455
+ }
7456
+
7457
+ fn output_cost_per_audio_token(&self) -> Option<f64> {
7458
+ self.output_cost_per_audio_token
7459
+ }
7460
+
7461
+ fn output_cost_per_reasoning_token(&self) -> Option<f64> {
7462
+ self.output_cost_per_reasoning_token
7463
+ }
7464
+
7465
+ fn max_tokens(&self) -> Option<u64> {
7466
+ self.max_tokens
7467
+ }
7468
+
7469
+ fn max_input_tokens(&self) -> Option<u64> {
7470
+ self.max_input_tokens
7471
+ }
7472
+
7473
+ fn max_output_tokens(&self) -> Option<u64> {
7474
+ self.max_output_tokens
7475
+ }
7476
+
7477
+ fn mode(&self) -> Option<String> {
7478
+ self.mode.clone()
7479
+ }
7480
+
7481
+ fn supports_vision(&self) -> Option<bool> {
7482
+ self.supports_vision
7483
+ }
7484
+
7485
+ fn supports_function_calling(&self) -> Option<bool> {
7486
+ self.supports_function_calling
7487
+ }
7488
+
7489
+ fn supports_reasoning(&self) -> Option<bool> {
7490
+ self.supports_reasoning
7491
+ }
7492
+
7493
+ fn supports_structured_output(&self) -> Option<bool> {
7494
+ self.supports_structured_output
7495
+ }
7496
+
7497
+ fn supports_audio_input(&self) -> Option<bool> {
7498
+ self.supports_audio_input
7499
+ }
7500
+
7501
+ fn supports_audio_output(&self) -> Option<bool> {
7502
+ self.supports_audio_output
7503
+ }
7504
+
7505
+ fn supports_prompt_caching(&self) -> Option<bool> {
7506
+ self.supports_prompt_caching
7507
+ }
7508
+
7509
+ fn tiers(&self) -> Vec<ModelTier> {
7510
+ self.tiers.clone()
7511
+ }
7512
+ }
7513
+
7514
+ #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
7515
+ #[serde(default)]
7516
+ #[magnus::wrap(class = "LiterLlm::ModelTier")]
7517
+ pub struct ModelTier {
7518
+ min_context_tokens: u64,
7519
+ input_cost_per_token: f64,
7520
+ output_cost_per_token: f64,
7521
+ cache_read_input_token_cost: Option<f64>,
7522
+ cache_creation_input_token_cost: Option<f64>,
7523
+ input_cost_per_audio_token: Option<f64>,
7524
+ output_cost_per_audio_token: Option<f64>,
7525
+ output_cost_per_reasoning_token: Option<f64>,
7526
+ }
7527
+
7528
+ unsafe impl IntoValueFromNative for ModelTier {}
7529
+
7530
+ impl magnus::TryConvert for ModelTier {
7531
+ fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
7532
+ if let Ok(r) = <&ModelTier as magnus::TryConvert>::try_convert(val) {
7533
+ return Ok(r.clone());
7534
+ }
7535
+ let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
7536
+ s
7537
+ } else {
7538
+ val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
7539
+ magnus::Error::new(
7540
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7541
+ format!("no implicit conversion into ModelTier: {}", e),
7542
+ )
7543
+ })?
7544
+ };
7545
+ serde_json::from_str::<ModelTier>(&json_str).map_err(|e| {
7546
+ magnus::Error::new(
7547
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7548
+ format!("failed to deserialize ModelTier: {}", e),
7549
+ )
7550
+ })
7551
+ }
7552
+ }
7553
+
7554
+ unsafe impl TryConvertOwned for ModelTier {}
7555
+
7556
+ impl Default for ModelTier {
7557
+ fn default() -> Self {
7558
+ liter_llm::ModelTier::default().into()
7559
+ }
7560
+ }
7561
+
7562
+ impl ModelTier {
7563
+ fn new(args: &[magnus::Value]) -> Result<Self, magnus::Error> {
7564
+ let ruby = unsafe { magnus::Ruby::get_unchecked() };
7565
+ let args = magnus::scan_args::scan_args::<(), (Option<magnus::RHash>,), (), (), (), ()>(args)?;
7566
+ let (kwargs_opt,) = args.optional;
7567
+ let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
7568
+ Ok(Self {
7569
+ min_context_tokens: kwargs
7570
+ .get(ruby.to_symbol("min_context_tokens"))
7571
+ .and_then(|v| u64::try_convert(v).ok())
7572
+ .unwrap_or_default(),
7573
+ input_cost_per_token: kwargs
7574
+ .get(ruby.to_symbol("input_cost_per_token"))
7575
+ .and_then(|v| f64::try_convert(v).ok())
7576
+ .unwrap_or_default(),
7577
+ output_cost_per_token: kwargs
7578
+ .get(ruby.to_symbol("output_cost_per_token"))
7579
+ .and_then(|v| f64::try_convert(v).ok())
7580
+ .unwrap_or_default(),
7581
+ cache_read_input_token_cost: kwargs
7582
+ .get(ruby.to_symbol("cache_read_input_token_cost"))
7583
+ .and_then(|v| f64::try_convert(v).ok()),
7584
+ cache_creation_input_token_cost: kwargs
7585
+ .get(ruby.to_symbol("cache_creation_input_token_cost"))
7586
+ .and_then(|v| f64::try_convert(v).ok()),
7587
+ input_cost_per_audio_token: kwargs
7588
+ .get(ruby.to_symbol("input_cost_per_audio_token"))
7589
+ .and_then(|v| f64::try_convert(v).ok()),
7590
+ output_cost_per_audio_token: kwargs
7591
+ .get(ruby.to_symbol("output_cost_per_audio_token"))
7592
+ .and_then(|v| f64::try_convert(v).ok()),
7593
+ output_cost_per_reasoning_token: kwargs
7594
+ .get(ruby.to_symbol("output_cost_per_reasoning_token"))
7595
+ .and_then(|v| f64::try_convert(v).ok()),
7596
+ })
7597
+ }
7598
+
7599
+ fn min_context_tokens(&self) -> u64 {
7600
+ self.min_context_tokens
7601
+ }
7602
+
7603
+ fn input_cost_per_token(&self) -> f64 {
7604
+ self.input_cost_per_token
7605
+ }
7606
+
7607
+ fn output_cost_per_token(&self) -> f64 {
7608
+ self.output_cost_per_token
7609
+ }
7610
+
7611
+ fn cache_read_input_token_cost(&self) -> Option<f64> {
7612
+ self.cache_read_input_token_cost
7613
+ }
7614
+
7615
+ fn cache_creation_input_token_cost(&self) -> Option<f64> {
7616
+ self.cache_creation_input_token_cost
7617
+ }
7618
+
7619
+ fn input_cost_per_audio_token(&self) -> Option<f64> {
7620
+ self.input_cost_per_audio_token
7621
+ }
7622
+
7623
+ fn output_cost_per_audio_token(&self) -> Option<f64> {
7624
+ self.output_cost_per_audio_token
7625
+ }
7626
+
7627
+ fn output_cost_per_reasoning_token(&self) -> Option<f64> {
7628
+ self.output_cost_per_reasoning_token
7629
+ }
7630
+ }
7631
+
7252
7632
  #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
7253
7633
  #[serde(default)]
7254
7634
  #[magnus::wrap(class = "LiterLlm::BudgetConfig")]
@@ -7326,6 +7706,84 @@ impl BudgetConfig {
7326
7706
  }
7327
7707
  }
7328
7708
 
7709
+ #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
7710
+ #[serde(default)]
7711
+ #[magnus::wrap(class = "LiterLlm::CacheConfig")]
7712
+ pub struct CacheConfig {
7713
+ max_entries: usize,
7714
+ ttl: u64,
7715
+ backend: CacheBackend,
7716
+ }
7717
+
7718
+ unsafe impl IntoValueFromNative for CacheConfig {}
7719
+
7720
+ impl magnus::TryConvert for CacheConfig {
7721
+ fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
7722
+ if let Ok(r) = <&CacheConfig as magnus::TryConvert>::try_convert(val) {
7723
+ return Ok(r.clone());
7724
+ }
7725
+ let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
7726
+ s
7727
+ } else {
7728
+ val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
7729
+ magnus::Error::new(
7730
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7731
+ format!("no implicit conversion into CacheConfig: {}", e),
7732
+ )
7733
+ })?
7734
+ };
7735
+ serde_json::from_str::<CacheConfig>(&json_str).map_err(|e| {
7736
+ magnus::Error::new(
7737
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7738
+ format!("failed to deserialize CacheConfig: {}", e),
7739
+ )
7740
+ })
7741
+ }
7742
+ }
7743
+
7744
+ unsafe impl TryConvertOwned for CacheConfig {}
7745
+
7746
+ impl Default for CacheConfig {
7747
+ fn default() -> Self {
7748
+ liter_llm::CacheConfig::default().into()
7749
+ }
7750
+ }
7751
+
7752
+ impl CacheConfig {
7753
+ fn new(args: &[magnus::Value]) -> Result<Self, magnus::Error> {
7754
+ let ruby = unsafe { magnus::Ruby::get_unchecked() };
7755
+ let args = magnus::scan_args::scan_args::<(), (Option<magnus::RHash>,), (), (), (), ()>(args)?;
7756
+ let (kwargs_opt,) = args.optional;
7757
+ let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
7758
+ Ok(Self {
7759
+ max_entries: kwargs
7760
+ .get(ruby.to_symbol("max_entries"))
7761
+ .and_then(|v| usize::try_convert(v).ok())
7762
+ .unwrap_or(256),
7763
+ ttl: kwargs
7764
+ .get(ruby.to_symbol("ttl"))
7765
+ .and_then(|v| u64::try_convert(v).ok())
7766
+ .unwrap_or(300000),
7767
+ backend: kwargs
7768
+ .get(ruby.to_symbol("backend"))
7769
+ .and_then(|v| CacheBackend::try_convert(v).ok())
7770
+ .unwrap_or(CacheBackend::Memory),
7771
+ })
7772
+ }
7773
+
7774
+ fn max_entries(&self) -> usize {
7775
+ self.max_entries
7776
+ }
7777
+
7778
+ fn ttl(&self) -> u64 {
7779
+ self.ttl.clone()
7780
+ }
7781
+
7782
+ fn backend(&self) -> CacheBackend {
7783
+ self.backend.clone()
7784
+ }
7785
+ }
7786
+
7329
7787
  #[derive(Clone)]
7330
7788
  #[magnus::wrap(class = "LiterLlm::SingleflightResult")]
7331
7789
  pub struct SingleflightResult {
@@ -7489,10 +7947,96 @@ impl IntentPrototype {
7489
7947
  }
7490
7948
 
7491
7949
  #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
7492
- #[serde(tag = "role")]
7493
- pub enum Message {
7494
- #[serde(rename = "system")]
7495
- System { _0: SystemMessage },
7950
+ #[serde(default)]
7951
+ #[magnus::wrap(class = "LiterLlm::CatalogRefreshConfig")]
7952
+ pub struct CatalogRefreshConfig {
7953
+ enabled: bool,
7954
+ source_url: String,
7955
+ ttl_seconds: u64,
7956
+ cache_path: Option<String>,
7957
+ }
7958
+
7959
+ unsafe impl IntoValueFromNative for CatalogRefreshConfig {}
7960
+
7961
+ impl magnus::TryConvert for CatalogRefreshConfig {
7962
+ fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
7963
+ if let Ok(r) = <&CatalogRefreshConfig as magnus::TryConvert>::try_convert(val) {
7964
+ return Ok(r.clone());
7965
+ }
7966
+ let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
7967
+ s
7968
+ } else {
7969
+ val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
7970
+ magnus::Error::new(
7971
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7972
+ format!("no implicit conversion into CatalogRefreshConfig: {}", e),
7973
+ )
7974
+ })?
7975
+ };
7976
+ serde_json::from_str::<CatalogRefreshConfig>(&json_str).map_err(|e| {
7977
+ magnus::Error::new(
7978
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
7979
+ format!("failed to deserialize CatalogRefreshConfig: {}", e),
7980
+ )
7981
+ })
7982
+ }
7983
+ }
7984
+
7985
+ unsafe impl TryConvertOwned for CatalogRefreshConfig {}
7986
+
7987
+ impl Default for CatalogRefreshConfig {
7988
+ fn default() -> Self {
7989
+ liter_llm::cost::refresh::CatalogRefreshConfig::default().into()
7990
+ }
7991
+ }
7992
+
7993
+ impl CatalogRefreshConfig {
7994
+ fn new(args: &[magnus::Value]) -> Result<Self, magnus::Error> {
7995
+ let ruby = unsafe { magnus::Ruby::get_unchecked() };
7996
+ let args = magnus::scan_args::scan_args::<(), (Option<magnus::RHash>,), (), (), (), ()>(args)?;
7997
+ let (kwargs_opt,) = args.optional;
7998
+ let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
7999
+ Ok(Self {
8000
+ enabled: kwargs
8001
+ .get(ruby.to_symbol("enabled"))
8002
+ .and_then(|v| bool::try_convert(v).ok())
8003
+ .unwrap_or(false),
8004
+ source_url: kwargs
8005
+ .get(ruby.to_symbol("source_url"))
8006
+ .and_then(|v| String::try_convert(v).ok())
8007
+ .unwrap_or_default(),
8008
+ ttl_seconds: kwargs
8009
+ .get(ruby.to_symbol("ttl_seconds"))
8010
+ .and_then(|v| u64::try_convert(v).ok())
8011
+ .unwrap_or(86400),
8012
+ cache_path: kwargs
8013
+ .get(ruby.to_symbol("cache_path"))
8014
+ .and_then(|v| String::try_convert(v).ok()),
8015
+ })
8016
+ }
8017
+
8018
+ fn enabled(&self) -> bool {
8019
+ self.enabled
8020
+ }
8021
+
8022
+ fn source_url(&self) -> String {
8023
+ self.source_url.clone()
8024
+ }
8025
+
8026
+ fn ttl_seconds(&self) -> u64 {
8027
+ self.ttl_seconds
8028
+ }
8029
+
8030
+ fn cache_path(&self) -> Option<String> {
8031
+ self.cache_path.clone()
8032
+ }
8033
+ }
8034
+
8035
+ #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
8036
+ #[serde(tag = "role")]
8037
+ pub enum Message {
8038
+ #[serde(rename = "system")]
8039
+ System { _0: SystemMessage },
7496
8040
  #[serde(rename = "user")]
7497
8041
  User { _0: UserMessage },
7498
8042
  #[serde(rename = "assistant")]
@@ -8855,6 +9399,65 @@ impl magnus::TryConvert for Enforcement {
8855
9399
  unsafe impl IntoValueFromNative for Enforcement {}
8856
9400
  unsafe impl TryConvertOwned for Enforcement {}
8857
9401
 
9402
+ #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
9403
+ #[serde(tag = "type")]
9404
+ #[serde(rename_all = "snake_case")]
9405
+ pub enum CacheBackend {
9406
+ Memory,
9407
+ OpenDal { scheme: String, config: String },
9408
+ }
9409
+
9410
+ impl Default for CacheBackend {
9411
+ fn default() -> Self {
9412
+ Self::Memory
9413
+ }
9414
+ }
9415
+
9416
+ impl magnus::IntoValue for CacheBackend {
9417
+ fn into_value_with(self, handle: &Ruby) -> magnus::Value {
9418
+ match serde_json::to_value(&self) {
9419
+ Ok(v) => json_to_ruby(handle, v),
9420
+ Err(_) => handle.qnil().into_value_with(handle),
9421
+ }
9422
+ }
9423
+ }
9424
+
9425
+ impl magnus::TryConvert for CacheBackend {
9426
+ fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
9427
+ // For data enums with fields (e.g., PageAction), try to deserialize from JSON first.
9428
+ // For unit enums or when passed as a string, fall back to string-based conversion.
9429
+ let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
9430
+ s
9431
+ } else {
9432
+ val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
9433
+ magnus::Error::new(
9434
+ unsafe { Ruby::get_unchecked() }.exception_type_error(),
9435
+ format!("no implicit conversion into CacheBackend: {}", e),
9436
+ )
9437
+ })?
9438
+ };
9439
+ // Try deserializing as JSON first (handles JSON strings like "\"markdown\"" or "{\"click\":{\"selector\":\"...\"}}\"")
9440
+ // For internally-tagged enums, a bare variant string is wrapped as {"<tag>": value}.
9441
+ // If that fails, try treating it as a plain string value and wrap in quotes
9442
+ // If both fail, try as Custom variant (for untagged enum support)
9443
+ serde_json::from_str(&json_str)
9444
+ .or_else(|_| serde_json::from_value(serde_json::json!({ "type": json_str })))
9445
+ .or_else(|_| serde_json::from_str(&format!("\"{json_str}\"")))
9446
+ .or_else(|_| {
9447
+ // Try as a JSON string for Custom variant (untagged enums accept any remaining value)
9448
+ match serde_json::to_value(&json_str) {
9449
+ Ok(val) => serde_json::from_value(val),
9450
+ Err(e) => Err(e),
9451
+ }
9452
+ })
9453
+ .map_err(|e| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_type_error(), e.to_string()))
9454
+ }
9455
+ }
9456
+
9457
+ unsafe impl IntoValueFromNative for CacheBackend {}
9458
+ unsafe impl TryConvertOwned for CacheBackend {}
9459
+ impl CacheBackend {}
9460
+
8858
9461
  #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
8859
9462
  pub enum CircuitState {
8860
9463
  Closed,
@@ -8940,6 +9543,50 @@ impl magnus::TryConvert for HealthStatus {
8940
9543
  unsafe impl IntoValueFromNative for HealthStatus {}
8941
9544
  unsafe impl TryConvertOwned for HealthStatus {}
8942
9545
 
9546
+ #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
9547
+ pub enum RefreshOutcome {
9548
+ Disabled,
9549
+ FromCache,
9550
+ Fetched,
9551
+ }
9552
+
9553
+ impl Default for RefreshOutcome {
9554
+ fn default() -> Self {
9555
+ Self::Disabled
9556
+ }
9557
+ }
9558
+
9559
+ impl magnus::IntoValue for RefreshOutcome {
9560
+ fn into_value_with(self, handle: &Ruby) -> magnus::Value {
9561
+ let sym = match self {
9562
+ RefreshOutcome::Disabled => "disabled",
9563
+ RefreshOutcome::FromCache => "from_cache",
9564
+ RefreshOutcome::Fetched => "fetched",
9565
+ };
9566
+ handle.to_symbol(sym).into_value_with(handle)
9567
+ }
9568
+ }
9569
+
9570
+ impl magnus::TryConvert for RefreshOutcome {
9571
+ fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
9572
+ let s: String = magnus::TryConvert::try_convert(val)?;
9573
+ // Accept the serde wire name (snake_case), the PascalCase Rust variant name,
9574
+ // and a lowercase fallback so fixtures written in any of those styles work.
9575
+ match s.as_str() {
9576
+ "disabled" | "Disabled" => Ok(RefreshOutcome::Disabled),
9577
+ "from_cache" | "FromCache" => Ok(RefreshOutcome::FromCache),
9578
+ "fetched" | "Fetched" => Ok(RefreshOutcome::Fetched),
9579
+ other => Err(magnus::Error::new(
9580
+ unsafe { Ruby::get_unchecked() }.exception_arg_error(),
9581
+ format!("invalid RefreshOutcome value: {other}"),
9582
+ )),
9583
+ }
9584
+ }
9585
+ }
9586
+
9587
+ unsafe impl IntoValueFromNative for RefreshOutcome {}
9588
+ unsafe impl TryConvertOwned for RefreshOutcome {}
9589
+
8943
9590
  fn create_client(args: &[magnus::Value]) -> Result<DefaultClient, Error> {
8944
9591
  let args = magnus::scan_args::scan_args::<
8945
9592
  (String,),
@@ -9075,6 +9722,10 @@ fn completion_cost_with_cache(
9075
9722
  liter_llm::completion_cost_with_cache(&model, prompt_tokens, cached_tokens, completion_tokens)
9076
9723
  }
9077
9724
 
9725
+ fn model_info(model: String) -> Option<ModelInfo> {
9726
+ liter_llm::model_info(&model).map(Into::into)
9727
+ }
9728
+
9078
9729
  fn clear() -> () {
9079
9730
  liter_llm::guardrail::registry::clear()
9080
9731
  }
@@ -9134,16 +9785,98 @@ fn ensure_crypto_provider() -> () {
9134
9785
  liter_llm::ensure_crypto_provider()
9135
9786
  }
9136
9787
 
9788
+ fn install_catalog_overlay_from_str(catalog_json: String) -> Result<(), Error> {
9789
+ let result = liter_llm::cost::refresh::install_catalog_overlay_from_str(&catalog_json).map_err(|e| {
9790
+ magnus::Error::new(
9791
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
9792
+ e.to_string(),
9793
+ )
9794
+ })?;
9795
+ Ok(result)
9796
+ }
9797
+
9798
+ fn clear_catalog_overlay() -> () {
9799
+ liter_llm::cost::refresh::clear_catalog_overlay()
9800
+ }
9801
+
9802
+ fn refresh_catalog(args: &[magnus::Value]) -> Result<RefreshOutcome, Error> {
9803
+ let args = magnus::scan_args::scan_args::<(), (Option<magnus::Value>,), (), (), (), ()>(args)?;
9804
+ let (config,) = args.optional;
9805
+
9806
+ let config_core: liter_llm::CatalogRefreshConfig = match config {
9807
+ Some(_v) if !_v.is_nil() => {
9808
+ let binding_val: CatalogRefreshConfig = CatalogRefreshConfig::try_convert(_v).map_err(|e| {
9809
+ magnus::Error::new(
9810
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
9811
+ e.to_string(),
9812
+ )
9813
+ })?;
9814
+ binding_val.into()
9815
+ }
9816
+ _ => Default::default(),
9817
+ };
9818
+ let rt = tokio::runtime::Runtime::new().map_err(|e| {
9819
+ magnus::Error::new(
9820
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
9821
+ e.to_string(),
9822
+ )
9823
+ })?;
9824
+ let result = rt
9825
+ .block_on(async { liter_llm::cost::refresh::refresh_catalog(&config_core).await })
9826
+ .map_err(|e| {
9827
+ magnus::Error::new(
9828
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
9829
+ e.to_string(),
9830
+ )
9831
+ })?;
9832
+ Ok(result.into())
9833
+ }
9834
+
9835
+ fn refresh_catalog_async(args: &[magnus::Value]) -> Result<RefreshOutcome, Error> {
9836
+ let args = magnus::scan_args::scan_args::<(), (Option<magnus::Value>,), (), (), (), ()>(args)?;
9837
+ let (config,) = args.optional;
9838
+
9839
+ let config_core: liter_llm::CatalogRefreshConfig = match config {
9840
+ Some(_v) if !_v.is_nil() => {
9841
+ let binding_val: CatalogRefreshConfig = CatalogRefreshConfig::try_convert(_v).map_err(|e| {
9842
+ magnus::Error::new(
9843
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
9844
+ e.to_string(),
9845
+ )
9846
+ })?;
9847
+ binding_val.into()
9848
+ }
9849
+ _ => Default::default(),
9850
+ };
9851
+ let rt = tokio::runtime::Runtime::new().map_err(|e| {
9852
+ magnus::Error::new(
9853
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
9854
+ e.to_string(),
9855
+ )
9856
+ })?;
9857
+ let result = rt
9858
+ .block_on(async { liter_llm::cost::refresh::refresh_catalog(&config_core).await })
9859
+ .map_err(|e| {
9860
+ magnus::Error::new(
9861
+ unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
9862
+ e.to_string(),
9863
+ )
9864
+ })?;
9865
+ Ok(result.into())
9866
+ }
9867
+
9137
9868
  fn chat_stream(engine: DefaultClient, req: ChatCompletionRequest) -> Result<magnus::Value, Error> {
9138
9869
  engine.chat_stream(req)
9139
9870
  }
9140
9871
 
9872
+ #[allow(clippy::needless_update)]
9141
9873
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9142
9874
  impl From<SystemMessage> for liter_llm::types::SystemMessage {
9143
9875
  fn from(val: SystemMessage) -> Self {
9144
9876
  Self {
9145
9877
  content: val.content.into(),
9146
9878
  name: val.name,
9879
+ ..Default::default()
9147
9880
  }
9148
9881
  }
9149
9882
  }
@@ -9158,12 +9891,14 @@ impl From<liter_llm::types::SystemMessage> for SystemMessage {
9158
9891
  }
9159
9892
  }
9160
9893
 
9894
+ #[allow(clippy::needless_update)]
9161
9895
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9162
9896
  impl From<UserMessage> for liter_llm::types::UserMessage {
9163
9897
  fn from(val: UserMessage) -> Self {
9164
9898
  Self {
9165
9899
  content: val.content.into(),
9166
9900
  name: val.name,
9901
+ ..Default::default()
9167
9902
  }
9168
9903
  }
9169
9904
  }
@@ -9178,12 +9913,14 @@ impl From<liter_llm::types::UserMessage> for UserMessage {
9178
9913
  }
9179
9914
  }
9180
9915
 
9916
+ #[allow(clippy::needless_update)]
9181
9917
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9182
9918
  impl From<ImageUrl> for liter_llm::types::ImageUrl {
9183
9919
  fn from(val: ImageUrl) -> Self {
9184
9920
  Self {
9185
9921
  url: val.url,
9186
9922
  detail: val.detail.map(Into::into),
9923
+ ..Default::default()
9187
9924
  }
9188
9925
  }
9189
9926
  }
@@ -9198,12 +9935,14 @@ impl From<liter_llm::types::ImageUrl> for ImageUrl {
9198
9935
  }
9199
9936
  }
9200
9937
 
9938
+ #[allow(clippy::needless_update)]
9201
9939
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9202
9940
  impl From<DocumentContent> for liter_llm::types::DocumentContent {
9203
9941
  fn from(val: DocumentContent) -> Self {
9204
9942
  Self {
9205
9943
  data: val.data,
9206
9944
  media_type: val.media_type,
9945
+ ..Default::default()
9207
9946
  }
9208
9947
  }
9209
9948
  }
@@ -9218,12 +9957,14 @@ impl From<liter_llm::types::DocumentContent> for DocumentContent {
9218
9957
  }
9219
9958
  }
9220
9959
 
9960
+ #[allow(clippy::needless_update)]
9221
9961
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9222
9962
  impl From<AudioContent> for liter_llm::types::AudioContent {
9223
9963
  fn from(val: AudioContent) -> Self {
9224
9964
  Self {
9225
9965
  data: val.data,
9226
9966
  format: val.format,
9967
+ ..Default::default()
9227
9968
  }
9228
9969
  }
9229
9970
  }
@@ -9238,6 +9979,7 @@ impl From<liter_llm::types::AudioContent> for AudioContent {
9238
9979
  }
9239
9980
  }
9240
9981
 
9982
+ #[allow(clippy::needless_update)]
9241
9983
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9242
9984
  impl From<AssistantMessage> for liter_llm::types::AssistantMessage {
9243
9985
  fn from(val: AssistantMessage) -> Self {
@@ -9247,6 +9989,8 @@ impl From<AssistantMessage> for liter_llm::types::AssistantMessage {
9247
9989
  tool_calls: val.tool_calls.map(|v| v.into_iter().map(Into::into).collect()),
9248
9990
  refusal: val.refusal,
9249
9991
  function_call: val.function_call.map(Into::into),
9992
+ reasoning_content: val.reasoning_content,
9993
+ ..Default::default()
9250
9994
  }
9251
9995
  }
9252
9996
  }
@@ -9260,10 +10004,12 @@ impl From<liter_llm::types::AssistantMessage> for AssistantMessage {
9260
10004
  tool_calls: val.tool_calls.map(|v| v.into_iter().map(Into::into).collect()),
9261
10005
  refusal: val.refusal.map(|v| v.to_string()),
9262
10006
  function_call: val.function_call.map(Into::into),
10007
+ reasoning_content: val.reasoning_content.map(|v| v.to_string()),
9263
10008
  }
9264
10009
  }
9265
10010
  }
9266
10011
 
10012
+ #[allow(clippy::needless_update)]
9267
10013
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9268
10014
  impl From<ToolMessage> for liter_llm::types::ToolMessage {
9269
10015
  fn from(val: ToolMessage) -> Self {
@@ -9271,6 +10017,7 @@ impl From<ToolMessage> for liter_llm::types::ToolMessage {
9271
10017
  content: val.content,
9272
10018
  tool_call_id: val.tool_call_id,
9273
10019
  name: val.name,
10020
+ ..Default::default()
9274
10021
  }
9275
10022
  }
9276
10023
  }
@@ -9286,12 +10033,14 @@ impl From<liter_llm::types::ToolMessage> for ToolMessage {
9286
10033
  }
9287
10034
  }
9288
10035
 
10036
+ #[allow(clippy::needless_update)]
9289
10037
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9290
10038
  impl From<DeveloperMessage> for liter_llm::types::DeveloperMessage {
9291
10039
  fn from(val: DeveloperMessage) -> Self {
9292
10040
  Self {
9293
10041
  content: val.content,
9294
10042
  name: val.name,
10043
+ ..Default::default()
9295
10044
  }
9296
10045
  }
9297
10046
  }
@@ -9306,12 +10055,14 @@ impl From<liter_llm::types::DeveloperMessage> for DeveloperMessage {
9306
10055
  }
9307
10056
  }
9308
10057
 
10058
+ #[allow(clippy::needless_update)]
9309
10059
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9310
10060
  impl From<FunctionMessage> for liter_llm::types::FunctionMessage {
9311
10061
  fn from(val: FunctionMessage) -> Self {
9312
10062
  Self {
9313
10063
  content: val.content,
9314
10064
  name: val.name,
10065
+ ..Default::default()
9315
10066
  }
9316
10067
  }
9317
10068
  }
@@ -9412,12 +10163,14 @@ impl From<liter_llm::types::FunctionCall> for FunctionCall {
9412
10163
  }
9413
10164
  }
9414
10165
 
10166
+ #[allow(clippy::needless_update)]
9415
10167
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9416
10168
  impl From<SpecificToolChoice> for liter_llm::types::SpecificToolChoice {
9417
10169
  fn from(val: SpecificToolChoice) -> Self {
9418
10170
  Self {
9419
10171
  choice_type: val.choice_type.into(),
9420
10172
  function: val.function.into(),
10173
+ ..Default::default()
9421
10174
  }
9422
10175
  }
9423
10176
  }
@@ -9432,10 +10185,14 @@ impl From<liter_llm::types::SpecificToolChoice> for SpecificToolChoice {
9432
10185
  }
9433
10186
  }
9434
10187
 
10188
+ #[allow(clippy::needless_update)]
9435
10189
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9436
10190
  impl From<SpecificFunction> for liter_llm::types::SpecificFunction {
9437
10191
  fn from(val: SpecificFunction) -> Self {
9438
- Self { name: val.name }
10192
+ Self {
10193
+ name: val.name,
10194
+ ..Default::default()
10195
+ }
9439
10196
  }
9440
10197
  }
9441
10198
 
@@ -9448,6 +10205,7 @@ impl From<liter_llm::types::SpecificFunction> for SpecificFunction {
9448
10205
  }
9449
10206
  }
9450
10207
 
10208
+ #[allow(clippy::needless_update)]
9451
10209
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9452
10210
  impl From<JsonSchemaFormat> for liter_llm::types::JsonSchemaFormat {
9453
10211
  fn from(val: JsonSchemaFormat) -> Self {
@@ -9456,6 +10214,7 @@ impl From<JsonSchemaFormat> for liter_llm::types::JsonSchemaFormat {
9456
10214
  description: val.description,
9457
10215
  schema: serde_json::from_str(&val.schema).unwrap_or_default(),
9458
10216
  strict: val.strict,
10217
+ ..Default::default()
9459
10218
  }
9460
10219
  }
9461
10220
  }
@@ -9472,6 +10231,7 @@ impl From<liter_llm::types::JsonSchemaFormat> for JsonSchemaFormat {
9472
10231
  }
9473
10232
  }
9474
10233
 
10234
+ #[allow(clippy::needless_update)]
9475
10235
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9476
10236
  impl From<Usage> for liter_llm::types::Usage {
9477
10237
  fn from(val: Usage) -> Self {
@@ -9480,6 +10240,7 @@ impl From<Usage> for liter_llm::types::Usage {
9480
10240
  completion_tokens: val.completion_tokens,
9481
10241
  total_tokens: val.total_tokens,
9482
10242
  prompt_tokens_details: val.prompt_tokens_details.map(Into::into),
10243
+ ..Default::default()
9483
10244
  }
9484
10245
  }
9485
10246
  }
@@ -9496,12 +10257,14 @@ impl From<liter_llm::types::Usage> for Usage {
9496
10257
  }
9497
10258
  }
9498
10259
 
10260
+ #[allow(clippy::needless_update)]
9499
10261
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9500
10262
  impl From<PromptTokensDetails> for liter_llm::types::PromptTokensDetails {
9501
10263
  fn from(val: PromptTokensDetails) -> Self {
9502
10264
  Self {
9503
10265
  cached_tokens: val.cached_tokens,
9504
10266
  audio_tokens: val.audio_tokens,
10267
+ ..Default::default()
9505
10268
  }
9506
10269
  }
9507
10270
  }
@@ -9516,6 +10279,7 @@ impl From<liter_llm::types::PromptTokensDetails> for PromptTokensDetails {
9516
10279
  }
9517
10280
  }
9518
10281
 
10282
+ #[allow(clippy::needless_update)]
9519
10283
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9520
10284
  impl From<ChatCompletionRequest> for liter_llm::types::ChatCompletionRequest {
9521
10285
  fn from(val: ChatCompletionRequest) -> Self {
@@ -9541,6 +10305,7 @@ impl From<ChatCompletionRequest> for liter_llm::types::ChatCompletionRequest {
9541
10305
  reasoning_effort: val.reasoning_effort.map(Into::into),
9542
10306
  modalities: val.modalities.map(|v| v.into_iter().map(Into::into).collect()),
9543
10307
  extra_body: val.extra_body.as_ref().and_then(|s| serde_json::from_str(s).ok()),
10308
+ ..Default::default()
9544
10309
  }
9545
10310
  }
9546
10311
  }
@@ -9574,11 +10339,13 @@ impl From<liter_llm::types::ChatCompletionRequest> for ChatCompletionRequest {
9574
10339
  }
9575
10340
  }
9576
10341
 
10342
+ #[allow(clippy::needless_update)]
9577
10343
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9578
10344
  impl From<StreamOptions> for liter_llm::types::StreamOptions {
9579
10345
  fn from(val: StreamOptions) -> Self {
9580
10346
  Self {
9581
10347
  include_usage: val.include_usage,
10348
+ ..Default::default()
9582
10349
  }
9583
10350
  }
9584
10351
  }
@@ -9592,6 +10359,7 @@ impl From<liter_llm::types::StreamOptions> for StreamOptions {
9592
10359
  }
9593
10360
  }
9594
10361
 
10362
+ #[allow(clippy::needless_update)]
9595
10363
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9596
10364
  impl From<ChatCompletionResponse> for liter_llm::types::ChatCompletionResponse {
9597
10365
  fn from(val: ChatCompletionResponse) -> Self {
@@ -9604,6 +10372,7 @@ impl From<ChatCompletionResponse> for liter_llm::types::ChatCompletionResponse {
9604
10372
  usage: val.usage.map(Into::into),
9605
10373
  system_fingerprint: val.system_fingerprint,
9606
10374
  service_tier: val.service_tier,
10375
+ ..Default::default()
9607
10376
  }
9608
10377
  }
9609
10378
  }
@@ -9624,6 +10393,7 @@ impl From<liter_llm::types::ChatCompletionResponse> for ChatCompletionResponse {
9624
10393
  }
9625
10394
  }
9626
10395
 
10396
+ #[allow(clippy::needless_update)]
9627
10397
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9628
10398
  impl From<Choice> for liter_llm::types::Choice {
9629
10399
  fn from(val: Choice) -> Self {
@@ -9631,6 +10401,7 @@ impl From<Choice> for liter_llm::types::Choice {
9631
10401
  index: val.index,
9632
10402
  message: val.message.into(),
9633
10403
  finish_reason: val.finish_reason.map(Into::into),
10404
+ ..Default::default()
9634
10405
  }
9635
10406
  }
9636
10407
  }
@@ -9682,6 +10453,7 @@ impl From<liter_llm::types::StreamDelta> for StreamDelta {
9682
10453
  tool_calls: val.tool_calls.map(|v| v.into_iter().map(Into::into).collect()),
9683
10454
  function_call: val.function_call.map(Into::into),
9684
10455
  refusal: val.refusal.map(|v| v.to_string()),
10456
+ reasoning_content: val.reasoning_content.map(|v| v.to_string()),
9685
10457
  }
9686
10458
  }
9687
10459
  }
@@ -9708,6 +10480,7 @@ impl From<liter_llm::types::StreamFunctionCall> for StreamFunctionCall {
9708
10480
  }
9709
10481
  }
9710
10482
 
10483
+ #[allow(clippy::needless_update)]
9711
10484
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9712
10485
  impl From<EmbeddingRequest> for liter_llm::types::EmbeddingRequest {
9713
10486
  fn from(val: EmbeddingRequest) -> Self {
@@ -9717,6 +10490,7 @@ impl From<EmbeddingRequest> for liter_llm::types::EmbeddingRequest {
9717
10490
  encoding_format: val.encoding_format.map(Into::into),
9718
10491
  dimensions: val.dimensions,
9719
10492
  user: val.user,
10493
+ ..Default::default()
9720
10494
  }
9721
10495
  }
9722
10496
  }
@@ -9780,6 +10554,7 @@ impl From<liter_llm::types::EmbeddingObject> for EmbeddingObject {
9780
10554
  }
9781
10555
  }
9782
10556
 
10557
+ #[allow(clippy::needless_update)]
9783
10558
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9784
10559
  impl From<CreateImageRequest> for liter_llm::types::CreateImageRequest {
9785
10560
  fn from(val: CreateImageRequest) -> Self {
@@ -9792,6 +10567,7 @@ impl From<CreateImageRequest> for liter_llm::types::CreateImageRequest {
9792
10567
  style: val.style,
9793
10568
  response_format: val.response_format,
9794
10569
  user: val.user,
10570
+ ..Default::default()
9795
10571
  }
9796
10572
  }
9797
10573
  }
@@ -9812,12 +10588,14 @@ impl From<liter_llm::types::CreateImageRequest> for CreateImageRequest {
9812
10588
  }
9813
10589
  }
9814
10590
 
10591
+ #[allow(clippy::needless_update)]
9815
10592
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9816
10593
  impl From<ImagesResponse> for liter_llm::types::ImagesResponse {
9817
10594
  fn from(val: ImagesResponse) -> Self {
9818
10595
  Self {
9819
10596
  created: val.created,
9820
10597
  data: val.data.into_iter().map(Into::into).collect(),
10598
+ ..Default::default()
9821
10599
  }
9822
10600
  }
9823
10601
  }
@@ -9832,6 +10610,7 @@ impl From<liter_llm::types::ImagesResponse> for ImagesResponse {
9832
10610
  }
9833
10611
  }
9834
10612
 
10613
+ #[allow(clippy::needless_update)]
9835
10614
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9836
10615
  impl From<Image> for liter_llm::types::Image {
9837
10616
  fn from(val: Image) -> Self {
@@ -9839,6 +10618,7 @@ impl From<Image> for liter_llm::types::Image {
9839
10618
  url: val.url,
9840
10619
  b64_json: val.b64_json,
9841
10620
  revised_prompt: val.revised_prompt,
10621
+ ..Default::default()
9842
10622
  }
9843
10623
  }
9844
10624
  }
@@ -9854,12 +10634,14 @@ impl From<liter_llm::types::Image> for Image {
9854
10634
  }
9855
10635
  }
9856
10636
 
10637
+ #[allow(clippy::needless_update)]
9857
10638
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9858
10639
  impl From<DecodedDataUrl> for liter_llm::image::DecodedDataUrl {
9859
10640
  fn from(val: DecodedDataUrl) -> Self {
9860
10641
  Self {
9861
10642
  mime: val.mime,
9862
10643
  data: val.data.to_vec().into(),
10644
+ ..Default::default()
9863
10645
  }
9864
10646
  }
9865
10647
  }
@@ -9874,6 +10656,7 @@ impl From<liter_llm::image::DecodedDataUrl> for DecodedDataUrl {
9874
10656
  }
9875
10657
  }
9876
10658
 
10659
+ #[allow(clippy::needless_update)]
9877
10660
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9878
10661
  impl From<CreateSpeechRequest> for liter_llm::types::CreateSpeechRequest {
9879
10662
  fn from(val: CreateSpeechRequest) -> Self {
@@ -9883,6 +10666,7 @@ impl From<CreateSpeechRequest> for liter_llm::types::CreateSpeechRequest {
9883
10666
  voice: val.voice,
9884
10667
  response_format: val.response_format,
9885
10668
  speed: val.speed,
10669
+ ..Default::default()
9886
10670
  }
9887
10671
  }
9888
10672
  }
@@ -9900,6 +10684,7 @@ impl From<liter_llm::types::CreateSpeechRequest> for CreateSpeechRequest {
9900
10684
  }
9901
10685
  }
9902
10686
 
10687
+ #[allow(clippy::needless_update)]
9903
10688
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9904
10689
  impl From<CreateTranscriptionRequest> for liter_llm::types::CreateTranscriptionRequest {
9905
10690
  fn from(val: CreateTranscriptionRequest) -> Self {
@@ -9910,6 +10695,7 @@ impl From<CreateTranscriptionRequest> for liter_llm::types::CreateTranscriptionR
9910
10695
  prompt: val.prompt,
9911
10696
  response_format: val.response_format,
9912
10697
  temperature: val.temperature,
10698
+ ..Default::default()
9913
10699
  }
9914
10700
  }
9915
10701
  }
@@ -9928,6 +10714,7 @@ impl From<liter_llm::types::CreateTranscriptionRequest> for CreateTranscriptionR
9928
10714
  }
9929
10715
  }
9930
10716
 
10717
+ #[allow(clippy::needless_update)]
9931
10718
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9932
10719
  impl From<TranscriptionResponse> for liter_llm::types::TranscriptionResponse {
9933
10720
  fn from(val: TranscriptionResponse) -> Self {
@@ -9936,6 +10723,7 @@ impl From<TranscriptionResponse> for liter_llm::types::TranscriptionResponse {
9936
10723
  language: val.language,
9937
10724
  duration: val.duration,
9938
10725
  segments: val.segments.map(|v| v.into_iter().map(Into::into).collect()),
10726
+ ..Default::default()
9939
10727
  }
9940
10728
  }
9941
10729
  }
@@ -9952,6 +10740,7 @@ impl From<liter_llm::types::TranscriptionResponse> for TranscriptionResponse {
9952
10740
  }
9953
10741
  }
9954
10742
 
10743
+ #[allow(clippy::needless_update)]
9955
10744
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9956
10745
  impl From<TranscriptionSegment> for liter_llm::types::TranscriptionSegment {
9957
10746
  fn from(val: TranscriptionSegment) -> Self {
@@ -9960,6 +10749,7 @@ impl From<TranscriptionSegment> for liter_llm::types::TranscriptionSegment {
9960
10749
  start: val.start,
9961
10750
  end: val.end,
9962
10751
  text: val.text,
10752
+ ..Default::default()
9963
10753
  }
9964
10754
  }
9965
10755
  }
@@ -9976,12 +10766,14 @@ impl From<liter_llm::types::TranscriptionSegment> for TranscriptionSegment {
9976
10766
  }
9977
10767
  }
9978
10768
 
10769
+ #[allow(clippy::needless_update)]
9979
10770
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
9980
10771
  impl From<ModerationRequest> for liter_llm::types::ModerationRequest {
9981
10772
  fn from(val: ModerationRequest) -> Self {
9982
10773
  Self {
9983
10774
  input: val.input.into(),
9984
10775
  model: val.model,
10776
+ ..Default::default()
9985
10777
  }
9986
10778
  }
9987
10779
  }
@@ -10040,6 +10832,7 @@ impl From<liter_llm::types::ModerationResult> for ModerationResult {
10040
10832
  }
10041
10833
  }
10042
10834
 
10835
+ #[allow(clippy::needless_update)]
10043
10836
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10044
10837
  impl From<ModerationCategories> for liter_llm::types::ModerationCategories {
10045
10838
  fn from(val: ModerationCategories) -> Self {
@@ -10055,6 +10848,7 @@ impl From<ModerationCategories> for liter_llm::types::ModerationCategories {
10055
10848
  self_harm_instructions: val.self_harm_instructions,
10056
10849
  harassment_threatening: val.harassment_threatening,
10057
10850
  violence: val.violence,
10851
+ ..Default::default()
10058
10852
  }
10059
10853
  }
10060
10854
  }
@@ -10078,6 +10872,7 @@ impl From<liter_llm::types::ModerationCategories> for ModerationCategories {
10078
10872
  }
10079
10873
  }
10080
10874
 
10875
+ #[allow(clippy::needless_update)]
10081
10876
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10082
10877
  impl From<ModerationCategoryScores> for liter_llm::types::ModerationCategoryScores {
10083
10878
  fn from(val: ModerationCategoryScores) -> Self {
@@ -10093,6 +10888,7 @@ impl From<ModerationCategoryScores> for liter_llm::types::ModerationCategoryScor
10093
10888
  self_harm_instructions: val.self_harm_instructions,
10094
10889
  harassment_threatening: val.harassment_threatening,
10095
10890
  violence: val.violence,
10891
+ ..Default::default()
10096
10892
  }
10097
10893
  }
10098
10894
  }
@@ -10116,6 +10912,7 @@ impl From<liter_llm::types::ModerationCategoryScores> for ModerationCategoryScor
10116
10912
  }
10117
10913
  }
10118
10914
 
10915
+ #[allow(clippy::needless_update)]
10119
10916
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10120
10917
  impl From<RerankRequest> for liter_llm::types::RerankRequest {
10121
10918
  fn from(val: RerankRequest) -> Self {
@@ -10125,6 +10922,7 @@ impl From<RerankRequest> for liter_llm::types::RerankRequest {
10125
10922
  documents: val.documents.into_iter().map(Into::into).collect(),
10126
10923
  top_n: val.top_n,
10127
10924
  return_documents: val.return_documents,
10925
+ ..Default::default()
10128
10926
  }
10129
10927
  }
10130
10928
  }
@@ -10202,6 +11000,7 @@ impl From<liter_llm::types::RerankResultDocument> for RerankResultDocument {
10202
11000
  }
10203
11001
  }
10204
11002
 
11003
+ #[allow(clippy::needless_update)]
10205
11004
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10206
11005
  impl From<SearchRequest> for liter_llm::types::SearchRequest {
10207
11006
  fn from(val: SearchRequest) -> Self {
@@ -10211,6 +11010,7 @@ impl From<SearchRequest> for liter_llm::types::SearchRequest {
10211
11010
  max_results: val.max_results,
10212
11011
  search_domain_filter: val.search_domain_filter.map(|v| v.into_iter().collect()),
10213
11012
  country: val.country,
11013
+ ..Default::default()
10214
11014
  }
10215
11015
  }
10216
11016
  }
@@ -10272,6 +11072,7 @@ impl From<liter_llm::types::SearchResult> for SearchResult {
10272
11072
  }
10273
11073
  }
10274
11074
 
11075
+ #[allow(clippy::needless_update)]
10275
11076
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10276
11077
  impl From<OcrRequest> for liter_llm::types::OcrRequest {
10277
11078
  fn from(val: OcrRequest) -> Self {
@@ -10280,6 +11081,7 @@ impl From<OcrRequest> for liter_llm::types::OcrRequest {
10280
11081
  document: val.document.into(),
10281
11082
  pages: val.pages.map(|v| v.into_iter().collect()),
10282
11083
  include_image_base64: val.include_image_base64,
11084
+ ..Default::default()
10283
11085
  }
10284
11086
  }
10285
11087
  }
@@ -10382,12 +11184,14 @@ impl From<liter_llm::types::PageDimensions> for PageDimensions {
10382
11184
  }
10383
11185
  }
10384
11186
 
11187
+ #[allow(clippy::needless_update)]
10385
11188
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10386
11189
  impl From<ModelsListResponse> for liter_llm::types::ModelsListResponse {
10387
11190
  fn from(val: ModelsListResponse) -> Self {
10388
11191
  Self {
10389
11192
  object: val.object,
10390
11193
  data: val.data.into_iter().map(Into::into).collect(),
11194
+ ..Default::default()
10391
11195
  }
10392
11196
  }
10393
11197
  }
@@ -10402,6 +11206,7 @@ impl From<liter_llm::types::ModelsListResponse> for ModelsListResponse {
10402
11206
  }
10403
11207
  }
10404
11208
 
11209
+ #[allow(clippy::needless_update)]
10405
11210
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10406
11211
  impl From<ModelObject> for liter_llm::types::ModelObject {
10407
11212
  fn from(val: ModelObject) -> Self {
@@ -10410,6 +11215,7 @@ impl From<ModelObject> for liter_llm::types::ModelObject {
10410
11215
  object: val.object,
10411
11216
  created: val.created,
10412
11217
  owned_by: val.owned_by,
11218
+ ..Default::default()
10413
11219
  }
10414
11220
  }
10415
11221
  }
@@ -10426,6 +11232,7 @@ impl From<liter_llm::types::ModelObject> for ModelObject {
10426
11232
  }
10427
11233
  }
10428
11234
 
11235
+ #[allow(clippy::needless_update)]
10429
11236
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10430
11237
  impl From<CreateFileRequest> for liter_llm::types::CreateFileRequest {
10431
11238
  fn from(val: CreateFileRequest) -> Self {
@@ -10433,6 +11240,7 @@ impl From<CreateFileRequest> for liter_llm::types::CreateFileRequest {
10433
11240
  file: val.file,
10434
11241
  purpose: val.purpose.into(),
10435
11242
  filename: val.filename,
11243
+ ..Default::default()
10436
11244
  }
10437
11245
  }
10438
11246
  }
@@ -10448,6 +11256,7 @@ impl From<liter_llm::types::CreateFileRequest> for CreateFileRequest {
10448
11256
  }
10449
11257
  }
10450
11258
 
11259
+ #[allow(clippy::needless_update)]
10451
11260
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10452
11261
  impl From<FileObject> for liter_llm::types::FileObject {
10453
11262
  fn from(val: FileObject) -> Self {
@@ -10459,6 +11268,7 @@ impl From<FileObject> for liter_llm::types::FileObject {
10459
11268
  filename: val.filename,
10460
11269
  purpose: val.purpose,
10461
11270
  status: val.status,
11271
+ ..Default::default()
10462
11272
  }
10463
11273
  }
10464
11274
  }
@@ -10478,6 +11288,7 @@ impl From<liter_llm::types::FileObject> for FileObject {
10478
11288
  }
10479
11289
  }
10480
11290
 
11291
+ #[allow(clippy::needless_update)]
10481
11292
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10482
11293
  impl From<FileListResponse> for liter_llm::types::FileListResponse {
10483
11294
  fn from(val: FileListResponse) -> Self {
@@ -10485,6 +11296,7 @@ impl From<FileListResponse> for liter_llm::types::FileListResponse {
10485
11296
  object: val.object,
10486
11297
  data: val.data.into_iter().map(Into::into).collect(),
10487
11298
  has_more: val.has_more,
11299
+ ..Default::default()
10488
11300
  }
10489
11301
  }
10490
11302
  }
@@ -10500,6 +11312,7 @@ impl From<liter_llm::types::FileListResponse> for FileListResponse {
10500
11312
  }
10501
11313
  }
10502
11314
 
11315
+ #[allow(clippy::needless_update)]
10503
11316
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10504
11317
  impl From<FileListQuery> for liter_llm::types::FileListQuery {
10505
11318
  fn from(val: FileListQuery) -> Self {
@@ -10507,6 +11320,7 @@ impl From<FileListQuery> for liter_llm::types::FileListQuery {
10507
11320
  purpose: val.purpose,
10508
11321
  limit: val.limit,
10509
11322
  after: val.after,
11323
+ ..Default::default()
10510
11324
  }
10511
11325
  }
10512
11326
  }
@@ -10522,6 +11336,7 @@ impl From<liter_llm::types::FileListQuery> for FileListQuery {
10522
11336
  }
10523
11337
  }
10524
11338
 
11339
+ #[allow(clippy::needless_update)]
10525
11340
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10526
11341
  impl From<DeleteResponse> for liter_llm::types::DeleteResponse {
10527
11342
  fn from(val: DeleteResponse) -> Self {
@@ -10529,6 +11344,7 @@ impl From<DeleteResponse> for liter_llm::types::DeleteResponse {
10529
11344
  id: val.id,
10530
11345
  object: val.object,
10531
11346
  deleted: val.deleted,
11347
+ ..Default::default()
10532
11348
  }
10533
11349
  }
10534
11350
  }
@@ -10544,6 +11360,7 @@ impl From<liter_llm::types::DeleteResponse> for DeleteResponse {
10544
11360
  }
10545
11361
  }
10546
11362
 
11363
+ #[allow(clippy::needless_update)]
10547
11364
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10548
11365
  impl From<CreateBatchRequest> for liter_llm::types::CreateBatchRequest {
10549
11366
  fn from(val: CreateBatchRequest) -> Self {
@@ -10552,6 +11369,7 @@ impl From<CreateBatchRequest> for liter_llm::types::CreateBatchRequest {
10552
11369
  endpoint: val.endpoint,
10553
11370
  completion_window: val.completion_window,
10554
11371
  metadata: val.metadata.as_ref().and_then(|s| serde_json::from_str(s).ok()),
11372
+ ..Default::default()
10555
11373
  }
10556
11374
  }
10557
11375
  }
@@ -10568,6 +11386,7 @@ impl From<liter_llm::types::CreateBatchRequest> for CreateBatchRequest {
10568
11386
  }
10569
11387
  }
10570
11388
 
11389
+ #[allow(clippy::needless_update)]
10571
11390
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10572
11391
  impl From<BatchObject> for liter_llm::types::BatchObject {
10573
11392
  fn from(val: BatchObject) -> Self {
@@ -10586,6 +11405,7 @@ impl From<BatchObject> for liter_llm::types::BatchObject {
10586
11405
  expired_at: val.expired_at,
10587
11406
  request_counts: val.request_counts.map(Into::into),
10588
11407
  metadata: val.metadata.as_ref().and_then(|s| serde_json::from_str(s).ok()),
11408
+ ..Default::default()
10589
11409
  }
10590
11410
  }
10591
11411
  }
@@ -10612,6 +11432,7 @@ impl From<liter_llm::types::BatchObject> for BatchObject {
10612
11432
  }
10613
11433
  }
10614
11434
 
11435
+ #[allow(clippy::needless_update)]
10615
11436
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10616
11437
  impl From<BatchRequestCounts> for liter_llm::types::BatchRequestCounts {
10617
11438
  fn from(val: BatchRequestCounts) -> Self {
@@ -10619,6 +11440,7 @@ impl From<BatchRequestCounts> for liter_llm::types::BatchRequestCounts {
10619
11440
  total: val.total,
10620
11441
  completed: val.completed,
10621
11442
  failed: val.failed,
11443
+ ..Default::default()
10622
11444
  }
10623
11445
  }
10624
11446
  }
@@ -10634,6 +11456,7 @@ impl From<liter_llm::types::BatchRequestCounts> for BatchRequestCounts {
10634
11456
  }
10635
11457
  }
10636
11458
 
11459
+ #[allow(clippy::needless_update)]
10637
11460
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10638
11461
  impl From<BatchListResponse> for liter_llm::types::BatchListResponse {
10639
11462
  fn from(val: BatchListResponse) -> Self {
@@ -10643,6 +11466,7 @@ impl From<BatchListResponse> for liter_llm::types::BatchListResponse {
10643
11466
  has_more: val.has_more,
10644
11467
  first_id: val.first_id,
10645
11468
  last_id: val.last_id,
11469
+ ..Default::default()
10646
11470
  }
10647
11471
  }
10648
11472
  }
@@ -10660,12 +11484,14 @@ impl From<liter_llm::types::BatchListResponse> for BatchListResponse {
10660
11484
  }
10661
11485
  }
10662
11486
 
11487
+ #[allow(clippy::needless_update)]
10663
11488
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10664
11489
  impl From<BatchListQuery> for liter_llm::types::BatchListQuery {
10665
11490
  fn from(val: BatchListQuery) -> Self {
10666
11491
  Self {
10667
11492
  limit: val.limit,
10668
11493
  after: val.after,
11494
+ ..Default::default()
10669
11495
  }
10670
11496
  }
10671
11497
  }
@@ -10680,6 +11506,7 @@ impl From<liter_llm::types::BatchListQuery> for BatchListQuery {
10680
11506
  }
10681
11507
  }
10682
11508
 
11509
+ #[allow(clippy::needless_update)]
10683
11510
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10684
11511
  impl From<CreateResponseRequest> for liter_llm::types::CreateResponseRequest {
10685
11512
  fn from(val: CreateResponseRequest) -> Self {
@@ -10691,6 +11518,7 @@ impl From<CreateResponseRequest> for liter_llm::types::CreateResponseRequest {
10691
11518
  temperature: val.temperature,
10692
11519
  max_output_tokens: val.max_output_tokens,
10693
11520
  metadata: val.metadata.as_ref().and_then(|s| serde_json::from_str(s).ok()),
11521
+ ..Default::default()
10694
11522
  }
10695
11523
  }
10696
11524
  }
@@ -10710,12 +11538,14 @@ impl From<liter_llm::types::CreateResponseRequest> for CreateResponseRequest {
10710
11538
  }
10711
11539
  }
10712
11540
 
11541
+ #[allow(clippy::needless_update)]
10713
11542
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10714
11543
  impl From<ResponseTool> for liter_llm::types::ResponseTool {
10715
11544
  fn from(val: ResponseTool) -> Self {
10716
11545
  Self {
10717
11546
  tool_type: val.tool_type,
10718
11547
  config: serde_json::from_str(&val.config).unwrap_or_default(),
11548
+ ..Default::default()
10719
11549
  }
10720
11550
  }
10721
11551
  }
@@ -10730,6 +11560,7 @@ impl From<liter_llm::types::ResponseTool> for ResponseTool {
10730
11560
  }
10731
11561
  }
10732
11562
 
11563
+ #[allow(clippy::needless_update)]
10733
11564
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10734
11565
  impl From<ResponseObject> for liter_llm::types::ResponseObject {
10735
11566
  fn from(val: ResponseObject) -> Self {
@@ -10742,6 +11573,7 @@ impl From<ResponseObject> for liter_llm::types::ResponseObject {
10742
11573
  output: val.output.into_iter().map(Into::into).collect(),
10743
11574
  usage: val.usage.map(Into::into),
10744
11575
  error: val.error.as_ref().and_then(|s| serde_json::from_str(s).ok()),
11576
+ ..Default::default()
10745
11577
  }
10746
11578
  }
10747
11579
  }
@@ -10762,12 +11594,14 @@ impl From<liter_llm::types::ResponseObject> for ResponseObject {
10762
11594
  }
10763
11595
  }
10764
11596
 
11597
+ #[allow(clippy::needless_update)]
10765
11598
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10766
11599
  impl From<ResponseOutputItem> for liter_llm::types::ResponseOutputItem {
10767
11600
  fn from(val: ResponseOutputItem) -> Self {
10768
11601
  Self {
10769
11602
  item_type: val.item_type,
10770
11603
  content: serde_json::from_str(&val.content).unwrap_or_default(),
11604
+ ..Default::default()
10771
11605
  }
10772
11606
  }
10773
11607
  }
@@ -10782,6 +11616,7 @@ impl From<liter_llm::types::ResponseOutputItem> for ResponseOutputItem {
10782
11616
  }
10783
11617
  }
10784
11618
 
11619
+ #[allow(clippy::needless_update)]
10785
11620
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10786
11621
  impl From<ResponseUsage> for liter_llm::types::ResponseUsage {
10787
11622
  fn from(val: ResponseUsage) -> Self {
@@ -10789,6 +11624,7 @@ impl From<ResponseUsage> for liter_llm::types::ResponseUsage {
10789
11624
  input_tokens: val.input_tokens,
10790
11625
  output_tokens: val.output_tokens,
10791
11626
  total_tokens: val.total_tokens,
11627
+ ..Default::default()
10792
11628
  }
10793
11629
  }
10794
11630
  }
@@ -10804,6 +11640,7 @@ impl From<liter_llm::types::ResponseUsage> for ResponseUsage {
10804
11640
  }
10805
11641
  }
10806
11642
 
11643
+ #[allow(clippy::needless_update)]
10807
11644
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10808
11645
  impl From<WaitForBatchConfig> for liter_llm::client::WaitForBatchConfig {
10809
11646
  fn from(val: WaitForBatchConfig) -> Self {
@@ -10812,6 +11649,7 @@ impl From<WaitForBatchConfig> for liter_llm::client::WaitForBatchConfig {
10812
11649
  max_interval_secs: val.max_interval_secs,
10813
11650
  backoff_multiplier: val.backoff_multiplier,
10814
11651
  timeout_secs: val.timeout_secs,
11652
+ ..Default::default()
10815
11653
  }
10816
11654
  }
10817
11655
  }
@@ -10852,6 +11690,7 @@ impl From<liter_llm::provider::custom::CustomProviderConfig> for CustomProviderC
10852
11690
  }
10853
11691
  }
10854
11692
 
11693
+ #[allow(clippy::needless_update)]
10855
11694
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10856
11695
  impl From<ProviderCapabilities> for liter_llm::provider::ProviderCapabilities {
10857
11696
  fn from(val: ProviderCapabilities) -> Self {
@@ -10863,6 +11702,7 @@ impl From<ProviderCapabilities> for liter_llm::provider::ProviderCapabilities {
10863
11702
  audio_in: val.audio_in,
10864
11703
  audio_out: val.audio_out,
10865
11704
  video_in: val.video_in,
11705
+ ..Default::default()
10866
11706
  }
10867
11707
  }
10868
11708
  }
@@ -10936,6 +11776,97 @@ impl From<liter_llm::provider::AuthConfig> for AuthConfig {
10936
11776
  }
10937
11777
  }
10938
11778
 
11779
+ #[allow(clippy::needless_update)]
11780
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
11781
+ impl From<ModelInfo> for liter_llm::ModelInfo {
11782
+ fn from(val: ModelInfo) -> Self {
11783
+ Self {
11784
+ input_cost_per_token: val.input_cost_per_token,
11785
+ output_cost_per_token: val.output_cost_per_token,
11786
+ cache_read_input_token_cost: val.cache_read_input_token_cost,
11787
+ cache_creation_input_token_cost: val.cache_creation_input_token_cost,
11788
+ input_cost_per_audio_token: val.input_cost_per_audio_token,
11789
+ output_cost_per_audio_token: val.output_cost_per_audio_token,
11790
+ output_cost_per_reasoning_token: val.output_cost_per_reasoning_token,
11791
+ max_tokens: val.max_tokens,
11792
+ max_input_tokens: val.max_input_tokens,
11793
+ max_output_tokens: val.max_output_tokens,
11794
+ mode: val.mode,
11795
+ supports_vision: val.supports_vision,
11796
+ supports_function_calling: val.supports_function_calling,
11797
+ supports_reasoning: val.supports_reasoning,
11798
+ supports_structured_output: val.supports_structured_output,
11799
+ supports_audio_input: val.supports_audio_input,
11800
+ supports_audio_output: val.supports_audio_output,
11801
+ supports_prompt_caching: val.supports_prompt_caching,
11802
+ tiers: val.tiers.into_iter().map(Into::into).collect(),
11803
+ ..Default::default()
11804
+ }
11805
+ }
11806
+ }
11807
+
11808
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
11809
+ impl From<liter_llm::ModelInfo> for ModelInfo {
11810
+ fn from(val: liter_llm::ModelInfo) -> Self {
11811
+ Self {
11812
+ input_cost_per_token: val.input_cost_per_token,
11813
+ output_cost_per_token: val.output_cost_per_token,
11814
+ cache_read_input_token_cost: val.cache_read_input_token_cost,
11815
+ cache_creation_input_token_cost: val.cache_creation_input_token_cost,
11816
+ input_cost_per_audio_token: val.input_cost_per_audio_token,
11817
+ output_cost_per_audio_token: val.output_cost_per_audio_token,
11818
+ output_cost_per_reasoning_token: val.output_cost_per_reasoning_token,
11819
+ max_tokens: val.max_tokens,
11820
+ max_input_tokens: val.max_input_tokens,
11821
+ max_output_tokens: val.max_output_tokens,
11822
+ mode: val.mode.map(|v| v.to_string()),
11823
+ supports_vision: val.supports_vision,
11824
+ supports_function_calling: val.supports_function_calling,
11825
+ supports_reasoning: val.supports_reasoning,
11826
+ supports_structured_output: val.supports_structured_output,
11827
+ supports_audio_input: val.supports_audio_input,
11828
+ supports_audio_output: val.supports_audio_output,
11829
+ supports_prompt_caching: val.supports_prompt_caching,
11830
+ tiers: val.tiers.into_iter().map(Into::into).collect(),
11831
+ }
11832
+ }
11833
+ }
11834
+
11835
+ #[allow(clippy::needless_update)]
11836
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
11837
+ impl From<ModelTier> for liter_llm::ModelTier {
11838
+ fn from(val: ModelTier) -> Self {
11839
+ Self {
11840
+ min_context_tokens: val.min_context_tokens,
11841
+ input_cost_per_token: val.input_cost_per_token,
11842
+ output_cost_per_token: val.output_cost_per_token,
11843
+ cache_read_input_token_cost: val.cache_read_input_token_cost,
11844
+ cache_creation_input_token_cost: val.cache_creation_input_token_cost,
11845
+ input_cost_per_audio_token: val.input_cost_per_audio_token,
11846
+ output_cost_per_audio_token: val.output_cost_per_audio_token,
11847
+ output_cost_per_reasoning_token: val.output_cost_per_reasoning_token,
11848
+ ..Default::default()
11849
+ }
11850
+ }
11851
+ }
11852
+
11853
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
11854
+ impl From<liter_llm::ModelTier> for ModelTier {
11855
+ fn from(val: liter_llm::ModelTier) -> Self {
11856
+ Self {
11857
+ min_context_tokens: val.min_context_tokens,
11858
+ input_cost_per_token: val.input_cost_per_token,
11859
+ output_cost_per_token: val.output_cost_per_token,
11860
+ cache_read_input_token_cost: val.cache_read_input_token_cost,
11861
+ cache_creation_input_token_cost: val.cache_creation_input_token_cost,
11862
+ input_cost_per_audio_token: val.input_cost_per_audio_token,
11863
+ output_cost_per_audio_token: val.output_cost_per_audio_token,
11864
+ output_cost_per_reasoning_token: val.output_cost_per_reasoning_token,
11865
+ }
11866
+ }
11867
+ }
11868
+
11869
+ #[allow(clippy::needless_update)]
10939
11870
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10940
11871
  impl From<BudgetConfig> for liter_llm::BudgetConfig {
10941
11872
  fn from(val: BudgetConfig) -> Self {
@@ -10943,6 +11874,7 @@ impl From<BudgetConfig> for liter_llm::BudgetConfig {
10943
11874
  global_limit: val.global_limit,
10944
11875
  model_limits: val.model_limits.into_iter().collect(),
10945
11876
  enforcement: val.enforcement.into(),
11877
+ ..Default::default()
10946
11878
  }
10947
11879
  }
10948
11880
  }
@@ -10958,6 +11890,31 @@ impl From<liter_llm::BudgetConfig> for BudgetConfig {
10958
11890
  }
10959
11891
  }
10960
11892
 
11893
+ #[allow(clippy::needless_update)]
11894
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
11895
+ impl From<CacheConfig> for liter_llm::CacheConfig {
11896
+ fn from(val: CacheConfig) -> Self {
11897
+ Self {
11898
+ max_entries: val.max_entries,
11899
+ ttl: std::time::Duration::from_millis(val.ttl),
11900
+ backend: val.backend.into(),
11901
+ ..Default::default()
11902
+ }
11903
+ }
11904
+ }
11905
+
11906
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
11907
+ impl From<liter_llm::CacheConfig> for CacheConfig {
11908
+ fn from(val: liter_llm::CacheConfig) -> Self {
11909
+ Self {
11910
+ max_entries: val.max_entries,
11911
+ ttl: val.ttl.as_millis() as u64,
11912
+ backend: val.backend.into(),
11913
+ }
11914
+ }
11915
+ }
11916
+
11917
+ #[allow(clippy::needless_update)]
10961
11918
  #[allow(clippy::redundant_closure, clippy::useless_conversion)]
10962
11919
  impl From<RateLimitConfig> for liter_llm::RateLimitConfig {
10963
11920
  fn from(val: RateLimitConfig) -> Self {
@@ -10965,6 +11922,7 @@ impl From<RateLimitConfig> for liter_llm::RateLimitConfig {
10965
11922
  rpm: val.rpm,
10966
11923
  tpm: val.tpm,
10967
11924
  window: std::time::Duration::from_millis(val.window),
11925
+ ..Default::default()
10968
11926
  }
10969
11927
  }
10970
11928
  }
@@ -10991,6 +11949,32 @@ impl From<liter_llm::tower::IntentPrototype> for IntentPrototype {
10991
11949
  }
10992
11950
  }
10993
11951
 
11952
+ #[allow(clippy::needless_update)]
11953
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
11954
+ impl From<CatalogRefreshConfig> for liter_llm::cost::refresh::CatalogRefreshConfig {
11955
+ fn from(val: CatalogRefreshConfig) -> Self {
11956
+ Self {
11957
+ enabled: val.enabled,
11958
+ source_url: val.source_url,
11959
+ ttl_seconds: val.ttl_seconds,
11960
+ cache_path: val.cache_path,
11961
+ ..Default::default()
11962
+ }
11963
+ }
11964
+ }
11965
+
11966
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
11967
+ impl From<liter_llm::cost::refresh::CatalogRefreshConfig> for CatalogRefreshConfig {
11968
+ fn from(val: liter_llm::cost::refresh::CatalogRefreshConfig) -> Self {
11969
+ Self {
11970
+ enabled: val.enabled,
11971
+ source_url: val.source_url.to_string(),
11972
+ ttl_seconds: val.ttl_seconds,
11973
+ cache_path: val.cache_path.map(|v| v.to_string()),
11974
+ }
11975
+ }
11976
+ }
11977
+
10994
11978
  impl From<Message> for liter_llm::types::Message {
10995
11979
  fn from(val: Message) -> Self {
10996
11980
  match val {
@@ -11514,6 +12498,30 @@ impl From<liter_llm::Enforcement> for Enforcement {
11514
12498
  }
11515
12499
  }
11516
12500
 
12501
+ impl From<CacheBackend> for liter_llm::CacheBackend {
12502
+ fn from(val: CacheBackend) -> Self {
12503
+ match val {
12504
+ CacheBackend::Memory => Self::Memory,
12505
+ CacheBackend::OpenDal { scheme, config } => Self::OpenDal {
12506
+ scheme: scheme,
12507
+ config: serde_json::from_str(&config).unwrap_or_default(),
12508
+ },
12509
+ }
12510
+ }
12511
+ }
12512
+
12513
+ impl From<liter_llm::CacheBackend> for CacheBackend {
12514
+ fn from(val: liter_llm::CacheBackend) -> Self {
12515
+ match val {
12516
+ liter_llm::CacheBackend::Memory => Self::Memory,
12517
+ liter_llm::CacheBackend::OpenDal { scheme, config } => Self::OpenDal {
12518
+ scheme: scheme.to_string(),
12519
+ config: serde_json::to_string(&config).unwrap_or_default(),
12520
+ },
12521
+ }
12522
+ }
12523
+ }
12524
+
11517
12525
  impl From<liter_llm::tower::CircuitState> for CircuitState {
11518
12526
  fn from(val: liter_llm::tower::CircuitState) -> Self {
11519
12527
  match val {
@@ -11533,6 +12541,26 @@ impl From<liter_llm::tower::HealthStatus> for HealthStatus {
11533
12541
  }
11534
12542
  }
11535
12543
 
12544
+ impl From<RefreshOutcome> for liter_llm::cost::refresh::RefreshOutcome {
12545
+ fn from(val: RefreshOutcome) -> Self {
12546
+ match val {
12547
+ RefreshOutcome::Disabled => Self::Disabled,
12548
+ RefreshOutcome::FromCache => Self::FromCache,
12549
+ RefreshOutcome::Fetched => Self::Fetched,
12550
+ }
12551
+ }
12552
+ }
12553
+
12554
+ impl From<liter_llm::cost::refresh::RefreshOutcome> for RefreshOutcome {
12555
+ fn from(val: liter_llm::cost::refresh::RefreshOutcome) -> Self {
12556
+ match val {
12557
+ liter_llm::cost::refresh::RefreshOutcome::Disabled => Self::Disabled,
12558
+ liter_llm::cost::refresh::RefreshOutcome::FromCache => Self::FromCache,
12559
+ liter_llm::cost::refresh::RefreshOutcome::Fetched => Self::Fetched,
12560
+ }
12561
+ }
12562
+ }
12563
+
11536
12564
  /// Convert a `liter_llm::error::LiterLlmError` error to a Magnus runtime error.
11537
12565
  #[allow(dead_code)]
11538
12566
  fn liter_llm_error_to_magnus_err(e: liter_llm::error::LiterLlmError) -> magnus::Error {
@@ -11573,6 +12601,13 @@ impl LiterLlmErrorInfo {
11573
12601
  }
11574
12602
  }
11575
12603
 
12604
+ /// Convert a `liter_llm::cost::refresh::CatalogRefreshError` error to a Magnus runtime error.
12605
+ #[allow(dead_code)]
12606
+ fn catalog_refresh_error_to_magnus_err(e: liter_llm::cost::refresh::CatalogRefreshError) -> magnus::Error {
12607
+ let msg = e.to_string();
12608
+ magnus::Error::new(unsafe { magnus::Ruby::get_unchecked() }.exception_runtime_error(), msg)
12609
+ }
12610
+
11576
12611
  #[derive(Clone)]
11577
12612
  #[magnus::wrap(class = "LiterLlm::ChatStreamIterator")]
11578
12613
  pub struct ChatStreamIterator {
@@ -11719,10 +12754,14 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
11719
12754
 
11720
12755
  class.define_method("function_call", method!(AssistantMessage::function_call, 0))?;
11721
12756
 
12757
+ class.define_method("reasoning_content", method!(AssistantMessage::reasoning_content, 0))?;
12758
+
11722
12759
  class.define_method("text", method!(AssistantMessage::text, 0))?;
11723
12760
 
11724
12761
  class.define_method("refusal_text", method!(AssistantMessage::refusal_text, 0))?;
11725
12762
 
12763
+ class.define_method("reasoning_text", method!(AssistantMessage::reasoning_text, 0))?;
12764
+
11726
12765
  class.define_method("output_images", method!(AssistantMessage::output_images, 0))?;
11727
12766
 
11728
12767
  class.define_method("output_audio", method!(AssistantMessage::output_audio, 0))?;
@@ -11981,6 +13020,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
11981
13020
 
11982
13021
  class.define_method("refusal", method!(StreamDelta::refusal, 0))?;
11983
13022
 
13023
+ class.define_method("reasoning_content", method!(StreamDelta::reasoning_content, 0))?;
13024
+
11984
13025
  class.define_method("to_s", method!(StreamDelta::to_s, 0))?;
11985
13026
 
11986
13027
  let class = module.define_class("StreamToolCall", ruby.class_object())?;
@@ -12723,6 +13764,107 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
12723
13764
 
12724
13765
  class.define_method("env_var", method!(AuthConfig::env_var, 0))?;
12725
13766
 
13767
+ let class = module.define_class("ModelInfo", ruby.class_object())?;
13768
+
13769
+ class.define_singleton_method("new", function!(ModelInfo::new, -1))?;
13770
+
13771
+ class.define_method("input_cost_per_token", method!(ModelInfo::input_cost_per_token, 0))?;
13772
+
13773
+ class.define_method("output_cost_per_token", method!(ModelInfo::output_cost_per_token, 0))?;
13774
+
13775
+ class.define_method(
13776
+ "cache_read_input_token_cost",
13777
+ method!(ModelInfo::cache_read_input_token_cost, 0),
13778
+ )?;
13779
+
13780
+ class.define_method(
13781
+ "cache_creation_input_token_cost",
13782
+ method!(ModelInfo::cache_creation_input_token_cost, 0),
13783
+ )?;
13784
+
13785
+ class.define_method(
13786
+ "input_cost_per_audio_token",
13787
+ method!(ModelInfo::input_cost_per_audio_token, 0),
13788
+ )?;
13789
+
13790
+ class.define_method(
13791
+ "output_cost_per_audio_token",
13792
+ method!(ModelInfo::output_cost_per_audio_token, 0),
13793
+ )?;
13794
+
13795
+ class.define_method(
13796
+ "output_cost_per_reasoning_token",
13797
+ method!(ModelInfo::output_cost_per_reasoning_token, 0),
13798
+ )?;
13799
+
13800
+ class.define_method("max_tokens", method!(ModelInfo::max_tokens, 0))?;
13801
+
13802
+ class.define_method("max_input_tokens", method!(ModelInfo::max_input_tokens, 0))?;
13803
+
13804
+ class.define_method("max_output_tokens", method!(ModelInfo::max_output_tokens, 0))?;
13805
+
13806
+ class.define_method("mode", method!(ModelInfo::mode, 0))?;
13807
+
13808
+ class.define_method("supports_vision", method!(ModelInfo::supports_vision, 0))?;
13809
+
13810
+ class.define_method(
13811
+ "supports_function_calling",
13812
+ method!(ModelInfo::supports_function_calling, 0),
13813
+ )?;
13814
+
13815
+ class.define_method("supports_reasoning", method!(ModelInfo::supports_reasoning, 0))?;
13816
+
13817
+ class.define_method(
13818
+ "supports_structured_output",
13819
+ method!(ModelInfo::supports_structured_output, 0),
13820
+ )?;
13821
+
13822
+ class.define_method("supports_audio_input", method!(ModelInfo::supports_audio_input, 0))?;
13823
+
13824
+ class.define_method("supports_audio_output", method!(ModelInfo::supports_audio_output, 0))?;
13825
+
13826
+ class.define_method(
13827
+ "supports_prompt_caching",
13828
+ method!(ModelInfo::supports_prompt_caching, 0),
13829
+ )?;
13830
+
13831
+ class.define_method("tiers", method!(ModelInfo::tiers, 0))?;
13832
+
13833
+ let class = module.define_class("ModelTier", ruby.class_object())?;
13834
+
13835
+ class.define_singleton_method("new", function!(ModelTier::new, -1))?;
13836
+
13837
+ class.define_method("min_context_tokens", method!(ModelTier::min_context_tokens, 0))?;
13838
+
13839
+ class.define_method("input_cost_per_token", method!(ModelTier::input_cost_per_token, 0))?;
13840
+
13841
+ class.define_method("output_cost_per_token", method!(ModelTier::output_cost_per_token, 0))?;
13842
+
13843
+ class.define_method(
13844
+ "cache_read_input_token_cost",
13845
+ method!(ModelTier::cache_read_input_token_cost, 0),
13846
+ )?;
13847
+
13848
+ class.define_method(
13849
+ "cache_creation_input_token_cost",
13850
+ method!(ModelTier::cache_creation_input_token_cost, 0),
13851
+ )?;
13852
+
13853
+ class.define_method(
13854
+ "input_cost_per_audio_token",
13855
+ method!(ModelTier::input_cost_per_audio_token, 0),
13856
+ )?;
13857
+
13858
+ class.define_method(
13859
+ "output_cost_per_audio_token",
13860
+ method!(ModelTier::output_cost_per_audio_token, 0),
13861
+ )?;
13862
+
13863
+ class.define_method(
13864
+ "output_cost_per_reasoning_token",
13865
+ method!(ModelTier::output_cost_per_reasoning_token, 0),
13866
+ )?;
13867
+
12726
13868
  let class = module.define_class("BudgetConfig", ruby.class_object())?;
12727
13869
 
12728
13870
  class.define_singleton_method("new", function!(BudgetConfig::new, -1))?;
@@ -12733,6 +13875,16 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
12733
13875
 
12734
13876
  class.define_method("enforcement", method!(BudgetConfig::enforcement, 0))?;
12735
13877
 
13878
+ let class = module.define_class("CacheConfig", ruby.class_object())?;
13879
+
13880
+ class.define_singleton_method("new", function!(CacheConfig::new, -1))?;
13881
+
13882
+ class.define_method("max_entries", method!(CacheConfig::max_entries, 0))?;
13883
+
13884
+ class.define_method("ttl", method!(CacheConfig::ttl, 0))?;
13885
+
13886
+ class.define_method("backend", method!(CacheConfig::backend, 0))?;
13887
+
12736
13888
  let class = module.define_class("SingleflightResult", ruby.class_object())?;
12737
13889
 
12738
13890
  let class = module.define_class("RateLimitConfig", ruby.class_object())?;
@@ -12755,6 +13907,18 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
12755
13907
 
12756
13908
  class.define_method("model", method!(IntentPrototype::model, 0))?;
12757
13909
 
13910
+ let class = module.define_class("CatalogRefreshConfig", ruby.class_object())?;
13911
+
13912
+ class.define_singleton_method("new", function!(CatalogRefreshConfig::new, -1))?;
13913
+
13914
+ class.define_method("enabled", method!(CatalogRefreshConfig::enabled, 0))?;
13915
+
13916
+ class.define_method("source_url", method!(CatalogRefreshConfig::source_url, 0))?;
13917
+
13918
+ class.define_method("ttl_seconds", method!(CatalogRefreshConfig::ttl_seconds, 0))?;
13919
+
13920
+ class.define_method("cache_path", method!(CatalogRefreshConfig::cache_path, 0))?;
13921
+
12758
13922
  let class = module.define_class("RerankDocument", ruby.class_object())?;
12759
13923
 
12760
13924
  class.define_singleton_method("object", function!(RerankDocument::_factory_object, 1))?;
@@ -12786,6 +13950,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
12786
13950
 
12787
13951
  module.define_module_function("completion_cost_with_cache", function!(completion_cost_with_cache, 4))?;
12788
13952
 
13953
+ module.define_module_function("model_info", function!(model_info, 1))?;
13954
+
12789
13955
  module.define_module_function("clear", function!(clear, 0))?;
12790
13956
 
12791
13957
  module.define_module_function("count_tokens", function!(count_tokens, 2))?;
@@ -12796,6 +13962,15 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
12796
13962
 
12797
13963
  module.define_module_function("ensure_crypto_provider", function!(ensure_crypto_provider, 0))?;
12798
13964
 
13965
+ module.define_module_function(
13966
+ "install_catalog_overlay_from_str",
13967
+ function!(install_catalog_overlay_from_str, 1),
13968
+ )?;
13969
+
13970
+ module.define_module_function("clear_catalog_overlay", function!(clear_catalog_overlay, 0))?;
13971
+
13972
+ module.define_module_function("refresh_catalog", function!(refresh_catalog_async, -1))?;
13973
+
12799
13974
  module.define_module_function("chat_stream", function!(chat_stream, 2))?;
12800
13975
 
12801
13976
  let liter_llm_error_info_class = module.define_class("LiterLlmErrorInfo", ruby.class_object())?;