dynamo_async_openai/
chat.rs

1// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3//
4// Based on https://github.com/64bit/async-openai/ by Himanshu Neema
5// Original Copyright (c) 2022 Himanshu Neema
6// Licensed under MIT License (see ATTRIBUTIONS-Rust.md)
7//
8// Modifications Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
9// Licensed under Apache 2.0
10
11use crate::{
12    Client,
13    config::Config,
14    error::OpenAIError,
15    types::{
16        ChatCompletionResponseStream, CreateChatCompletionRequest, CreateChatCompletionResponse,
17    },
18};
19
20/// Given a list of messages comprising a conversation, the model will return a response.
21///
22/// Related guide: [Chat completions](https://platform.openai.com//docs/guides/text-generation)
23pub struct Chat<'c, C: Config> {
24    client: &'c Client<C>,
25}
26
27impl<'c, C: Config> Chat<'c, C> {
28    pub fn new(client: &'c Client<C>) -> Self {
29        Self { client }
30    }
31
32    /// Creates a model response for the given chat conversation. Learn more in
33    /// the
34    ///
35    /// [text generation](https://platform.openai.com/docs/guides/text-generation),
36    /// [vision](https://platform.openai.com/docs/guides/vision),
37    ///
38    /// and [audio](https://platform.openai.com/docs/guides/audio) guides.
39    ///
40    ///
41    /// Parameter support can differ depending on the model used to generate the
42    /// response, particularly for newer reasoning models. Parameters that are
43    /// only supported for reasoning models are noted below. For the current state
44    /// of unsupported parameters in reasoning models,
45    ///
46    /// [refer to the reasoning guide](https://platform.openai.com/docs/guides/reasoning).
47    ///
48    /// byot: You must ensure "stream: false" in serialized `request`
49    #[crate::byot(
50        T0 = serde::Serialize,
51        R = serde::de::DeserializeOwned
52    )]
53    pub async fn create(
54        &self,
55        request: CreateChatCompletionRequest,
56    ) -> Result<CreateChatCompletionResponse, OpenAIError> {
57        #[cfg(not(feature = "byot"))]
58        {
59            if request.stream.is_some() && request.stream.unwrap() {
60                return Err(OpenAIError::InvalidArgument(
61                    "When stream is true, use Chat::create_stream".into(),
62                ));
63            }
64        }
65        self.client.post("/chat/completions", request).await
66    }
67
68    /// Creates a completion for the chat message
69    ///
70    /// partial message deltas will be sent, like in ChatGPT. Tokens will be sent as data-only [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format) as they become available, with the stream terminated by a `data: [DONE]` message.
71    ///
72    /// [ChatCompletionResponseStream] is a parsed SSE stream until a \[DONE\] is received from server.
73    ///
74    /// byot: You must ensure "stream: true" in serialized `request`
75    #[crate::byot(
76        T0 = serde::Serialize,
77        R = serde::de::DeserializeOwned,
78        stream = "true",
79        where_clause = "R: std::marker::Send + 'static"
80    )]
81    #[allow(unused_mut)]
82    pub async fn create_stream(
83        &self,
84        mut request: CreateChatCompletionRequest,
85    ) -> Result<ChatCompletionResponseStream, OpenAIError> {
86        #[cfg(not(feature = "byot"))]
87        {
88            if request.stream.is_some() && !request.stream.unwrap() {
89                return Err(OpenAIError::InvalidArgument(
90                    "When stream is false, use Chat::create".into(),
91                ));
92            }
93
94            request.stream = Some(true);
95        }
96        Ok(self.client.post_stream("/chat/completions", request).await)
97    }
98}