add new providers to the router

This commit is contained in:
Brandon Thomas committed 2026-03-16 19:21:56 -04:00
1 parent 500d76d71e
commit f3e69ddf75
30 files changed
+241 -1

No files matched your search

Generated
+1
View File
@@ -788,6 +788,7 @@ dependencies = [
"artcraft_client",
"fal_client",
"log",
"muapi_client",
"seedance2pro",
"serde",
"serde_derive",
@@ -19,6 +19,7 @@ workspace-build-acceleration.workspace = true
artcraft_api_defs.workspace = true
artcraft_client.workspace = true
fal_client.workspace = true
muapi_client.workspace = true
seedance2pro.workspace = true
tokens.workspace = true
world_labs_api.workspace = true
@@ -6,4 +6,6 @@ use serde_derive::{Deserialize, Serialize};
pub enum Provider {
Artcraft,
Fal,
Muapi,
Seedance2Pro,
}
@@ -5,3 +5,5 @@ pub mod request_mismatch_mitigation_strategy;
pub mod router_artcraft_client;
pub mod router_client;
pub mod router_fal_client;
pub mod router_muapi_client;
pub mod router_seedance2pro_client;
@@ -1,10 +1,14 @@
use crate::client::router_artcraft_client::RouterArtcraftClient;
use crate::client::router_fal_client::RouterFalClient;
use crate::client::router_muapi_client::RouterMuapiClient;
use crate::client::router_seedance2pro_client::RouterSeedance2ProClient;
use crate::errors::client_error::{ClientError, ClientType};
pub struct MultiRouterClient {
pub(crate) artcraft_client: Option<RouterArtcraftClient>,
pub(crate) fal_client: Option<RouterFalClient>,
pub(crate) muapi_client: Option<RouterMuapiClient>,
pub(crate) seedance2pro_client: Option<RouterSeedance2ProClient>,
}
impl MultiRouterClient {
@@ -17,4 +21,14 @@ impl MultiRouterClient {
self.fal_client.as_ref()
.ok_or(ClientError::ClientNotConfigured(ClientType::Fal))
}
pub fn get_muapi_client_ref(&self) -> Result<&RouterMuapiClient, ClientError> {
self.muapi_client.as_ref()
.ok_or(ClientError::ClientNotConfigured(ClientType::Muapi))
}
pub fn get_seedance2pro_client_ref(&self) -> Result<&RouterSeedance2ProClient, ClientError> {
self.seedance2pro_client.as_ref()
.ok_or(ClientError::ClientNotConfigured(ClientType::Seedance2Pro))
}
}
@@ -1,10 +1,14 @@
use crate::client::multi_router_client::MultiRouterClient;
use crate::client::router_artcraft_client::RouterArtcraftClient;
use crate::client::router_fal_client::RouterFalClient;
use crate::client::router_muapi_client::RouterMuapiClient;
use crate::client::router_seedance2pro_client::RouterSeedance2ProClient;
pub struct MultiRouterClientBuilder {
artcraft_client: Option<RouterArtcraftClient>,
fal_client: Option<RouterFalClient>,
muapi_client: Option<RouterMuapiClient>,
seedance2pro_client: Option<RouterSeedance2ProClient>,
}
impl MultiRouterClientBuilder {
@@ -12,6 +16,8 @@ impl MultiRouterClientBuilder {
Self {
artcraft_client: None,
fal_client: None,
muapi_client: None,
seedance2pro_client: None,
}
}
@@ -25,10 +31,22 @@ impl MultiRouterClientBuilder {
self
}
pub fn set_muapi_client(mut self, client: RouterMuapiClient) -> Self {
self.muapi_client = Some(client);
self
}
pub fn set_seedance2pro_client(mut self, client: RouterSeedance2ProClient) -> Self {
self.seedance2pro_client = Some(client);
self
}
pub fn build(self) -> MultiRouterClient {
MultiRouterClient {
artcraft_client: self.artcraft_client,
fal_client: self.fal_client,
muapi_client: self.muapi_client,
seedance2pro_client: self.seedance2pro_client,
}
}
}
@@ -1,12 +1,16 @@
use crate::client::multi_router_client::MultiRouterClient;
use crate::client::router_artcraft_client::RouterArtcraftClient;
use crate::client::router_fal_client::RouterFalClient;
use crate::client::router_muapi_client::RouterMuapiClient;
use crate::client::router_seedance2pro_client::RouterSeedance2ProClient;
use crate::errors::client_error::{ClientError, ClientType};
pub enum RouterClient {
Multi(MultiRouterClient),
Artcraft(RouterArtcraftClient),
Fal(RouterFalClient),
Muapi(RouterMuapiClient),
Seedance2Pro(RouterSeedance2ProClient),
}
impl RouterClient {
@@ -25,4 +29,20 @@ impl RouterClient {
_ => Err(ClientError::ClientNotConfigured(ClientType::Fal)),
}
}
pub fn get_muapi_client_ref(&self) -> Result<&RouterMuapiClient, ClientError> {
match self {
RouterClient::Muapi(client) => Ok(client),
RouterClient::Multi(multi) => multi.get_muapi_client_ref(),
_ => Err(ClientError::ClientNotConfigured(ClientType::Muapi)),
}
}
pub fn get_seedance2pro_client_ref(&self) -> Result<&RouterSeedance2ProClient, ClientError> {
match self {
RouterClient::Seedance2Pro(client) => Ok(client),
RouterClient::Multi(multi) => multi.get_seedance2pro_client_ref(),
_ => Err(ClientError::ClientNotConfigured(ClientType::Seedance2Pro)),
}
}
}
@@ -0,0 +1,11 @@
use muapi_client::creds::muapi_session::MuapiSession;
pub struct RouterMuapiClient {
pub(crate) session: MuapiSession,
}
impl RouterMuapiClient {
pub fn new(session: MuapiSession) -> Self {
RouterMuapiClient { session }
}
}
@@ -0,0 +1,11 @@
use seedance2pro::creds::seedance2pro_session::Seedance2ProSession;
pub struct RouterSeedance2ProClient {
pub(crate) session: Seedance2ProSession,
}
impl RouterSeedance2ProClient {
pub fn new(session: Seedance2ProSession) -> Self {
RouterSeedance2ProClient { session }
}
}
@@ -5,6 +5,8 @@ use std::fmt::{Display, Formatter};
pub enum ClientType {
Artcraft,
Fal,
Muapi,
Seedance2Pro,
}
impl Display for ClientType {
@@ -12,6 +14,8 @@ impl Display for ClientType {
match self {
Self::Artcraft => write!(f, "Artcraft"),
Self::Fal => write!(f, "Fal"),
Self::Muapi => write!(f, "Muapi"),
Self::Seedance2Pro => write!(f, "Seedance2Pro"),
}
}
}
@@ -136,6 +136,9 @@ impl<'a> GenerateImageRequest<'a> {
}))
}
},
Provider::Muapi | Provider::Seedance2Pro => Err(ArtcraftRouterError::UnsupportedModel(
format!("Image generation via {:?} is not supported", self.provider)
)),
}
}
@@ -39,6 +39,9 @@ impl<'a> GenerateSplatRequest<'a> {
Provider::Fal => Err(ArtcraftRouterError::UnsupportedModel(
format!("Splat generation via Fal is not yet supported (model: {:?})", self.model)
)),
Provider::Muapi | Provider::Seedance2Pro => Err(ArtcraftRouterError::UnsupportedModel(
format!("Splat generation via {:?} is not supported", self.provider)
)),
}
}
@@ -1 +1,3 @@
pub (crate) mod artcraft;
pub (crate) mod muapi;
pub (crate) mod seedance2pro;
@@ -0,0 +1,8 @@
use crate::generate::generate_video::plan::muapi::plan_generate_video_muapi_seedance2p0::PlanMuapiSeedance2p0;
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
pub(crate) fn estimate_video_cost_muapi_seedance2p0(
_plan: &PlanMuapiSeedance2p0,
) -> VideoGenerationCostEstimate {
todo!("estimate_video_cost_muapi_seedance2p0")
}
@@ -0,0 +1 @@
pub mod estimate_video_cost_muapi_seedance2p0;
@@ -0,0 +1,8 @@
use crate::generate::generate_video::plan::seedance2pro::plan_generate_video_seedance2pro_seedance2p0::PlanSeedance2proSeedance2p0;
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
pub(crate) fn estimate_video_cost_seedance2pro_seedance2p0(
_plan: &PlanSeedance2proSeedance2p0,
) -> VideoGenerationCostEstimate {
todo!("estimate_video_cost_seedance2pro_seedance2p0")
}
@@ -0,0 +1 @@
pub mod estimate_video_cost_seedance2pro_seedance2p0;
@@ -1 +1,3 @@
pub mod artcraft;
pub mod muapi;
pub mod seedance2pro;
@@ -0,0 +1,11 @@
use crate::client::router_muapi_client::RouterMuapiClient;
use crate::errors::artcraft_router_error::ArtcraftRouterError;
use crate::generate::generate_video::generate_video_response::GenerateVideoResponse;
use crate::generate::generate_video::plan::muapi::plan_generate_video_muapi_seedance2p0::PlanMuapiSeedance2p0;
pub async fn execute_muapi_seedance2p0(
_plan: &PlanMuapiSeedance2p0,
_muapi_client: &RouterMuapiClient,
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
todo!("execute_muapi_seedance2p0")
}
@@ -0,0 +1 @@
pub mod execute_muapi_seedance2p0;
@@ -0,0 +1,11 @@
use crate::client::router_seedance2pro_client::RouterSeedance2ProClient;
use crate::errors::artcraft_router_error::ArtcraftRouterError;
use crate::generate::generate_video::generate_video_response::GenerateVideoResponse;
use crate::generate::generate_video::plan::seedance2pro::plan_generate_video_seedance2pro_seedance2p0::PlanSeedance2proSeedance2p0;
pub async fn execute_seedance2pro_seedance2p0(
_plan: &PlanSeedance2proSeedance2p0,
_seedance2pro_client: &RouterSeedance2ProClient,
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
todo!("execute_seedance2pro_seedance2p0")
}
@@ -0,0 +1 @@
pub mod execute_seedance2pro_seedance2p0;
@@ -12,6 +12,8 @@ use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraf
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling3p0_standard::plan_generate_video_artcraft_kling3p0_standard;
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_seedance1p5_pro::plan_generate_video_artcraft_seedance1p5_pro;
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_seedance2p0::plan_generate_video_artcraft_seedance2p0;
use crate::generate::generate_video::plan::muapi::plan_generate_video_muapi_seedance2p0::plan_generate_video_muapi_seedance2p0;
use crate::generate::generate_video::plan::seedance2pro::plan_generate_video_seedance2pro_seedance2p0::plan_generate_video_seedance2pro_seedance2p0;
use crate::generate::generate_video::video_generation_plan::VideoGenerationPlan;
/// Plan to either (1) generate a video or (2) determine how much it costs to generate that video.
@@ -93,6 +95,18 @@ impl<'a> GenerateVideoRequest<'a> {
Provider::Fal => Err(ArtcraftRouterError::UnsupportedModel(
format!("Video generation via Fal is not yet supported (model: {:?})", self.model)
)),
Provider::Muapi => match self.model {
CommonVideoModel::Seedance2p0 => {
plan_generate_video_muapi_seedance2p0(self).map(VideoGenerationPlan::MuapiSeedance2p0)
}
_ => Err(ArtcraftRouterError::UnsupportedModel(format!("{:?}", self.model))),
},
Provider::Seedance2Pro => match self.model {
CommonVideoModel::Seedance2p0 => {
plan_generate_video_seedance2pro_seedance2p0(self).map(VideoGenerationPlan::Seedance2proSeedance2p0)
}
_ => Err(ArtcraftRouterError::UnsupportedModel(format!("{:?}", self.model))),
},
}
}
@@ -1,3 +1,4 @@
use muapi_client::api_types::request_id::RequestId as MuapiRequestId;
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
#[derive(Clone, Debug)]
@@ -6,15 +7,42 @@ pub struct ArtcraftVideoResponsePayload {
pub all_inference_job_tokens: Vec<InferenceJobToken>,
}
#[derive(Clone, Debug)]
pub struct MuapiVideoResponsePayload {
pub request_id: MuapiRequestId,
}
#[derive(Clone, Debug)]
pub struct Seedance2proVideoResponsePayload {
pub task_id: String,
}
#[derive(Clone, Debug)]
pub enum GenerateVideoResponse {
Artcraft(ArtcraftVideoResponsePayload),
Muapi(MuapiVideoResponsePayload),
Seedance2Pro(Seedance2proVideoResponsePayload),
}
impl GenerateVideoResponse {
pub fn get_artcraft_payload(&self) -> Option<ArtcraftVideoResponsePayload> {
match self {
Self::Artcraft(p) => Some(p.clone()),
_ => None,
}
}
pub fn get_muapi_payload(&self) -> Option<MuapiVideoResponsePayload> {
match self {
Self::Muapi(p) => Some(p.clone()),
_ => None,
}
}
pub fn get_seedance2pro_payload(&self) -> Option<Seedance2proVideoResponsePayload> {
match self {
Self::Seedance2Pro(p) => Some(p.clone()),
_ => None,
}
}
}
@@ -1 +1,3 @@
pub mod artcraft;
pub mod artcraft;
pub mod muapi;
pub mod seedance2pro;
@@ -0,0 +1 @@
pub mod plan_generate_video_muapi_seedance2p0;
@@ -0,0 +1,18 @@
use crate::api::common_aspect_ratio::CommonAspectRatio;
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
use crate::errors::artcraft_router_error::ArtcraftRouterError;
use crate::generate::generate_video::generate_video_request::GenerateVideoRequest;
#[derive(Debug, Clone)]
pub struct PlanMuapiSeedance2p0 {
pub prompt: Option<String>,
pub image_url: Option<String>,
pub aspect_ratio: Option<CommonAspectRatio>,
pub duration_seconds: Option<u16>,
}
pub fn plan_generate_video_muapi_seedance2p0(
_request: &GenerateVideoRequest<'_>,
) -> Result<PlanMuapiSeedance2p0, ArtcraftRouterError> {
todo!("plan_generate_video_muapi_seedance2p0")
}
@@ -0,0 +1 @@
pub mod plan_generate_video_seedance2pro_seedance2p0;
@@ -0,0 +1,18 @@
use crate::api::common_aspect_ratio::CommonAspectRatio;
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
use crate::errors::artcraft_router_error::ArtcraftRouterError;
use crate::generate::generate_video::generate_video_request::GenerateVideoRequest;
#[derive(Debug, Clone)]
pub struct PlanSeedance2proSeedance2p0 {
pub prompt: Option<String>,
pub image_url: Option<String>,
pub aspect_ratio: Option<CommonAspectRatio>,
pub duration_seconds: Option<u16>,
}
pub fn plan_generate_video_seedance2pro_seedance2p0(
_request: &GenerateVideoRequest<'_>,
) -> Result<PlanSeedance2proSeedance2p0, ArtcraftRouterError> {
todo!("plan_generate_video_seedance2pro_seedance2p0")
}
@@ -4,15 +4,21 @@ use crate::generate::generate_video::cost::artcraft::estimate_video_cost_artcraf
use crate::generate::generate_video::cost::artcraft::estimate_video_cost_artcraft_kling3p0_standard::estimate_video_cost_artcraft_kling3p0_standard;
use crate::generate::generate_video::cost::artcraft::estimate_video_cost_artcraft_seedance1p5_pro::estimate_video_cost_artcraft_seedance1p5_pro;
use crate::generate::generate_video::cost::artcraft::estimate_video_cost_artcraft_seedance2p0::estimate_video_cost_artcraft_seedance2p0;
use crate::generate::generate_video::cost::muapi::estimate_video_cost_muapi_seedance2p0::estimate_video_cost_muapi_seedance2p0;
use crate::generate::generate_video::cost::seedance2pro::estimate_video_cost_seedance2pro_seedance2p0::estimate_video_cost_seedance2pro_seedance2p0;
use crate::generate::generate_video::execute::artcraft::generate_video_artcraft_kling3p0_pro::execute_artcraft_kling3p0_pro;
use crate::generate::generate_video::execute::artcraft::generate_video_artcraft_kling3p0_standard::execute_artcraft_kling3p0_standard;
use crate::generate::generate_video::execute::artcraft::generate_video_artcraft_seedance1p5_pro::execute_artcraft_seedance1p5_pro;
use crate::generate::generate_video::execute::artcraft::generate_video_artcraft_seedance2p0::execute_artcraft_seedance2p0;
use crate::generate::generate_video::execute::muapi::execute_muapi_seedance2p0::execute_muapi_seedance2p0;
use crate::generate::generate_video::execute::seedance2pro::execute_seedance2pro_seedance2p0::execute_seedance2pro_seedance2p0;
use crate::generate::generate_video::generate_video_response::GenerateVideoResponse;
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling3p0_pro::PlanArtcraftKling3p0Pro;
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_kling3p0_standard::PlanArtcraftKling3p0Standard;
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_seedance1p5_pro::PlanArtcraftSeedance1p5Pro;
use crate::generate::generate_video::plan::artcraft::plan_generate_video_artcraft_seedance2p0::PlanArtcraftSeedance2p0;
use crate::generate::generate_video::plan::muapi::plan_generate_video_muapi_seedance2p0::PlanMuapiSeedance2p0;
use crate::generate::generate_video::plan::seedance2pro::plan_generate_video_seedance2pro_seedance2p0::PlanSeedance2proSeedance2p0;
use crate::generate::generate_video::video_generation_cost_estimate::VideoGenerationCostEstimate;
#[derive(Debug)]
@@ -21,6 +27,8 @@ pub enum VideoGenerationPlan<'a> {
ArtcraftKling3p0Standard(PlanArtcraftKling3p0Standard<'a>),
ArtcraftSeedance1p5Pro(PlanArtcraftSeedance1p5Pro<'a>),
ArtcraftSeedance2p0(PlanArtcraftSeedance2p0<'a>),
MuapiSeedance2p0(PlanMuapiSeedance2p0),
Seedance2proSeedance2p0(PlanSeedance2proSeedance2p0),
}
impl<'a> VideoGenerationPlan<'a> {
@@ -45,6 +53,14 @@ impl<'a> VideoGenerationPlan<'a> {
let artcraft_client = client.get_artcraft_client_ref()?;
execute_artcraft_seedance2p0(plan, artcraft_client).await
}
VideoGenerationPlan::MuapiSeedance2p0(plan) => {
let muapi_client = client.get_muapi_client_ref()?;
execute_muapi_seedance2p0(plan, muapi_client).await
}
VideoGenerationPlan::Seedance2proSeedance2p0(plan) => {
let seedance2pro_client = client.get_seedance2pro_client_ref()?;
execute_seedance2pro_seedance2p0(plan, seedance2pro_client).await
}
}
}
@@ -62,6 +78,12 @@ impl<'a> VideoGenerationPlan<'a> {
VideoGenerationPlan::ArtcraftSeedance2p0(plan) => {
estimate_video_cost_artcraft_seedance2p0(plan)
}
VideoGenerationPlan::MuapiSeedance2p0(plan) => {
estimate_video_cost_muapi_seedance2p0(plan)
}
VideoGenerationPlan::Seedance2proSeedance2p0(plan) => {
estimate_video_cost_seedance2pro_seedance2p0(plan)
}
}
}
}