diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image/enqueue_text_to_image_command.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image/enqueue_text_to_image_command.rs index 40711b643a..9ea18682a5 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/image/enqueue_text_to_image_command.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/image/enqueue_text_to_image_command.rs @@ -74,8 +74,13 @@ pub enum EnqueueTextToImageModel { Flux1Dev, #[serde(rename = "flux_1_schnell")] Flux1Schnell, + #[deprecated(note="use `flux_pro_11_ultra` instead")] #[serde(rename = "flux_pro_ultra")] FluxProUltra, + #[serde(rename = "flux_pro_11")] + FluxPro11, + #[serde(rename = "flux_pro_11_ultra")] + FluxPro11Ultra, #[serde(rename = "gpt_image_1")] GptImage1, #[serde(rename = "recraft_3")] diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image/handle_image_artcraft.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image/handle_image_artcraft.rs index a685c0075e..e4b8cfaaf9 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/image/handle_image_artcraft.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/image/handle_image_artcraft.rs @@ -13,6 +13,9 @@ use crate::services::sora::state::sora_credential_manager::SoraCredentialManager use crate::services::sora::state::sora_task_queue::SoraTaskQueue; use crate::services::storyteller::state::storyteller_credential_manager::StorytellerCredentialManager; use anyhow::anyhow; +use artcraft_api_defs::generate::image::generate_flux_1_dev_text_to_image::GenerateFlux1DevTextToImageRequest; +use artcraft_api_defs::generate::image::generate_flux_1_schnell_text_to_image::GenerateFlux1SchnellTextToImageRequest; +use artcraft_api_defs::generate::image::generate_flux_pro_11_text_to_image::GenerateFluxPro11TextToImageRequest; use artcraft_api_defs::generate::image::generate_flux_pro_11_ultra_text_to_image::GenerateFluxPro11UltraTextToImageRequest; use artcraft_api_defs::generate::object::generate_hunyuan_2_image_to_3d::GenerateHunyuan2ImageTo3dRequest; use artcraft_api_defs::generate::video::generate_kling_1_6_pro_image_to_video::GenerateKling16ProImageToVideoRequest; @@ -22,15 +25,14 @@ use fal_client::requests::queue::image_gen::enqueue_flux_pro_11_ultra_text_to_im use fal_client::requests::queue::image_gen::enqueue_recraft3_text_to_image::{enqueue_recraft3_text_to_image, Recraft3TextToImageArgs}; use idempotency::uuid::generate_random_uuid; use log::{error, info, warn}; +use storyteller_client::generate::image::generate_flux_1_dev_text_to_image::generate_flux_1_dev_text_to_image; +use storyteller_client::generate::image::generate_flux_1_schnell_text_to_image::generate_flux_1_schnell_text_to_image; +use storyteller_client::generate::image::generate_flux_pro_11_text_to_image::generate_flux_pro_11_text_to_image; use storyteller_client::generate::image::generate_flux_pro_11_ultra_text_to_image::generate_flux_pro_11_ultra_text_to_image; use storyteller_client::generate::object::generate_hunyuan2_image_to_3d::generate_hunyuan2_image_to_3d; use storyteller_client::generate::video::generate_kling_16_pro_image_to_video::generate_kling_16_pro_image_to_video; use storyteller_client::utils::api_host::ApiHost; use tauri::{AppHandle, State}; -use artcraft_api_defs::generate::image::generate_flux_1_dev_text_to_image::GenerateFlux1DevTextToImageRequest; -use artcraft_api_defs::generate::image::generate_flux_1_schnell_text_to_image::GenerateFlux1SchnellTextToImageRequest; -use storyteller_client::generate::image::generate_flux_1_dev_text_to_image::generate_flux_1_dev_text_to_image; -use storyteller_client::generate::image::generate_flux_1_schnell_text_to_image::generate_flux_1_schnell_text_to_image; pub async fn handle_image_artcraft( request: EnqueueTextToImageRequest, @@ -120,8 +122,36 @@ pub async fn handle_image_artcraft( } } } - Some(EnqueueTextToImageModel::FluxProUltra) => { - info!("enqueue Flux Pro Ultra"); + Some(EnqueueTextToImageModel::FluxPro11) => { + info!("enqueue Flux Pro 1.1"); + selected_model = Some(GenerationModel::FluxPro11); + let request = GenerateFluxPro11TextToImageRequest { + uuid_idempotency_token, + prompt: request.prompt, + aspect_ratio: None, + num_images: None, + }; + let result = generate_flux_pro_11_text_to_image( + &ApiHost::Storyteller, + Some(&creds), + request, + ).await; + match result { + Ok(enqueued) => { + info!("Successfully enqueued Artcraft Flux Pro 1.1 text to image generation"); + enqueued.inference_job_token + } + Err(err) => { + error!("Failed to use Artcraft Flux Pro 1.1 text to image generation: {:?}", err); + return Err(InternalImageError::StorytellerError(err)); + } + } + } + Some( + EnqueueTextToImageModel::FluxProUltra | + EnqueueTextToImageModel::FluxPro11Ultra + ) => { + info!("enqueue Flux Pro 1.1 Ultra"); selected_model = Some(GenerationModel::FluxPro11Ultra); let request = GenerateFluxPro11UltraTextToImageRequest { uuid_idempotency_token, @@ -136,11 +166,11 @@ pub async fn handle_image_artcraft( ).await; match result { Ok(enqueued) => { - info!("Successfully enqueued Artcraft flux pro ultra text to image generation"); + info!("Successfully enqueued Artcraft Flux Pro 1.1 Ultra text to image generation"); enqueued.inference_job_token } Err(err) => { - error!("Failed to use Artcraft flux pro ultra text to image generation: {:?}", err); + error!("Failed to use Artcraft Flux Pro 1.1 Ultra text to image generation: {:?}", err); return Err(InternalImageError::StorytellerError(err)); } } diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image/handle_image_fal.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image/handle_image_fal.rs index 4fd85a1ac8..09b1ba23f1 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/image/handle_image_fal.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/image/handle_image_fal.rs @@ -56,12 +56,16 @@ pub async fn handle_image_fal( } Some( EnqueueTextToImageModel::Flux1Dev | - EnqueueTextToImageModel::Flux1Schnell + EnqueueTextToImageModel::Flux1Schnell | + EnqueueTextToImageModel::FluxPro11 ) => { return Err(InternalImageError::AnyhowError(anyhow!("not yet implemented: {:?}", request.model))); } - Some(EnqueueTextToImageModel::FluxProUltra) => { - info!("enqueue Flux Pro Ultra text-to-image with prompt: {}", prompt); + Some( + EnqueueTextToImageModel::FluxProUltra | + EnqueueTextToImageModel::FluxPro11Ultra + ) => { + info!("enqueue Flux Pro 1.1 Ultra text-to-image with prompt: {}", prompt); enqueue_flux_pro_11_ultra_text_to_image(FluxPro11UltraTextToImageArgs { prompt, api_key: &api_key, diff --git a/crates/desktop/artcraft/src/core/events/generation_events/common.rs b/crates/desktop/artcraft/src/core/events/generation_events/common.rs index c7bf4bfa57..c25ab4bd04 100644 --- a/crates/desktop/artcraft/src/core/events/generation_events/common.rs +++ b/crates/desktop/artcraft/src/core/events/generation_events/common.rs @@ -15,6 +15,8 @@ pub enum GenerationModel { Flux1Dev, #[serde(rename = "flux_1_schnell")] Flux1Schnell, + #[serde(rename = "flux_pro_1.1")] + FluxPro11, #[serde(rename = "flux_pro_1.1_ultra")] FluxPro11Ultra, #[serde(rename = "kling_1.6")] diff --git a/crates/lib/api_clients/storyteller_client/src/generate/image/generate_flux_pro_11_text_to_image.rs b/crates/lib/api_clients/storyteller_client/src/generate/image/generate_flux_pro_11_text_to_image.rs new file mode 100644 index 0000000000..250e7ab550 --- /dev/null +++ b/crates/lib/api_clients/storyteller_client/src/generate/image/generate_flux_pro_11_text_to_image.rs @@ -0,0 +1,68 @@ +use crate::credentials::storyteller_credential_set::StorytellerCredentialSet; +use crate::error::api_error::ApiError; +use crate::error::client_error::ClientError; +use crate::error::storyteller_error::StorytellerError; +use crate::utils::api_host::ApiHost; +use crate::utils::constants::{APPLICATION_JSON, USER_AGENT}; +use crate::utils::filter_bad_response::filter_bad_response; +use artcraft_api_defs::generate::image::generate_flux_pro_11_text_to_image::{GenerateFluxPro11TextToImageRequest, GenerateFluxPro11TextToImageResponse, GENERATE_FLUX_PRO_11_TEXT_TO_IMAGE_PATH}; +use log::{debug, info}; +use reqwest::Client; + +pub async fn generate_flux_pro_11_text_to_image( + api_host: &ApiHost, + maybe_creds: Option<&StorytellerCredentialSet>, + request: GenerateFluxPro11TextToImageRequest, +) -> Result { + + let url = get_route(api_host); + + info!("Requesting {:?}", &url); + + let client = Client::builder() + .gzip(true) + .build() + .map_err(|err| StorytellerError::Client(ClientError::from(err)))?; + + let mut request_builder = client.post(url) + .header("User-Agent", USER_AGENT) + .header("Accept", APPLICATION_JSON) + .header("Content-Type", APPLICATION_JSON); + + if let Some(creds) = maybe_creds { + if let Some(header) = &creds.maybe_as_cookie_header() { + request_builder = request_builder.header("Cookie", header); + } + } + + let request_body = serde_json::to_string(&request) + .map_err(|err| StorytellerError::Client(ClientError::from(err)))?; + + debug!("Request body: {:?}", request_body); + + let response = request_builder + .body(request_body) + .send() + .await + .map_err(|err| StorytellerError::Api(ApiError::from(err)))?; + + let response = filter_bad_response(response) + .await + .map_err(|err| StorytellerError::Api(ApiError::from(err)))?; + + let response_body = &response.text() + .await + .map_err(|err| StorytellerError::Api(ApiError::from(err)))?; + + debug!("Response body: {:?}", response_body); + + let response = serde_json::from_str(&response_body) + .map_err(|err| StorytellerError::Api(ApiError::from(err)))?; + + Ok(response) +} + +fn get_route(api_host: &ApiHost) -> String { + let api_hostname = api_host.to_api_hostname(); + format!("https://{}{}", api_hostname, GENERATE_FLUX_PRO_11_TEXT_TO_IMAGE_PATH) +} diff --git a/crates/lib/api_clients/storyteller_client/src/generate/image/mod.rs b/crates/lib/api_clients/storyteller_client/src/generate/image/mod.rs index 362fe356d9..8a6a0561c6 100644 --- a/crates/lib/api_clients/storyteller_client/src/generate/image/mod.rs +++ b/crates/lib/api_clients/storyteller_client/src/generate/image/mod.rs @@ -1,3 +1,4 @@ pub mod generate_flux_1_dev_text_to_image; pub mod generate_flux_1_schnell_text_to_image; +pub mod generate_flux_pro_11_text_to_image; pub mod generate_flux_pro_11_ultra_text_to_image; \ No newline at end of file