chat_completions.rs 6.35 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

Paul Hendricks's avatar
Paul Hendricks committed
16
17
18
19
use super::nvext::NvExt;
use super::nvext::NvExtProvider;
use super::OpenAISamplingOptionsProvider;
use super::OpenAIStopConditionsProvider;
20
use serde::{Deserialize, Serialize};
Paul Hendricks's avatar
Paul Hendricks committed
21
use triton_distributed_runtime::protocols::annotated::AnnotationsProvider;
22
23
24
25
26
use validator::Validate;

mod aggregator;
mod delta;

Paul Hendricks's avatar
Paul Hendricks committed
27
pub use aggregator::DeltaAggregator;
28
29
pub use delta::DeltaGenerator;

30
31
32
33
34
35
36
/// A request structure for creating a chat completion, extending OpenAI's
/// `CreateChatCompletionRequest` with [`NvExt`] extensions.
///
/// # Fields
/// - `inner`: The base OpenAI chat completion request, embedded using `serde(flatten)`.
/// - `nvext`: The optional NVIDIA extension field. See [`NvExt`] for
///   more details.
Paul Hendricks's avatar
Paul Hendricks committed
37
#[derive(Serialize, Deserialize, Validate, Debug, Clone)]
38
pub struct NvCreateChatCompletionRequest {
Paul Hendricks's avatar
Paul Hendricks committed
39
40
    #[serde(flatten)]
    pub inner: async_openai::types::CreateChatCompletionRequest,
41
42
43
    pub nvext: Option<NvExt>,
}

44
45
46
47
48
49
/// A response structure for unary chat completion responses, embedding OpenAI's
/// `CreateChatCompletionResponse`.
///
/// # Fields
/// - `inner`: The base OpenAI unary chat completion response, embedded
///   using `serde(flatten)`.
Paul Hendricks's avatar
Paul Hendricks committed
50
#[derive(Serialize, Deserialize, Validate, Debug, Clone)]
51
pub struct NvCreateChatCompletionResponse {
Paul Hendricks's avatar
Paul Hendricks committed
52
53
    #[serde(flatten)]
    pub inner: async_openai::types::CreateChatCompletionResponse,
54
55
}

56
57
58
59
60
61
/// A response structure for streamed chat completions, embedding OpenAI's
/// `CreateChatCompletionStreamResponse`.
///
/// # Fields
/// - `inner`: The base OpenAI streaming chat completion response, embedded
///   using `serde(flatten)`.
Paul Hendricks's avatar
Paul Hendricks committed
62
#[derive(Serialize, Deserialize, Validate, Debug, Clone)]
63
pub struct NvCreateChatCompletionStreamResponse {
Paul Hendricks's avatar
Paul Hendricks committed
64
65
    #[serde(flatten)]
    pub inner: async_openai::types::CreateChatCompletionStreamResponse,
66
67
}

68
69
/// Implements `NvExtProvider` for `NvCreateChatCompletionRequest`,
/// providing access to NVIDIA-specific extensions.
70
impl NvExtProvider for NvCreateChatCompletionRequest {
71
    /// Returns a reference to the optional `NvExt` extension, if available.
72
73
74
75
    fn nvext(&self) -> Option<&NvExt> {
        self.nvext.as_ref()
    }

76
    /// Returns `None`, as raw prompt extraction is not implemented.
77
78
79
80
81
    fn raw_prompt(&self) -> Option<String> {
        None
    }
}

82
83
/// Implements `AnnotationsProvider` for `NvCreateChatCompletionRequest`,
/// enabling retrieval and management of request annotations.
84
impl AnnotationsProvider for NvCreateChatCompletionRequest {
85
    /// Retrieves the list of annotations from `NvExt`, if present.
Biswa Panda's avatar
Biswa Panda committed
86
87
88
89
90
91
    fn annotations(&self) -> Option<Vec<String>> {
        self.nvext
            .as_ref()
            .and_then(|nvext| nvext.annotations.clone())
    }

92
93
94
95
96
97
98
    /// Checks whether a specific annotation exists in the request.
    ///
    /// # Arguments
    /// * `annotation` - A string slice representing the annotation to check.
    ///
    /// # Returns
    /// `true` if the annotation exists, `false` otherwise.
Biswa Panda's avatar
Biswa Panda committed
99
100
101
102
103
104
105
106
    fn has_annotation(&self, annotation: &str) -> bool {
        self.nvext
            .as_ref()
            .and_then(|nvext| nvext.annotations.as_ref())
            .map(|annotations| annotations.contains(&annotation.to_string()))
            .unwrap_or(false)
    }
}
107

