use super::{CompletionOptions, CompletionResponse, CompletionStream, Message, Router};
use crate::core::router::{RuntimeBinding, default_runtime};
use crate::utils::error::gateway_error::{GatewayError, Result};
use async_trait::async_trait;
mod router_impl;
pub struct DefaultRouter {
runtime_binding: Option<RuntimeBinding>,
}
impl DefaultRouter {
pub async fn new() -> Result<Self> {
Ok(Self {
runtime_binding: None,
})
}
pub fn from_runtime(runtime: RuntimeBinding) -> Self {
Self {
runtime_binding: Some(runtime),
}
}
}
pub struct ErrorRouter {
error: String,
}
impl ErrorRouter {
pub fn new(error: impl Into<String>) -> Self {
Self {
error: error.into(),
}
}
}
#[async_trait]
impl Router for ErrorRouter {
async fn complete(
&self,
_model: &str,
_messages: Vec<Message>,
_options: CompletionOptions,
) -> Result<CompletionResponse> {
Err(GatewayError::internal(format!(
"Router initialization failed: {}",
self.error
)))
}
async fn complete_stream(
&self,
_model: &str,
_messages: Vec<Message>,
_options: CompletionOptions,
) -> Result<CompletionStream> {
Err(GatewayError::internal(format!(
"Router initialization failed: {}",
self.error
)))
}
}
pub async fn completion(
model: &str,
messages: Vec<Message>,
options: Option<CompletionOptions>,
) -> Result<CompletionResponse> {
let handle = default_runtime().map_err(GatewayError::from)?;
router_impl::complete_with_runtime_handle(&handle, model, messages, options.unwrap_or_default())
.await
}
pub async fn acompletion(
model: &str,
messages: Vec<Message>,
options: Option<CompletionOptions>,
) -> Result<CompletionResponse> {
completion(model, messages, options).await
}
pub async fn completion_stream(
model: &str,
messages: Vec<Message>,
options: Option<CompletionOptions>,
) -> Result<CompletionStream> {
let handle = default_runtime().map_err(GatewayError::from)?;
router_impl::complete_stream_with_runtime_handle(
&handle,
model,
messages,
options.unwrap_or_default(),
)
.await
}
fn convert_chat_chunk_to_completion_chunk(
chunk: crate::core::types::responses::ChatChunk,
) -> super::stream::CompletionChunk {
super::stream::CompletionChunk {
id: chunk.id,
object: chunk.object,
created: chunk.created,
model: chunk.model,
choices: chunk
.choices
.into_iter()
.map(|choice| super::stream::StreamChoice {
index: choice.index,
delta: super::stream::StreamDelta {
role: choice.delta.role.map(|role| role.to_string()),
content: choice.delta.content,
tool_calls: None,
},
finish_reason: choice.finish_reason,
})
.collect(),
}
}