mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 01:38:44 +00:00
new crate
This commit is contained in:
1 parent
9506885529
commit
8d5d9f8991
15 files changed
+302
No files matched your search
@@ -0,0 +1,29 @@
|
||||
[package]
|
||||
name = "artcraft_router"
|
||||
edition = "2024"
|
||||
version = "0.0.1"
|
||||
publish = false
|
||||
|
||||
[package.metadata.cargo-udeps.ignore]
|
||||
normal = ["workspace-build-acceleration"]
|
||||
|
||||
[lib]
|
||||
name = "artcraft_router"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
# Workspace hack (faster compile times)
|
||||
workspace-build-acceleration.workspace = true
|
||||
|
||||
# Internal
|
||||
artcraft_api_defs.workspace = true
|
||||
storyteller_client.workspace = true
|
||||
tokens.workspace = true
|
||||
|
||||
# External
|
||||
anyhow.workspace = true
|
||||
log.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
uuid = { version = "1", features = ["v4"] }
|
||||
@@ -0,0 +1,42 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
/// This is a comprehensive list of common aspect ratios you can specify when enqueuing a generation.
|
||||
/// Not every model will support every aspect ratio.
|
||||
/// In the case a model doesn't support the aspect ratio, gracefully pick the nearest option.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CommonAspectRatio {
|
||||
// Auto (eg. for image editing to use the source; used by Nano Banana Pro edit image, but not text-to-image)
|
||||
Auto,
|
||||
|
||||
// Square
|
||||
Square,
|
||||
|
||||
// Wide
|
||||
WideThreeByTwo,
|
||||
WideFourByThree,
|
||||
WideFiveByFour,
|
||||
WideSixteenByNine,
|
||||
WideTwentyOneByNine,
|
||||
|
||||
// Tall
|
||||
TallTwoByThree,
|
||||
TallThreeByFour,
|
||||
TallFourByFive,
|
||||
TallNineBySixteen,
|
||||
TallNineByTwentyOne,
|
||||
|
||||
// Imprecise semantic values that we probably remap to other meanings
|
||||
// on a model-by-model basis.
|
||||
Wide,
|
||||
Tall,
|
||||
|
||||
// Auto values that bake in resolution
|
||||
// These are from the Seedream models
|
||||
Auto2k,
|
||||
Auto4k,
|
||||
|
||||
// Defined aspect ratios that bake in resolution
|
||||
// These are from the Seedream models
|
||||
SquareHd,
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
/// This is a comprehensive list of common resolutions you can specify when enqueuing a generation.
|
||||
/// Not every model will support every resolution.
|
||||
/// In the case a model doesn't support the resolution, gracefully pick the nearest option.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CommonVideoResolution {
|
||||
/// Models: Nano Banana Pro
|
||||
OneK,
|
||||
/// Models: Nano Banana Pro
|
||||
TwoK,
|
||||
/// Models: (None)
|
||||
ThreeK,
|
||||
/// Models: Nano Banana Pro
|
||||
FourK,
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
/// Common video models supported by the router.
|
||||
/// Not all models are available through all providers.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CommonVideoModel {
|
||||
#[serde(rename = "grok_video")]
|
||||
GrokVideo,
|
||||
|
||||
#[serde(rename = "kling_1.6_pro")]
|
||||
Kling16Pro,
|
||||
|
||||
#[serde(rename = "kling_2.1_pro")]
|
||||
Kling21Pro,
|
||||
|
||||
#[serde(rename = "kling_2.1_master")]
|
||||
Kling21Master,
|
||||
|
||||
#[serde(rename = "kling_2p5_turbo_pro")]
|
||||
Kling2p5TurboPro,
|
||||
|
||||
#[serde(rename = "kling_2p6_pro")]
|
||||
Kling2p6Pro,
|
||||
|
||||
#[serde(rename = "seedance_1.0_lite")]
|
||||
Seedance10Lite,
|
||||
|
||||
#[serde(rename = "seedance_2p0")]
|
||||
Seedance2p0,
|
||||
|
||||
#[serde(rename = "sora_2")]
|
||||
Sora2,
|
||||
|
||||
#[serde(rename = "sora_2_pro")]
|
||||
Sora2Pro,
|
||||
|
||||
#[serde(rename = "veo_2")]
|
||||
Veo2,
|
||||
|
||||
#[serde(rename = "veo_3")]
|
||||
Veo3,
|
||||
|
||||
#[serde(rename = "veo_3_fast")]
|
||||
Veo3Fast,
|
||||
|
||||
#[serde(rename = "veo_3p1")]
|
||||
Veo3p1,
|
||||
|
||||
#[serde(rename = "veo_3p1_fast")]
|
||||
Veo3p1Fast,
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod common_aspect_ratio;
|
||||
pub mod common_resolution;
|
||||
pub mod common_video_model;
|
||||
@@ -0,0 +1,33 @@
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ArtcraftRouterError {
|
||||
/// The requested model is not yet supported by the router.
|
||||
UnsupportedModel(String),
|
||||
|
||||
/// Invalid or missing input arguments.
|
||||
InvalidInput(String),
|
||||
|
||||
/// An error from an underlying provider.
|
||||
Provider(ProviderError),
|
||||
}
|
||||
|
||||
impl Error for ArtcraftRouterError {}
|
||||
|
||||
impl Display for ArtcraftRouterError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::UnsupportedModel(model) => write!(f, "Unsupported model: {}", model),
|
||||
Self::InvalidInput(msg) => write!(f, "Invalid input: {}", msg),
|
||||
Self::Provider(e) => write!(f, "Provider error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ProviderError> for ArtcraftRouterError {
|
||||
fn from(error: ProviderError) -> Self {
|
||||
Self::Provider(error)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod artcraft_router_error;
|
||||
pub mod provider_error;
|
||||
@@ -0,0 +1,24 @@
|
||||
use std::error::Error;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use storyteller_client::error::storyteller_error::StorytellerError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ProviderError {
|
||||
Storyteller(StorytellerError),
|
||||
}
|
||||
|
||||
impl Error for ProviderError {}
|
||||
|
||||
impl Display for ProviderError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Storyteller(e) => write!(f, "Storyteller provider error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StorytellerError> for ProviderError {
|
||||
fn from(error: StorytellerError) -> Self {
|
||||
Self::Storyteller(error)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
use crate::api::common_aspect_ratio::CommonAspectRatio;
|
||||
use crate::api::common_resolution::CommonVideoResolution;
|
||||
use crate::api::common_video_model::CommonVideoModel;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::generate::generate_video::providers::artcraft::generate_video_artcraft_seedance2p0::generate_video_artcraft_seedance2p0;
|
||||
use storyteller_client::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use storyteller_client::utils::api_host::ApiHost;
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
|
||||
pub struct GenerateVideoArgs {
|
||||
pub model: CommonVideoModel,
|
||||
pub resolution: Option<CommonVideoResolution>,
|
||||
pub aspect_ratio: Option<CommonAspectRatio>,
|
||||
pub prompt: Option<String>,
|
||||
}
|
||||
|
||||
pub struct GenerateVideoResponse {
|
||||
pub inference_job_token: InferenceJobToken,
|
||||
pub all_inference_job_tokens: Vec<InferenceJobToken>,
|
||||
}
|
||||
|
||||
pub struct GenerateVideoContext<'a> {
|
||||
pub api_host: &'a ApiHost,
|
||||
pub storyteller_creds: Option<&'a StorytellerCredentialSet>,
|
||||
}
|
||||
|
||||
pub async fn generate_video(
|
||||
args: &GenerateVideoArgs,
|
||||
context: &GenerateVideoContext<'_>,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
match args.model {
|
||||
CommonVideoModel::Seedance2p0 => {
|
||||
generate_video_artcraft_seedance2p0(args, context.api_host, context.storyteller_creds).await
|
||||
}
|
||||
_ => Err(ArtcraftRouterError::UnsupportedModel(format!("{:?}", args.model))),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod generate_video;
|
||||
pub mod providers;
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
use crate::api::common_aspect_ratio::CommonAspectRatio;
|
||||
use crate::errors::artcraft_router_error::ArtcraftRouterError;
|
||||
use crate::errors::provider_error::ProviderError;
|
||||
use crate::generate::generate_video::generate_video::{GenerateVideoArgs, GenerateVideoResponse};
|
||||
use artcraft_api_defs::generate::video::multi_function::seedance_2p0_multi_function_video_gen::{
|
||||
Seedance2p0AspectRatio, Seedance2p0BatchCount, Seedance2p0MultiFunctionVideoGenRequest,
|
||||
};
|
||||
use storyteller_client::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use storyteller_client::endpoints::generate::video::multi_function::seedance_2p0_multi_function_video_gen::seedance_2p0_multi_function_video_gen;
|
||||
use storyteller_client::utils::api_host::ApiHost;
|
||||
use uuid::Uuid;
|
||||
|
||||
fn map_aspect_ratio(aspect_ratio: Option<CommonAspectRatio>) -> Option<Seedance2p0AspectRatio> {
|
||||
match aspect_ratio {
|
||||
Some(CommonAspectRatio::WideSixteenByNine) | Some(CommonAspectRatio::Wide) => {
|
||||
Some(Seedance2p0AspectRatio::Landscape16x9)
|
||||
}
|
||||
Some(CommonAspectRatio::TallNineBySixteen) | Some(CommonAspectRatio::Tall) => {
|
||||
Some(Seedance2p0AspectRatio::Portrait9x16)
|
||||
}
|
||||
Some(CommonAspectRatio::Square) => Some(Seedance2p0AspectRatio::Square1x1),
|
||||
Some(CommonAspectRatio::WideFourByThree) => Some(Seedance2p0AspectRatio::Standard4x3),
|
||||
Some(CommonAspectRatio::TallThreeByFour) => Some(Seedance2p0AspectRatio::Portrait3x4),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn generate_video_artcraft_seedance2p0(
|
||||
args: &GenerateVideoArgs,
|
||||
api_host: &ApiHost,
|
||||
creds: Option<&StorytellerCredentialSet>,
|
||||
) -> Result<GenerateVideoResponse, ArtcraftRouterError> {
|
||||
let uuid_idempotency_token = Uuid::new_v4().to_string();
|
||||
let aspect_ratio = map_aspect_ratio(args.aspect_ratio);
|
||||
|
||||
let request = Seedance2p0MultiFunctionVideoGenRequest {
|
||||
uuid_idempotency_token,
|
||||
prompt: args.prompt.clone(),
|
||||
start_frame_media_token: None,
|
||||
end_frame_media_token: None,
|
||||
reference_image_media_tokens: None,
|
||||
aspect_ratio,
|
||||
duration_seconds: None,
|
||||
batch_count: Some(Seedance2p0BatchCount::One),
|
||||
};
|
||||
|
||||
let response = seedance_2p0_multi_function_video_gen(api_host, creds, request)
|
||||
.await
|
||||
.map_err(|err| ArtcraftRouterError::Provider(ProviderError::Storyteller(err)))?;
|
||||
|
||||
Ok(GenerateVideoResponse {
|
||||
inference_job_token: response.inference_job_token,
|
||||
all_inference_job_tokens: response.all_inference_job_tokens,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod generate_video_artcraft_seedance2p0;
|
||||
@@ -0,0 +1 @@
|
||||
pub mod artcraft;
|
||||
@@ -0,0 +1 @@
|
||||
pub mod generate_video;
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod api;
|
||||
pub mod errors;
|
||||
pub mod generate;
|
||||
Reference in new issue
Block a user