108
109
/// Implements `OpenAISamplingOptionsProvider` for `NvCreateChatCompletionRequest`,
/// exposing OpenAI's sampling parameters for chat completion.
110
impl OpenAISamplingOptionsProvider for NvCreateChatCompletionRequest {
111
    /// Retrieves the temperature parameter for sampling, if set.
112
    fn get_temperature(&self) -> Option<f32> {
Paul Hendricks's avatar
Paul Hendricks committed
113
        self.inner.temperature
114
115
    }

116
    /// Retrieves the top-p (nucleus sampling) parameter, if set.
117
    fn get_top_p(&self) -> Option<f32> {
Paul Hendricks's avatar
Paul Hendricks committed
118
        self.inner.top_p
119
120
    }

121
    /// Retrieves the frequency penalty parameter, if set.
122
    fn get_frequency_penalty(&self) -> Option<f32> {
Paul Hendricks's avatar
Paul Hendricks committed
123
        self.inner.frequency_penalty
124
125
    }

126
    /// Retrieves the presence penalty parameter, if set.
127
    fn get_presence_penalty(&self) -> Option<f32> {
Paul Hendricks's avatar
Paul Hendricks committed
128
        self.inner.presence_penalty
129
130
    }

131
    /// Returns a reference to the optional `NvExt` extension, if available.
132
133
134
135
136
    fn nvext(&self) -> Option<&NvExt> {
        self.nvext.as_ref()
    }
}

137
138
/// Implements `OpenAIStopConditionsProvider` for `NvCreateChatCompletionRequest`,
/// providing access to stop conditions that control chat completion behavior.
Paul Hendricks's avatar
Paul Hendricks committed
139
#[allow(deprecated)]
140
impl OpenAIStopConditionsProvider for NvCreateChatCompletionRequest {
141
142
143
144
    /// Retrieves the maximum number of tokens allowed in the response.
    ///
    /// # Note
    /// This field is deprecated in favor of `max_completion_tokens`.
Paul Hendricks's avatar
Paul Hendricks committed
145
146
147
    fn get_max_tokens(&self) -> Option<u32> {
        // ALLOW: max_tokens is deprecated in favor of max_completion_tokens
        self.inner.max_tokens
148
149
    }

150
151
152
153
154
    /// Retrieves the minimum number of tokens required in the response.
    ///
    /// # Note
    /// This method is currently a placeholder and always returns `None`
    /// since `min_tokens` is not an OpenAI-supported parameter.
Paul Hendricks's avatar
Paul Hendricks committed
155
156
    fn get_min_tokens(&self) -> Option<u32> {
        None
157
158
    }

159
160
161
162
163
164
165
    /// Retrieves the stop conditions that terminate the chat completion response.
    ///
    /// Converts OpenAI's `Stop` enum to a `Vec<String>`, normalizing the representation.
    ///
    /// # Returns
    /// * `Some(Vec<String>)` if stop conditions are set.
    /// * `None` if no stop conditions are defined.
166
    fn get_stop(&self) -> Option<Vec<String>> {
167
168
169
170
        self.inner.stop.as_ref().map(|stop| match stop {
            async_openai::types::Stop::String(s) => vec![s.clone()],
            async_openai::types::Stop::StringArray(arr) => arr.clone(),
        })
171
172
    }

173
    /// Returns a reference to the optional `NvExt` extension, if available.
174
175
176
177
    fn nvext(&self) -> Option<&NvExt> {
        self.nvext.as_ref()
    }
}