Skip to content

Commit 28e3d0a

Browse files
authored
Parse ints from floats in openai generic (#1746)
The SambaNova provider returns a float for the `"completed"` field of the Completions generic API. This PR makes the Completions parser more flexible, accepting both ints and floats, but always returning ints. I have tested this locally - SambaNova and OpenAI requests now parse correctly. I didn't check in the testing code, because we don't necessarily want to mention lots of providers in our test suite. <!-- ELLIPSIS_HIDDEN --> ---- > [!IMPORTANT] > Enhance `ChatCompletionGeneric` to accept both int and float for `created` field, ensuring consistent int return using `deserialize_float_to_u32`. > > - **Behavior**: > - `ChatCompletionGeneric` now accepts both `int` and `float` for `created` field, always returning `int`. > - Adds `deserialize_float_to_u32` function to handle deserialization of `created` field. > - **Code**: > - Adds `deserialize_float_to_u32` function in `types.rs` to convert floats to integers using `floor()`. > - Updates `ChatCompletionGeneric` struct to use `deserialize_float_to_u32` for `created` field. > > <sup>This description was created by </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=BoundaryML%2Fbaml&utm_source=github&utm_medium=referral)<sup> for 0d334bd. It will automatically update as commits are pushed.</sup> <!-- ELLIPSIS_HIDDEN -->
1 parent b0e79a2 commit 28e3d0a

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

  • engine/baml-runtime/src/internal/llm_client/primitive/openai

engine/baml-runtime/src/internal/llm_client/primitive/openai/types.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use serde::de::{self, Deserializer};
12
use serde::{Deserialize, Serialize};
23

34
pub type CompletionResponse = ChatCompletionGeneric<CompletionChoice>;
@@ -13,6 +14,7 @@ pub struct ChatCompletionGeneric<C> {
1314
/// A list of chat completion choices. Can be more than one if `n` is greater than 1.s
1415
pub choices: Vec<C>,
1516
/// The Unix timestamp (in seconds) of when the chat completion was created.
17+
#[serde(deserialize_with = "deserialize_float_to_u32")]
1618
pub created: Option<u32>,
1719
/// The model used for the chat completion.
1820
pub model: String,
@@ -26,6 +28,24 @@ pub struct ChatCompletionGeneric<C> {
2628
pub usage: Option<CompletionUsage>,
2729
}
2830

31+
fn deserialize_float_to_u32<'de, D>(deserializer: D) -> Result<Option<u32>, D::Error>
32+
where
33+
D: Deserializer<'de>,
34+
{
35+
#[derive(Deserialize)]
36+
#[serde(untagged)]
37+
enum FloatOrInt {
38+
Int(u32),
39+
Float(f64),
40+
}
41+
42+
match Option::<FloatOrInt>::deserialize(deserializer)? {
43+
Some(FloatOrInt::Int(i)) => Ok(Some(i)),
44+
Some(FloatOrInt::Float(f)) => Ok(Some(f.floor() as u32)),
45+
None => Ok(None),
46+
}
47+
}
48+
2949
#[derive(Debug, Deserialize, Clone, PartialEq)]
3050
pub struct CompletionChoice {
3151
pub finish_reason: Option<String>,

0 commit comments

Comments
 (0)