Unverified Commit b6a3b0c6 authored by ishandhanani's avatar ishandhanani Committed by GitHub
Browse files

refactor(2/3): rename dynamo-async-openai to dynamo-protocols (#7565)

parent c84c0934
......@@ -3,9 +3,7 @@
use std::collections::BTreeMap;
use dynamo_async_openai::types::{
ChatCompletionTool, ChatCompletionToolChoiceOption, FunctionObject,
};
use dynamo_protocols::types::{ChatCompletionTool, ChatCompletionToolChoiceOption, FunctionObject};
use serde_json::{Value, json};
use thiserror::Error;
......@@ -267,7 +265,7 @@ fn merge_defs(
#[cfg(test)]
mod tests {
use super::*;
use dynamo_async_openai::types::{ChatCompletionToolChoiceOption, ChatCompletionToolType};
use dynamo_protocols::types::{ChatCompletionToolChoiceOption, ChatCompletionToolType};
fn sample_tools() -> Vec<ChatCompletionTool> {
vec![
......@@ -310,9 +308,9 @@ mod tests {
fn named_choice_returns_parameters() {
let tools = sample_tools();
let tool_choice = ChatCompletionToolChoiceOption::Named(
dynamo_async_openai::types::ChatCompletionNamedToolChoice {
dynamo_protocols::types::ChatCompletionNamedToolChoice {
r#type: ChatCompletionToolType::Function,
function: dynamo_async_openai::types::FunctionName {
function: dynamo_protocols::types::FunctionName {
name: "get_weather".to_string(),
},
},
......@@ -358,9 +356,9 @@ mod tests {
fn missing_tool_errors() {
let tools = sample_tools();
let tool_choice = ChatCompletionToolChoiceOption::Named(
dynamo_async_openai::types::ChatCompletionNamedToolChoice {
dynamo_protocols::types::ChatCompletionNamedToolChoice {
r#type: ChatCompletionToolType::Function,
function: dynamo_async_openai::types::FunctionName {
function: dynamo_protocols::types::FunctionName {
name: "unknown".to_string(),
},
},
......
......@@ -119,9 +119,9 @@ pub fn validate_no_unsupported_fields(
///
/// `{"type":"text"}` is accepted and means no structured constraint.
pub fn validate_response_format(
response_format: &Option<dynamo_async_openai::types::ResponseFormat>,
response_format: &Option<dynamo_protocols::types::ResponseFormat>,
) -> Result<(), anyhow::Error> {
use dynamo_async_openai::types::ResponseFormat;
use dynamo_protocols::types::ResponseFormat;
let Some(fmt) = response_format else {
return Ok(());
......@@ -355,15 +355,15 @@ pub fn validate_user(user: Option<&str>) -> Result<(), anyhow::Error> {
}
/// Validates stop sequences
pub fn validate_stop(stop: &Option<dynamo_async_openai::types::Stop>) -> Result<(), anyhow::Error> {
pub fn validate_stop(stop: &Option<dynamo_protocols::types::Stop>) -> Result<(), anyhow::Error> {
if let Some(stop_value) = stop {
match stop_value {
dynamo_async_openai::types::Stop::String(s) => {
dynamo_protocols::types::Stop::String(s) => {
if s.is_empty() {
anyhow::bail!("Stop sequence cannot be empty");
}
}
dynamo_async_openai::types::Stop::StringArray(sequences) => {
dynamo_protocols::types::Stop::StringArray(sequences) => {
if sequences.is_empty() {
anyhow::bail!("Stop sequences array cannot be empty");
}
......@@ -391,7 +391,7 @@ pub fn validate_stop(stop: &Option<dynamo_async_openai::types::Stop>) -> Result<
/// Validates messages array
pub fn validate_messages(
messages: &[dynamo_async_openai::types::ChatCompletionRequestMessage],
messages: &[dynamo_protocols::types::ChatCompletionRequestMessage],
) -> Result<(), anyhow::Error> {
if messages.is_empty() {
anyhow::bail!("Messages array cannot be empty");
......@@ -415,7 +415,7 @@ pub fn validate_top_logprobs(top_logprobs: Option<u8>) -> Result<(), anyhow::Err
/// Validates tools array
pub fn validate_tools(
tools: &Option<&[dynamo_async_openai::types::ChatCompletionTool]>,
tools: &Option<&[dynamo_protocols::types::ChatCompletionTool]>,
) -> Result<(), anyhow::Error> {
let tools = match tools {
Some(val) => val,
......@@ -448,7 +448,7 @@ pub fn validate_tools(
/// Validates reasoning effort parameter
pub fn validate_reasoning_effort(
_reasoning_effort: &Option<dynamo_async_openai::types::ReasoningEffort>,
_reasoning_effort: &Option<dynamo_protocols::types::ReasoningEffort>,
) -> Result<(), anyhow::Error> {
// TODO ADD HERE
// ReasoningEffort is an enum, so if it exists, it's valid by definition
......@@ -458,7 +458,7 @@ pub fn validate_reasoning_effort(
/// Validates service tier parameter
pub fn validate_service_tier(
_service_tier: &Option<dynamo_async_openai::types::ServiceTier>,
_service_tier: &Option<dynamo_protocols::types::ServiceTier>,
) -> Result<(), anyhow::Error> {
// TODO ADD HERE
// ServiceTier is an enum, so if it exists, it's valid by definition
......@@ -471,14 +471,14 @@ pub fn validate_service_tier(
//
/// Validates prompt
pub fn validate_prompt(prompt: &dynamo_async_openai::types::Prompt) -> Result<(), anyhow::Error> {
pub fn validate_prompt(prompt: &dynamo_protocols::types::Prompt) -> Result<(), anyhow::Error> {
match prompt {
dynamo_async_openai::types::Prompt::String(s) => {
dynamo_protocols::types::Prompt::String(s) => {
if s.is_empty() {
anyhow::bail!("Prompt string cannot be empty");
}
}
dynamo_async_openai::types::Prompt::StringArray(arr) => {
dynamo_protocols::types::Prompt::StringArray(arr) => {
if arr.is_empty() {
anyhow::bail!("Prompt string array cannot be empty");
}
......@@ -488,12 +488,12 @@ pub fn validate_prompt(prompt: &dynamo_async_openai::types::Prompt) -> Result<()
}
}
}
dynamo_async_openai::types::Prompt::IntegerArray(arr) => {
dynamo_protocols::types::Prompt::IntegerArray(arr) => {
if arr.is_empty() {
anyhow::bail!("Prompt integer array cannot be empty");
}
}
dynamo_async_openai::types::Prompt::ArrayOfIntegerArray(arr) => {
dynamo_protocols::types::Prompt::ArrayOfIntegerArray(arr) => {
if arr.is_empty() {
anyhow::bail!("Prompt array of integer arrays cannot be empty");
}
......@@ -516,7 +516,7 @@ pub fn validate_prompt(prompt: &dynamo_async_openai::types::Prompt) -> Result<()
///
/// Format for prompt_embeds: PyTorch tensor serialized with torch.save() and base64-encoded
pub fn validate_prompt_or_embeds(
prompt: Option<&dynamo_async_openai::types::Prompt>,
prompt: Option<&dynamo_protocols::types::Prompt>,
prompt_embeds: Option<&str>,
) -> Result<(), anyhow::Error> {
// Check that at least one is provided
......
......@@ -46,7 +46,7 @@ use crate::protocols::openai::{
OpenAIOutputOptionsProvider, OpenAISamplingOptionsProvider, OpenAIStopConditionsProvider,
};
use dynamo_async_openai::types::responses::{IncludeEnum, Reasoning, Truncation};
use dynamo_protocols::types::responses::{IncludeEnum, Reasoning, Truncation};
use super::anthropic::types::{AnthropicCreateMessageRequest, ThinkingConfig};
use super::openai::responses::NvCreateResponse;
......@@ -417,8 +417,8 @@ impl OpenAIStopConditionsProvider for UnifiedRequest {
fn get_stop(&self) -> Option<Vec<String>> {
self.inner.inner.stop.as_ref().map(|stop| match stop {
dynamo_async_openai::types::Stop::String(s) => vec![s.clone()],
dynamo_async_openai::types::Stop::StringArray(arr) => arr.clone(),
dynamo_protocols::types::Stop::String(s) => vec![s.clone()],
dynamo_protocols::types::Stop::StringArray(arr) => arr.clone(),
})
}
......@@ -466,9 +466,7 @@ impl OAIChatLikeRequest for UnifiedRequest {
minijinja::value::Value::from_serialize(&messages_json)
}
fn typed_messages(
&self,
) -> Option<&[dynamo_async_openai::types::ChatCompletionRequestMessage]> {
fn typed_messages(&self) -> Option<&[dynamo_protocols::types::ChatCompletionRequestMessage]> {
Some(self.inner.inner.messages.as_slice())
}
......@@ -535,7 +533,7 @@ mod tests {
#[test]
fn test_chat_completions_roundtrip() {
let req = NvCreateChatCompletionRequest {
inner: dynamo_async_openai::types::CreateChatCompletionRequest {
inner: dynamo_protocols::types::CreateChatCompletionRequest {
model: "test-model".to_string(),
messages: vec![],
..Default::default()
......
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use dynamo_async_openai::types::{
ChatChoiceStream, ChatCompletionMessageContent, ChatCompletionStreamResponseDelta,
CreateChatCompletionStreamResponse, Role,
};
use dynamo_llm::protocols::{
Annotated, ContentProvider, DataStream,
codec::{Message, SseCodecError, create_message_stream},
......@@ -17,6 +13,10 @@ use dynamo_llm::protocols::{
completions::NvCreateCompletionResponse,
},
};
use dynamo_protocols::types::{
ChatChoiceStream, ChatCompletionMessageContent, ChatCompletionStreamResponseDelta,
CreateChatCompletionStreamResponse, Role,
};
use futures::StreamExt;
fn get_text(content: &ChatCompletionMessageContent) -> &str {
......
......@@ -3,7 +3,6 @@
use anyhow::Error;
use async_stream::stream;
use dynamo_async_openai::config::OpenAIConfig;
use dynamo_llm::protocols::{
Annotated,
codec::SseLineCodec,
......@@ -28,6 +27,7 @@ use dynamo_llm::{
},
model_card::ModelDeploymentCard,
};
use dynamo_protocols::config::OpenAIConfig;
use dynamo_runtime::metrics::prometheus_names::{frontend_service, name_prefix};
use dynamo_runtime::{
CancellationToken,
......@@ -318,16 +318,16 @@ async fn test_http_service() {
let client = reqwest::Client::new();
let message = dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content: dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
let message = dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"hi".to_string(),
),
name: None,
},
);
let mut request = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let mut request = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model("foo")
.messages(vec![message])
.build()
......@@ -493,7 +493,7 @@ async fn test_http_service() {
// ==== ChatCompletions / Unary / Error ====
// ==== Completions / Unary / Error ====
let mut request = dynamo_async_openai::types::CreateCompletionRequestArgs::default()
let mut request = dynamo_protocols::types::CreateCompletionRequestArgs::default()
.model("bar")
.prompt("hi")
.build()
......@@ -649,13 +649,12 @@ async fn test_pure_openai_client() {
wait_for_service_ready(port).await;
// Test successful streaming request
let request = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let request = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model("foo")
.messages(vec![
dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content:
dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"Hi".to_string(),
),
name: None,
......@@ -682,13 +681,12 @@ async fn test_pure_openai_client() {
assert!(count > 0, "Should receive at least one response");
// Test error case with invalid model
let request = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let request = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model("bar") // This model will fail
.messages(vec![
dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content:
dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"Hi".to_string(),
),
name: None,
......@@ -716,13 +714,12 @@ async fn test_pure_openai_client() {
// Test context management
let ctx = HttpRequestContext::new();
let request = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let request = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model("foo")
.messages(vec![
dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content:
dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"Hi".to_string(),
),
name: None,
......@@ -761,13 +758,12 @@ async fn test_nv_custom_client() {
wait_for_service_ready(port).await;
// Test successful streaming request
let inner_request = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let inner_request = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model("foo")
.messages(vec![
dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content:
dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"Hi".to_string(),
),
name: None,
......@@ -803,13 +799,12 @@ async fn test_nv_custom_client() {
assert!(count > 0, "Should receive at least one response");
// Test error case with invalid model
let inner_request = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let inner_request = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model("bar") // This model will fail
.messages(vec![
dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content:
dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"Hi".to_string(),
),
name: None,
......@@ -846,13 +841,12 @@ async fn test_nv_custom_client() {
// Test context management
let ctx = HttpRequestContext::new();
let inner_request = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let inner_request = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model("foo")
.messages(vec![
dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content:
dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"Hi".to_string(),
),
name: None,
......@@ -1010,16 +1004,16 @@ async fn test_client_disconnect_cancellation_unary() {
let client = reqwest::Client::new();
let message = dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content: dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
let message = dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"This will take a long time".to_string(),
),
name: None,
},
);
let request = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let request = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model("slow-model")
.messages(vec![message])
.stream(false) // Test unary response
......@@ -1106,16 +1100,16 @@ async fn test_client_disconnect_cancellation_streaming() {
let client = reqwest::Client::new();
let message = dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content: dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
let message = dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"This will stream for a long time".to_string(),
),
name: None,
},
);
let request = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let request = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model("slow-stream-model")
.messages(vec![message])
.stream(true) // Test streaming response
......
......@@ -218,16 +218,16 @@ async fn test_metrics_with_mock_model() {
let client = reqwest::Client::new();
// Create a chat completion request
let message = dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content: dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
let message = dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"Hello, mock model!".to_string(),
),
name: None,
},
);
let request = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let request = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model("mockmodel")
.messages(vec![message])
.max_tokens(50u32)
......@@ -419,16 +419,16 @@ mod integration_tests {
let client = reqwest::Client::new();
// Create a chat completion request
let message = dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content: dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
let message = dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"Hello, MDC model!".to_string(),
),
name: None,
},
);
let request = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let request = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model(model.service_name())
.messages(vec![message])
.max_tokens(50u32)
......
......@@ -62,7 +62,7 @@ pub mod kserve_test {
use tonic::{Request, Response, transport::Channel};
use crate::ports::get_random_port;
use dynamo_async_openai::types::Prompt;
use dynamo_protocols::types::Prompt;
use prost::Message;
struct SplitEngine {}
......
......@@ -10,7 +10,7 @@ use dynamo_llm::perf::logprobs::analyze_logprob_sensitivity;
use dynamo_llm::perf::{RecordedStream, TimestampedResponse};
use dynamo_llm::protocols::openai::chat_completions::NvCreateChatCompletionStreamResponse;
use dynamo_async_openai::types::{
use dynamo_protocols::types::{
ChatChoiceLogprobs, ChatChoiceStream, ChatCompletionMessageContent,
ChatCompletionStreamResponseDelta, ChatCompletionTokenLogprob, FinishReason, Role, TopLogprobs,
};
......@@ -397,7 +397,7 @@ fn create_response_with_linear_probs(
};
NvCreateChatCompletionStreamResponse {
inner: dynamo_async_openai::types::CreateChatCompletionStreamResponse {
inner: dynamo_protocols::types::CreateChatCompletionStreamResponse {
id: "test_id".to_string(),
choices: vec![choice],
created: 1234567890,
......@@ -481,7 +481,7 @@ fn create_multi_choice_response(
.collect();
NvCreateChatCompletionStreamResponse {
inner: dynamo_async_openai::types::CreateChatCompletionStreamResponse {
inner: dynamo_protocols::types::CreateChatCompletionStreamResponse {
id: "test_id".to_string(),
choices,
created: 1234567890,
......
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use dynamo_async_openai::types::CreateCompletionRequestArgs;
use dynamo_llm::protocols::openai::{completions::NvCreateCompletionRequest, validate};
use dynamo_protocols::types::CreateCompletionRequestArgs;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone)]
......@@ -125,10 +125,10 @@ fn build_samples() -> Result<Vec<CompletionSample>, String> {
#[test]
fn test_batch_prompt_utilities() {
use dynamo_async_openai::types::Prompt;
use dynamo_llm::protocols::openai::completions::{
extract_single_prompt, get_prompt_batch_size,
};
use dynamo_protocols::types::Prompt;
// Test single string prompt
let single_string = Prompt::String("Hello, world!".to_string());
......@@ -216,8 +216,8 @@ fn test_total_choices_validation() {
#[test]
fn test_batch_prompt_with_n_parameter() {
use dynamo_async_openai::types::Prompt;
use dynamo_llm::protocols::openai::completions::get_prompt_batch_size;
use dynamo_protocols::types::Prompt;
// Test batch size calculation
let prompt = Prompt::StringArray(vec!["p1".to_string(), "p2".to_string(), "p3".to_string()]);
......@@ -246,10 +246,10 @@ fn test_batch_prompt_with_n_parameter() {
#[test]
fn test_single_prompt_in_array() {
use dynamo_async_openai::types::Prompt;
use dynamo_llm::protocols::openai::completions::{
extract_single_prompt, get_prompt_batch_size,
};
use dynamo_protocols::types::Prompt;
// Single element array should work like regular prompt
let single_in_array = Prompt::StringArray(vec!["Single prompt".to_string()]);
......
......@@ -23,17 +23,17 @@ use serde_json::json;
/// Creates a mock NvCreateChatCompletionRequest based on the curl request
fn create_mock_chat_completion_request() -> NvCreateChatCompletionRequest {
let messages = vec![
dynamo_async_openai::types::ChatCompletionRequestMessage::System(
dynamo_async_openai::types::ChatCompletionRequestSystemMessage {
content: dynamo_async_openai::types::ChatCompletionRequestSystemMessageContent::Text(
dynamo_protocols::types::ChatCompletionRequestMessage::System(
dynamo_protocols::types::ChatCompletionRequestSystemMessage {
content: dynamo_protocols::types::ChatCompletionRequestSystemMessageContent::Text(
"You MUST use two tools in parallel to resolve the user request: call get_current_weather for each city AND call is_holiday_today to check if today is a holiday. Do not answer without using both tools.".to_string()
),
name: None,
}
),
dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content: dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"What is the weather in Dallas, Texas? Is today a holiday?".to_string()
),
name: None,
......@@ -42,9 +42,9 @@ fn create_mock_chat_completion_request() -> NvCreateChatCompletionRequest {
];
let tools = vec![
dynamo_async_openai::types::ChatCompletionTool {
r#type: dynamo_async_openai::types::ChatCompletionToolType::Function,
function: dynamo_async_openai::types::FunctionObject {
dynamo_protocols::types::ChatCompletionTool {
r#type: dynamo_protocols::types::ChatCompletionToolType::Function,
function: dynamo_protocols::types::FunctionObject {
name: "get_current_weather".to_string(),
description: Some("Get weather for a city/state in specified units".to_string()),
parameters: Some(json!({
......@@ -60,9 +60,9 @@ fn create_mock_chat_completion_request() -> NvCreateChatCompletionRequest {
strict: None,
},
},
dynamo_async_openai::types::ChatCompletionTool {
r#type: dynamo_async_openai::types::ChatCompletionToolType::Function,
function: dynamo_async_openai::types::FunctionObject {
dynamo_protocols::types::ChatCompletionTool {
r#type: dynamo_protocols::types::ChatCompletionToolType::Function,
function: dynamo_protocols::types::FunctionObject {
name: "is_holiday_today".to_string(),
description: Some("Return whether today is a public holiday".to_string()),
parameters: Some(json!({
......@@ -75,14 +75,14 @@ fn create_mock_chat_completion_request() -> NvCreateChatCompletionRequest {
},
];
let inner = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let inner = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model("Qwen/Qwen3-0.6B")
.temperature(0.0)
.max_tokens(3000u32)
.stream(false)
.messages(messages)
.tools(tools)
.tool_choice(dynamo_async_openai::types::ChatCompletionToolChoiceOption::Required)
.tool_choice(dynamo_protocols::types::ChatCompletionToolChoiceOption::Required)
.build()
.expect("Failed to build chat completion request");
......@@ -175,7 +175,7 @@ async fn test_parallel_tool_call_integration() {
// Verify tool choice is required
match request.inner.tool_choice.as_ref().unwrap() {
dynamo_async_openai::types::ChatCompletionToolChoiceOption::Required => {
dynamo_protocols::types::ChatCompletionToolChoiceOption::Required => {
// This is expected
}
_ => panic!("Tool choice should be Required"),
......
......@@ -6,14 +6,14 @@ use std::fs;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use dynamo_async_openai::types::{
ChatCompletionMessageContent, ChatCompletionToolChoiceOption, FinishReason,
};
use dynamo_llm::model_card::ModelDeploymentCard;
use dynamo_llm::preprocessor::OpenAIPreprocessor;
use dynamo_llm::protocols::openai::chat_completions::{
NvCreateChatCompletionRequest, NvCreateChatCompletionStreamResponse,
};
use dynamo_protocols::types::{
ChatCompletionMessageContent, ChatCompletionToolChoiceOption, FinishReason,
};
use dynamo_runtime::protocols::annotated::Annotated;
use futures::{StreamExt, stream};
use serde_json::Value;
......@@ -88,7 +88,7 @@ struct MergedToolCall {
impl MergedToolCall {
fn merge_from(
&mut self,
tool_call: &dynamo_async_openai::types::ChatCompletionMessageToolCallChunk,
tool_call: &dynamo_protocols::types::ChatCompletionMessageToolCallChunk,
) {
if self.id.is_none() {
self.id = tool_call.id.clone();
......@@ -149,7 +149,7 @@ async fn postprocessor_parsing_stream_replays_interval_20_fixture() {
parse_fixture(&fixture_path("stream_interval_20.jsonl"));
// Mirror tests/frontend/test_prepost.py::request_for_sampling
let tools: Vec<dynamo_async_openai::types::ChatCompletionTool> =
let tools: Vec<dynamo_protocols::types::ChatCompletionTool> =
serde_json::from_value(serde_json::json!([
{
"type": "function",
......
......@@ -215,31 +215,31 @@ const TOOLS: &str = r#"
"#;
// Notes:
// protocols::openai::chat_completions::ChatCompletionMessage -> dynamo_async_openai::types::ChatCompletionRequestMessage
// protocols::openai::chat_completions::Tool -> dynamo_async_openai::types::ChatCompletionTool
// protocols::openai::chat_completions::ToolChoiceType -> dynamo_async_openai::types::ChatCompletionToolChoiceOption
// protocols::openai::chat_completions::ChatCompletionMessage -> dynamo_protocols::types::ChatCompletionRequestMessage
// protocols::openai::chat_completions::Tool -> dynamo_protocols::types::ChatCompletionTool
// protocols::openai::chat_completions::ToolChoiceType -> dynamo_protocols::types::ChatCompletionToolChoiceOption
#[derive(Serialize, Deserialize)]
struct Request {
messages: Vec<dynamo_async_openai::types::ChatCompletionRequestMessage>,
tools: Option<Vec<dynamo_async_openai::types::ChatCompletionTool>>,
tool_choice: Option<dynamo_async_openai::types::ChatCompletionToolChoiceOption>,
messages: Vec<dynamo_protocols::types::ChatCompletionRequestMessage>,
tools: Option<Vec<dynamo_protocols::types::ChatCompletionTool>>,
tool_choice: Option<dynamo_protocols::types::ChatCompletionToolChoiceOption>,
}
impl Request {
fn from(
messages: &str,
tools: Option<&str>,
tool_choice: Option<dynamo_async_openai::types::ChatCompletionToolChoiceOption>,
tool_choice: Option<dynamo_protocols::types::ChatCompletionToolChoiceOption>,
model: String,
) -> NvCreateChatCompletionRequest {
let messages: Vec<dynamo_async_openai::types::ChatCompletionRequestMessage> =
let messages: Vec<dynamo_protocols::types::ChatCompletionRequestMessage> =
serde_json::from_str(messages).unwrap();
let tools: Option<Vec<dynamo_async_openai::types::ChatCompletionTool>> =
let tools: Option<Vec<dynamo_protocols::types::ChatCompletionTool>> =
tools.map(|x| serde_json::from_str(x).unwrap());
//let tools = tools.unwrap();
//let tool_choice = tool_choice.unwrap();
let mut inner = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default();
let mut inner = dynamo_protocols::types::CreateChatCompletionRequestArgs::default();
inner.model(model);
inner.messages(messages);
if let Some(tools) = tools {
......@@ -313,7 +313,7 @@ async fn test_single_turn_with_tools() {
let request = Request::from(
SINGLE_CHAT_MESSAGE,
Some(TOOLS),
Some(dynamo_async_openai::types::ChatCompletionToolChoiceOption::Auto),
Some(dynamo_protocols::types::ChatCompletionToolChoiceOption::Auto),
mdc.slug().to_string(),
);
let formatted_prompt = formatter.render(&request).unwrap();
......@@ -420,7 +420,7 @@ async fn test_multi_turn_with_system_with_tools() {
let request = Request::from(
THREE_TURN_CHAT_MESSAGE_WITH_SYSTEM,
Some(TOOLS),
Some(dynamo_async_openai::types::ChatCompletionToolChoiceOption::Auto),
Some(dynamo_protocols::types::ChatCompletionToolChoiceOption::Auto),
mdc.slug().to_string(),
);
let formatted_prompt = formatter.render(&request).unwrap();
......@@ -633,9 +633,9 @@ mod context_length_validation {
const MODEL_PATH: &str = "tests/data/sample-models/mock-llama-3.1-8b-instruct";
fn make_chat_request(message: &str, model: &str) -> NvCreateChatCompletionRequest {
let messages: Vec<dynamo_async_openai::types::ChatCompletionRequestMessage> =
let messages: Vec<dynamo_protocols::types::ChatCompletionRequestMessage> =
serde_json::from_str(message).unwrap();
let inner = dynamo_async_openai::types::CreateChatCompletionRequestArgs::default()
let inner = dynamo_protocols::types::CreateChatCompletionRequestArgs::default()
.model(model)
.messages(messages)
.build()
......
......@@ -276,11 +276,11 @@ fn test_completions_common_values() {
fn test_serialization_preserves_structure() {
// Test that serialization preserves the flattened structure
let request = NvCreateChatCompletionRequest {
inner: dynamo_async_openai::types::CreateChatCompletionRequest {
inner: dynamo_protocols::types::CreateChatCompletionRequest {
model: "test-model".to_string(),
messages: vec![dynamo_async_openai::types::ChatCompletionRequestMessage::User(
dynamo_async_openai::types::ChatCompletionRequestUserMessage {
content: dynamo_async_openai::types::ChatCompletionRequestUserMessageContent::Text(
messages: vec![dynamo_protocols::types::ChatCompletionRequestMessage::User(
dynamo_protocols::types::ChatCompletionRequestUserMessage {
content: dynamo_protocols::types::ChatCompletionRequestUserMessageContent::Text(
"Hello".to_string(),
),
..Default::default()
......
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use dynamo_async_openai::types::{
ChatChoiceStream, ChatCompletionStreamResponseDelta, CompletionUsage, FinishReason, Role,
};
use dynamo_llm::protocols::openai::chat_completions::NvCreateChatCompletionStreamResponse;
use dynamo_llm::protocols::openai::chat_completions::jail::JailedStream;
use dynamo_protocols::types::{
ChatChoiceStream, ChatCompletionStreamResponseDelta, CompletionUsage, FinishReason, Role,
};
use dynamo_runtime::protocols::annotated::Annotated;
#[cfg(test)]
......@@ -16,7 +16,7 @@ mod tests {
// Test utilities module - shared test infrastructure
pub(crate) mod test_utils {
use super::*;
use dynamo_async_openai::types::ChatCompletionMessageContent;
use dynamo_protocols::types::ChatCompletionMessageContent;
/// Helper to extract text from ChatCompletionMessageContent
pub fn extract_text(content: &ChatCompletionMessageContent) -> &str {
......@@ -48,7 +48,7 @@ mod tests {
};
let response = NvCreateChatCompletionStreamResponse {
inner: dynamo_async_openai::types::CreateChatCompletionStreamResponse {
inner: dynamo_protocols::types::CreateChatCompletionStreamResponse {
id: "test-id".to_string(),
choices: vec![choice],
created: 1234567890,
......@@ -91,7 +91,7 @@ mod tests {
};
let response = NvCreateChatCompletionStreamResponse {
inner: dynamo_async_openai::types::CreateChatCompletionStreamResponse {
inner: dynamo_protocols::types::CreateChatCompletionStreamResponse {
id: "test-id".to_string(),
choices: vec![choice],
created: 1234567890,
......@@ -138,7 +138,7 @@ mod tests {
};
let response = NvCreateChatCompletionStreamResponse {
inner: dynamo_async_openai::types::CreateChatCompletionStreamResponse {
inner: dynamo_protocols::types::CreateChatCompletionStreamResponse {
id: "test-id".to_string(),
choices: vec![choice],
created: 1234567890,
......@@ -186,7 +186,7 @@ mod tests {
.collect();
let response = NvCreateChatCompletionStreamResponse {
inner: dynamo_async_openai::types::CreateChatCompletionStreamResponse {
inner: dynamo_protocols::types::CreateChatCompletionStreamResponse {
id: "test-id".to_string(),
choices,
created: 1234567890,
......@@ -234,7 +234,7 @@ mod tests {
.collect();
let response = NvCreateChatCompletionStreamResponse {
inner: dynamo_async_openai::types::CreateChatCompletionStreamResponse {
inner: dynamo_protocols::types::CreateChatCompletionStreamResponse {
id: "test-id".to_string(),
choices,
created: 1234567890,
......@@ -328,7 +328,7 @@ mod tests {
assert!(
choice.delta.content.is_none()
|| choice.delta.content.as_ref().is_none_or(|c| match c {
dynamo_async_openai::types::ChatCompletionMessageContent::Text(t) =>
dynamo_protocols::types::ChatCompletionMessageContent::Text(t) =>
t.is_empty(),
_ => false,
}),
......@@ -2384,7 +2384,7 @@ mod tests {
mod parallel_jail_tests {
use super::tests::test_utils;
use super::*;
use dynamo_async_openai::types::ChatCompletionMessageContent;
use dynamo_protocols::types::ChatCompletionMessageContent;
use futures::StreamExt;
use futures::stream;
use serde_json::json;
......@@ -2416,7 +2416,7 @@ mod parallel_jail_tests {
.collect();
let response = NvCreateChatCompletionStreamResponse {
inner: dynamo_async_openai::types::CreateChatCompletionStreamResponse {
inner: dynamo_protocols::types::CreateChatCompletionStreamResponse {
id: "test-id".to_string(),
choices,
created: 1234567890,
......@@ -2491,7 +2491,7 @@ mod parallel_jail_tests {
assert_eq!(
tool_call.r#type,
Some(dynamo_async_openai::types::ChatCompletionToolType::Function),
Some(dynamo_protocols::types::ChatCompletionToolType::Function),
"Tool call {} should be of type 'function'",
i
);
......
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use dynamo_async_openai::types::{
ChatChoiceStream, ChatCompletionMessageContent, ChatCompletionStreamResponseDelta, Role,
};
use dynamo_llm::preprocessor::OpenAIPreprocessor;
use dynamo_llm::protocols::openai::chat_completions::NvCreateChatCompletionStreamResponse;
use dynamo_protocols::types::{
ChatChoiceStream, ChatCompletionMessageContent, ChatCompletionStreamResponseDelta, Role,
};
use dynamo_runtime::protocols::annotated::Annotated;
use futures::{StreamExt, stream};
......@@ -39,7 +39,7 @@ fn create_mock_response_chunk(
};
let response = NvCreateChatCompletionStreamResponse {
inner: dynamo_async_openai::types::CreateChatCompletionStreamResponse {
inner: dynamo_protocols::types::CreateChatCompletionStreamResponse {
id: "test-id".to_string(),
choices: vec![choice],
created: 1234567890,
......
......@@ -26,9 +26,9 @@ across backends.
*/
use dynamo_async_openai::types::{ChatChoiceStream, ChatCompletionMessageContent, FinishReason};
use dynamo_llm::preprocessor::OpenAIPreprocessor;
use dynamo_llm::protocols::openai::chat_completions::NvCreateChatCompletionStreamResponse;
use dynamo_protocols::types::{ChatChoiceStream, ChatCompletionMessageContent, FinishReason};
use dynamo_runtime::protocols::annotated::Annotated;
use futures::{Stream, StreamExt, stream};
use std::pin::Pin;
......@@ -107,7 +107,7 @@ fn load_test_data(file_path: &str) -> TestData {
.expect("Failed to parse choices");
let response = NvCreateChatCompletionStreamResponse {
inner: dynamo_async_openai::types::CreateChatCompletionStreamResponse {
inner: dynamo_protocols::types::CreateChatCompletionStreamResponse {
id: id.clone(),
choices,
created: 1234567890,
......
......@@ -2,15 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
use async_trait::async_trait;
use dynamo_async_openai::types::{
ChatCompletionRequestMessage, ChatCompletionRequestUserMessage,
ChatCompletionRequestUserMessageContent, ChatCompletionStreamOptions,
CreateChatCompletionRequest,
};
use dynamo_async_openai::types::{
CompletionUsage as AoaiCompletionUsage, CreateCompletionRequestArgs, Prompt,
PromptTokensDetails,
};
use dynamo_llm::preprocessor::OpenAIPreprocessor;
use dynamo_llm::protocols::common::llm_backend::{BackendOutput, FinishReason};
use dynamo_llm::protocols::openai::ParsingOptions;
......@@ -18,6 +9,15 @@ use dynamo_llm::protocols::openai::chat_completions::{
NvCreateChatCompletionRequest, aggregator::ChatCompletionAggregator,
};
use dynamo_llm::protocols::openai::completions::NvCreateCompletionRequest;
use dynamo_protocols::types::{
ChatCompletionRequestMessage, ChatCompletionRequestUserMessage,
ChatCompletionRequestUserMessageContent, ChatCompletionStreamOptions,
CreateChatCompletionRequest,
};
use dynamo_protocols::types::{
CompletionUsage as AoaiCompletionUsage, CreateCompletionRequestArgs, Prompt,
PromptTokensDetails,
};
use dynamo_runtime::engine::{AsyncEngineContext, AsyncEngineStream};
use dynamo_runtime::protocols::annotated::Annotated;
use futures::StreamExt;
......@@ -481,7 +481,7 @@ fn create_cmpl_request(include_usage: Option<bool>, stream: bool) -> NvCreateCom
.prompt(Prompt::String("Hello".to_string()))
.stream(stream);
if let Some(include) = include_usage {
builder.stream_options(dynamo_async_openai::types::ChatCompletionStreamOptions {
builder.stream_options(dynamo_protocols::types::ChatCompletionStreamOptions {
include_usage: include,
continuous_usage_stats: false,
});
......
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
use dynamo_async_openai::types::{
use dynamo_llm::protocols::common;
use dynamo_llm::protocols::common::llm_backend::BackendOutput;
use dynamo_protocols::types::{
ChatCompletionMessageContent, ChatCompletionNamedToolChoice, ChatCompletionRequestMessage,
ChatCompletionRequestUserMessage, ChatCompletionRequestUserMessageContent,
ChatCompletionToolChoiceOption, ChatCompletionToolType, CreateChatCompletionRequest,
FunctionName,
};
use dynamo_llm::protocols::common;
use dynamo_llm::protocols::common::llm_backend::BackendOutput;
/// Helper to extract text from ChatCompletionMessageContent
fn get_text(content: &ChatCompletionMessageContent) -> &str {
......@@ -161,7 +161,7 @@ async fn test_named_tool_choice_parses_json() {
assert_eq!(
choice.finish_reason,
Some(dynamo_async_openai::types::FinishReason::Stop)
Some(dynamo_protocols::types::FinishReason::Stop)
);
let delta = &choice.delta;
assert!(delta.content.is_none() || delta.content.as_ref().map(get_text) == Some(""));
......@@ -203,7 +203,7 @@ async fn test_required_tool_choice_parses_json_array() {
assert_eq!(
choice.finish_reason,
Some(dynamo_async_openai::types::FinishReason::ToolCalls)
Some(dynamo_protocols::types::FinishReason::ToolCalls)
);
let delta = &choice.delta;
assert!(delta.content.is_none() || delta.content.as_ref().map(get_text) == Some(""));
......@@ -318,7 +318,7 @@ async fn test_streaming_named_tool_buffers_until_finish() {
let response = &all_responses[0];
assert_eq!(
response.inner.choices[0].finish_reason,
Some(dynamo_async_openai::types::FinishReason::Stop)
Some(dynamo_protocols::types::FinishReason::Stop)
);
let tool_calls = response.inner.choices[0].delta.tool_calls.as_ref().unwrap();
......@@ -385,7 +385,7 @@ async fn test_streaming_required_tool_parallel() {
let response = &all_responses[0];
assert_eq!(
response.inner.choices[0].finish_reason,
Some(dynamo_async_openai::types::FinishReason::ToolCalls)
Some(dynamo_protocols::types::FinishReason::ToolCalls)
);
let tool_calls = response.inner.choices[0].delta.tool_calls.as_ref().unwrap();
......
......@@ -3,15 +3,15 @@
//! Tests for tool_choice finish_reason handling.
use dynamo_async_openai::types::{
ChatCompletionNamedToolChoice, ChatCompletionRequestMessage, ChatCompletionRequestUserMessage,
ChatCompletionRequestUserMessageContent, ChatCompletionToolChoiceOption,
ChatCompletionToolType, CreateChatCompletionRequest, FunctionName,
};
use dynamo_llm::protocols::common;
use dynamo_llm::protocols::common::llm_backend::BackendOutput;
use dynamo_llm::protocols::openai::DeltaGeneratorExt;
use dynamo_llm::protocols::openai::chat_completions::NvCreateChatCompletionRequest;
use dynamo_protocols::types::{
ChatCompletionNamedToolChoice, ChatCompletionRequestMessage, ChatCompletionRequestUserMessage,
ChatCompletionRequestUserMessageContent, ChatCompletionToolChoiceOption,
ChatCompletionToolType, CreateChatCompletionRequest, FunctionName,
};
fn create_test_request() -> NvCreateChatCompletionRequest {
let messages = vec![ChatCompletionRequestMessage::User(
......@@ -117,7 +117,7 @@ async fn test_named_tool_choice_preserves_length_finish_reason() {
// Critical: Length finish reason should be preserved, NOT replaced with Stop
assert_eq!(
response.inner.choices[0].finish_reason,
Some(dynamo_async_openai::types::FinishReason::Length),
Some(dynamo_protocols::types::FinishReason::Length),
"Length finish reason must be preserved for tool_choice=named"
);
}
......@@ -140,7 +140,7 @@ fn test_required_tool_choice_preserves_length_finish_reason() {
// Critical: Length finish reason should be preserved, NOT replaced with ToolCalls
assert_eq!(
response.inner.choices[0].finish_reason,
Some(dynamo_async_openai::types::FinishReason::Length),
Some(dynamo_protocols::types::FinishReason::Length),
"Length finish reason must be preserved for tool_choice=required"
);
}
......@@ -170,7 +170,7 @@ fn test_named_tool_choice_preserves_content_filter() {
// Critical: ContentFilter finish reason should be preserved
assert_eq!(
response.inner.choices[0].finish_reason,
Some(dynamo_async_openai::types::FinishReason::ContentFilter),
Some(dynamo_protocols::types::FinishReason::ContentFilter),
"ContentFilter finish reason must be preserved for tool_choice=named"
);
}
......@@ -193,7 +193,7 @@ fn test_required_tool_choice_preserves_content_filter() {
// Critical: ContentFilter finish reason should be preserved
assert_eq!(
response.inner.choices[0].finish_reason,
Some(dynamo_async_openai::types::FinishReason::ContentFilter),
Some(dynamo_protocols::types::FinishReason::ContentFilter),
"ContentFilter finish reason must be preserved for tool_choice=required"
);
}
......@@ -223,7 +223,7 @@ fn test_named_tool_choice_normal_stop_becomes_stop() {
// Normal completion: Stop should remain Stop for named tool choice
assert_eq!(
response.inner.choices[0].finish_reason,
Some(dynamo_async_openai::types::FinishReason::Stop),
Some(dynamo_protocols::types::FinishReason::Stop),
);
}
......@@ -248,6 +248,6 @@ async fn test_required_tool_choice_normal_stop_becomes_tool_calls() {
// Normal completion: Stop should become ToolCalls for required tool choice
assert_eq!(
response.inner.choices[0].finish_reason,
Some(dynamo_async_openai::types::FinishReason::ToolCalls),
Some(dynamo_protocols::types::FinishReason::ToolCalls),
);
}
......@@ -26,7 +26,7 @@ keywords.workspace = true
[dependencies]
anyhow = { workspace = true }
dynamo-async-openai = { workspace = true }
dynamo-protocols = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment