mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-21 09:22:41 -04:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9dfbf13be0 | ||
|
|
ef4756c964 | ||
|
|
6049961465 |
+1
-1
@@ -3,7 +3,7 @@ use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const BYTEDANCE_SEEDREAM_V4_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/bytedance_seedream_v4";
|
||||
pub const BYTEDANCE_SEEDREAM_V4_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/bytedance_seedream_4";
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct BytedanceSeedreamV4MultiFunctionImageGenRequest {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const BYTEDANCE_SEEDREAM_V4P5_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/bytedance_seedream_v4p5";
|
||||
pub const BYTEDANCE_SEEDREAM_V4P5_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/bytedance_seedream_4p5";
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct BytedanceSeedreamV4p5MultiFunctionImageGenRequest {
|
||||
|
||||
-1
@@ -1,7 +1,6 @@
|
||||
use crate::core::commands::enqueue::common::notify_frontend_of_errors::notify_frontend_of_errors;
|
||||
use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError};
|
||||
use crate::core::commands::enqueue::image_bg_removal::generic::handle_generic_bg_removal::handle_generic_bg_removal;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit::handle_gpt_image_1_edit;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus};
|
||||
use crate::core::commands::response::shorthand::{Response, ResponseOrErrorType};
|
||||
|
||||
-2
@@ -3,8 +3,6 @@ use crate::core::commands::enqueue::image_bg_removal::enqueue_image_bg_removal_c
|
||||
use crate::core::commands::enqueue::image_bg_removal::generic::handle_generic_bg_removal_artcraft::handle_generic_bg_removal_artcraft;
|
||||
use crate::core::commands::enqueue::image_bg_removal::generic::handle_generic_bg_removal_fal::handle_generic_bg_removal_fal;
|
||||
use crate::core::commands::enqueue::image_edit::enqueue_edit_image_command::EnqueueEditImageCommand;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_artcraft::handle_gpt_image_1_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_sora::handle_gpt_image_1_edit_sora;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
|
||||
+40
-1
@@ -1,9 +1,12 @@
|
||||
use crate::core::commands::enqueue::common::notify_frontend_of_errors::notify_frontend_of_errors;
|
||||
use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError};
|
||||
use crate::core::commands::enqueue::image_edit::flux_kontext::handle_flux_kontext_edit::handle_flux_kontext_edit;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit::handle_gpt_image_1_edit;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image::handle_gpt_image_1_edit::handle_gpt_image_1_edit;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image::handle_gpt_image_1p5_artcraft::handle_gpt_image_1p5_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::nano_banana::handle_nano_banana_edit::handle_nano_banana_edit;
|
||||
use crate::core::commands::enqueue::image_edit::nano_banana_pro::handle_nano_banana_pro_edit::handle_nano_banana_pro_edit;
|
||||
use crate::core::commands::enqueue::image_edit::seedream::handle_seedream_4_artcraft::handle_seedream_4_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::seedream::handle_seedream_4p5_artcraft::handle_seedream_4p5_edit_artcraft;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus};
|
||||
use crate::core::commands::response::shorthand::{Response, ResponseOrErrorType};
|
||||
@@ -63,6 +66,15 @@ pub enum ImageEditModel {
|
||||
#[serde(rename = "gpt_image_1")]
|
||||
GptImage1,
|
||||
|
||||
#[serde(rename = "gpt_image_1p5")]
|
||||
GptImage1p5,
|
||||
|
||||
#[serde(rename = "seedream_4")]
|
||||
Seedream4,
|
||||
|
||||
#[serde(rename = "seedream_4p5")]
|
||||
Seedream4p5,
|
||||
|
||||
// #[serde(rename = "qwen")]
|
||||
// Qwen,
|
||||
//
|
||||
@@ -308,6 +320,33 @@ pub async fn handle_request(
|
||||
sora_task_queue,
|
||||
).await?
|
||||
}
|
||||
Some(ImageEditModel::GptImage1p5) => {
|
||||
handle_gpt_image_1p5_edit_artcraft(
|
||||
request,
|
||||
app,
|
||||
app_data_root,
|
||||
app_env_configs,
|
||||
storyteller_creds_manager,
|
||||
).await?
|
||||
}
|
||||
Some(ImageEditModel::Seedream4) => {
|
||||
handle_seedream_4_edit_artcraft(
|
||||
request,
|
||||
app,
|
||||
app_data_root,
|
||||
app_env_configs,
|
||||
storyteller_creds_manager,
|
||||
).await?
|
||||
}
|
||||
Some(ImageEditModel::Seedream4p5) => {
|
||||
handle_seedream_4p5_edit_artcraft(
|
||||
request,
|
||||
app,
|
||||
app_data_root,
|
||||
app_env_configs,
|
||||
storyteller_creds_manager,
|
||||
).await?
|
||||
}
|
||||
};
|
||||
|
||||
match request.frontend_caller {
|
||||
|
||||
-2
@@ -1,8 +1,6 @@
|
||||
use crate::core::commands::enqueue::generate_error::GenerateError;
|
||||
use crate::core::commands::enqueue::image_edit::enqueue_edit_image_command::EnqueueEditImageCommand;
|
||||
use crate::core::commands::enqueue::image_edit::flux_kontext::handle_flux_kontext_edit_artcraft::handle_flux_kontext_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_artcraft::handle_gpt_image_1_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_sora::handle_gpt_image_1_edit_sora;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
use crate::core::commands::enqueue::generate_error::GenerateError;
|
||||
use crate::core::commands::enqueue::image_edit::enqueue_edit_image_command::EnqueueEditImageCommand;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_artcraft::handle_gpt_image_1_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_sora::handle_gpt_image_1_edit_sora;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image::handle_gpt_image_1_edit_artcraft::handle_gpt_image_1_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image::handle_gpt_image_1_edit_sora::handle_gpt_image_1_edit_sora;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError};
|
||||
use crate::core::commands::enqueue::image_edit::enqueue_edit_image_command::{EditImageQuality, EditImageSize, EnqueueEditImageCommand};
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit::MAX_IMAGES;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image::handle_gpt_image_1_edit::MAX_IMAGES;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationModel, GenerationServiceProvider};
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError};
|
||||
use crate::core::commands::enqueue::image_edit::enqueue_edit_image_command::{EditImageSize, EnqueueEditImageCommand, EnqueueEditImageErrorType};
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit::MAX_IMAGES;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image::handle_gpt_image_1_edit::MAX_IMAGES;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus};
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError};
|
||||
use crate::core::commands::enqueue::image_edit::enqueue_edit_image_command::{EditImageQuality, EditImageSize, EnqueueEditImageCommand};
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image::handle_gpt_image_1_edit::MAX_IMAGES;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationModel, GenerationServiceProvider};
|
||||
use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent;
|
||||
use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::provider_priority::ProviderPriorityStore;
|
||||
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::image::multi_function::gpt_image_1p5_multi_function_image_gen::{GptImage1p5MultiFunctionImageGenNumImages, GptImage1p5MultiFunctionImageGenQuality, GptImage1p5MultiFunctionImageGenRequest, GptImage1p5MultiFunctionImageGenSize};
|
||||
use enums::common::generation_provider::GenerationProvider;
|
||||
use enums::tauri::tasks::task_type::TaskType;
|
||||
use idempotency::uuid::generate_random_uuid;
|
||||
use log::{error, info};
|
||||
use storyteller_client::endpoints::generate::image::edit::gpt_image_1_edit_image::gpt_image_1_edit_image;
|
||||
use storyteller_client::endpoints::generate::image::generate_flux_1_dev_text_to_image::generate_flux_1_dev_text_to_image;
|
||||
use storyteller_client::endpoints::generate::image::generate_flux_1_schnell_text_to_image::generate_flux_1_schnell_text_to_image;
|
||||
use storyteller_client::endpoints::generate::image::generate_flux_pro_11_text_to_image::generate_flux_pro_11_text_to_image;
|
||||
use storyteller_client::endpoints::generate::image::generate_flux_pro_11_ultra_text_to_image::generate_flux_pro_11_ultra_text_to_image;
|
||||
use storyteller_client::endpoints::generate::image::multi_function::gpt_image_1p5_multi_function_image_gen_image::gpt_image_1p5_multi_function_image_gen;
|
||||
use tauri::AppHandle;
|
||||
|
||||
pub async fn handle_gpt_image_1p5_edit_artcraft(
|
||||
request: &EnqueueEditImageCommand,
|
||||
app: &AppHandle,
|
||||
app_data_root: &AppDataRoot,
|
||||
app_env_configs: &AppEnvConfigs,
|
||||
storyteller_creds_manager: &StorytellerCredentialManager,
|
||||
) -> Result<TaskEnqueueSuccess, GenerateError> {
|
||||
|
||||
let creds = match storyteller_creds_manager.get_credentials()? {
|
||||
Some(creds) => creds,
|
||||
None => {
|
||||
return Err(GenerateError::needs_storyteller_credentials());
|
||||
},
|
||||
};
|
||||
|
||||
info!("Calling Artcraft gpt-image-1.5 (edit) ...");
|
||||
|
||||
let uuid_idempotency_token = generate_random_uuid();
|
||||
|
||||
let image_quality = request.image_quality
|
||||
.map(|quality| match quality {
|
||||
EditImageQuality::Auto => GptImage1p5MultiFunctionImageGenQuality::High,
|
||||
EditImageQuality::High => GptImage1p5MultiFunctionImageGenQuality::High,
|
||||
EditImageQuality::Medium => GptImage1p5MultiFunctionImageGenQuality::Medium,
|
||||
EditImageQuality::Low => GptImage1p5MultiFunctionImageGenQuality::Low,
|
||||
});
|
||||
|
||||
let image_size = request.aspect_ratio
|
||||
.map(|size| match size {
|
||||
EditImageSize::Auto => GptImage1p5MultiFunctionImageGenSize::Square,
|
||||
EditImageSize::Square => GptImage1p5MultiFunctionImageGenSize::Square,
|
||||
EditImageSize::Tall => GptImage1p5MultiFunctionImageGenSize::Tall,
|
||||
EditImageSize::Wide => GptImage1p5MultiFunctionImageGenSize::Wide,
|
||||
});
|
||||
|
||||
let num_images = match request.image_count {
|
||||
None => None,
|
||||
Some(1) => Some(GptImage1p5MultiFunctionImageGenNumImages::One),
|
||||
Some(2) => Some(GptImage1p5MultiFunctionImageGenNumImages::Two),
|
||||
Some(3) => Some(GptImage1p5MultiFunctionImageGenNumImages::Three),
|
||||
Some(4) => Some(GptImage1p5MultiFunctionImageGenNumImages::Four),
|
||||
Some(other) => {
|
||||
return Err(GenerateError::BadInput(BadInputReason::InvalidNumberOfRequestedImages {
|
||||
min: 1,
|
||||
max: 4,
|
||||
requested: other,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
let mut media_tokens = Vec::with_capacity(10);
|
||||
|
||||
if let Some(scene_image_media_token) = request.scene_image_media_token.clone() {
|
||||
media_tokens.push(scene_image_media_token);
|
||||
}
|
||||
|
||||
if let Some(image_media_tokens) = request.image_media_tokens.as_ref() {
|
||||
media_tokens.extend_from_slice(image_media_tokens);
|
||||
}
|
||||
|
||||
if media_tokens.len() > MAX_IMAGES {
|
||||
return Err(GenerateError::BadInput(BadInputReason::InvalidNumberOfInputImages {
|
||||
min: 1,
|
||||
max: MAX_IMAGES as u32,
|
||||
provided: media_tokens.len() as u32,
|
||||
}));
|
||||
}
|
||||
|
||||
let request = GptImage1p5MultiFunctionImageGenRequest {
|
||||
uuid_idempotency_token,
|
||||
prompt: Some(request.prompt.clone()),
|
||||
image_media_tokens: Some(media_tokens),
|
||||
quality: image_quality,
|
||||
image_size,
|
||||
num_images,
|
||||
// Only for inpainting
|
||||
mask_image_token: None,
|
||||
// Not provided
|
||||
input_fidelity: None,
|
||||
output_format: None,
|
||||
background: None,
|
||||
};
|
||||
|
||||
let result = gpt_image_1p5_multi_function_image_gen(
|
||||
&app_env_configs.storyteller_host,
|
||||
Some(&creds),
|
||||
request,
|
||||
).await;
|
||||
|
||||
let job_id = match result {
|
||||
Ok(enqueued) => {
|
||||
// TODO(bt,2025-07-05): Enqueue job token?
|
||||
info!("Successfully enqueued Artcraft gpt-image-1.5. Job token: {}",
|
||||
enqueued.inference_job_token);
|
||||
enqueued.inference_job_token
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Failed to use Artcraft gpt-image-1.5: {:?}", err);
|
||||
return Err(GenerateError::from(err));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(TaskEnqueueSuccess {
|
||||
provider: GenerationProvider::Artcraft,
|
||||
model: Some(GenerationModel::GptImage1p5),
|
||||
provider_job_id: Some(job_id.to_string()),
|
||||
task_type: TaskType::ImageGeneration,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
pub (super) mod handle_gpt_image_1_edit;
|
||||
pub (super) mod handle_gpt_image_1_edit_artcraft;
|
||||
pub (super) mod handle_gpt_image_1_edit_sora;
|
||||
pub (super) mod handle_gpt_image_1p5_artcraft;
|
||||
@@ -1,3 +0,0 @@
|
||||
pub mod handle_gpt_image_1_edit;
|
||||
pub mod handle_gpt_image_1_edit_artcraft;
|
||||
pub mod handle_gpt_image_1_edit_sora;
|
||||
@@ -1,5 +1,6 @@
|
||||
pub mod enqueue_edit_image_command;
|
||||
pub mod gpt_image_1;
|
||||
pub mod gpt_image;
|
||||
mod flux_kontext;
|
||||
mod nano_banana;
|
||||
mod nano_banana_pro;
|
||||
mod seedream;
|
||||
|
||||
-2
@@ -1,7 +1,5 @@
|
||||
use crate::core::commands::enqueue::generate_error::GenerateError;
|
||||
use crate::core::commands::enqueue::image_edit::enqueue_edit_image_command::EnqueueEditImageCommand;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_artcraft::handle_gpt_image_1_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_sora::handle_gpt_image_1_edit_sora;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError};
|
||||
use crate::core::commands::enqueue::image_edit::enqueue_edit_image_command::{EditImageQuality, EditImageSize, EnqueueEditImageCommand};
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationModel, GenerationServiceProvider};
|
||||
use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent;
|
||||
use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::provider_priority::ProviderPriorityStore;
|
||||
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::multi_function::bytedance_seedream_v4_multi_function_image_gen::{BytedanceSeedreamV4MultiFunctionImageGenImageSize, BytedanceSeedreamV4MultiFunctionImageGenNumImages, BytedanceSeedreamV4MultiFunctionImageGenRequest};
|
||||
use enums::common::generation_provider::GenerationProvider;
|
||||
use enums::tauri::tasks::task_type::TaskType;
|
||||
use idempotency::uuid::generate_random_uuid;
|
||||
use log::{error, info};
|
||||
use storyteller_client::endpoints::generate::image::multi_function::bytedance_seedream_v4_multi_function_image_gen_image::bytedance_seedream_v4_multi_function_image_gen;
|
||||
use tauri::AppHandle;
|
||||
|
||||
const MAX_IMAGES: usize = 4;
|
||||
|
||||
pub async fn handle_seedream_4_edit_artcraft(
|
||||
request: &EnqueueEditImageCommand,
|
||||
app: &AppHandle,
|
||||
app_data_root: &AppDataRoot,
|
||||
app_env_configs: &AppEnvConfigs,
|
||||
storyteller_creds_manager: &StorytellerCredentialManager,
|
||||
) -> Result<TaskEnqueueSuccess, GenerateError> {
|
||||
|
||||
let creds = match storyteller_creds_manager.get_credentials()? {
|
||||
Some(creds) => creds,
|
||||
None => {
|
||||
return Err(GenerateError::needs_storyteller_credentials());
|
||||
},
|
||||
};
|
||||
|
||||
info!("Calling Artcraft seedream 4 (edit) ...");
|
||||
|
||||
let uuid_idempotency_token = generate_random_uuid();
|
||||
|
||||
let image_size = request.aspect_ratio
|
||||
.map(|size| match size {
|
||||
EditImageSize::Auto => BytedanceSeedreamV4MultiFunctionImageGenImageSize::Square,
|
||||
EditImageSize::Square => BytedanceSeedreamV4MultiFunctionImageGenImageSize::Square,
|
||||
EditImageSize::Tall => BytedanceSeedreamV4MultiFunctionImageGenImageSize::PortraitSixteenNine,
|
||||
EditImageSize::Wide => BytedanceSeedreamV4MultiFunctionImageGenImageSize::LandscapeSixteenNine,
|
||||
});
|
||||
|
||||
let num_images = match request.image_count {
|
||||
None => None,
|
||||
Some(1) => Some(BytedanceSeedreamV4MultiFunctionImageGenNumImages::One),
|
||||
Some(2) => Some(BytedanceSeedreamV4MultiFunctionImageGenNumImages::Two),
|
||||
Some(3) => Some(BytedanceSeedreamV4MultiFunctionImageGenNumImages::Three),
|
||||
Some(4) => Some(BytedanceSeedreamV4MultiFunctionImageGenNumImages::Four),
|
||||
Some(other) => {
|
||||
return Err(GenerateError::BadInput(BadInputReason::InvalidNumberOfRequestedImages {
|
||||
min: 1,
|
||||
max: 4,
|
||||
requested: other,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
let mut media_tokens = Vec::with_capacity(10);
|
||||
|
||||
if let Some(scene_image_media_token) = request.scene_image_media_token.clone() {
|
||||
media_tokens.push(scene_image_media_token);
|
||||
}
|
||||
|
||||
if let Some(image_media_tokens) = request.image_media_tokens.as_ref() {
|
||||
media_tokens.extend_from_slice(image_media_tokens);
|
||||
}
|
||||
|
||||
if media_tokens.len() > MAX_IMAGES {
|
||||
return Err(GenerateError::BadInput(BadInputReason::InvalidNumberOfInputImages {
|
||||
min: 1,
|
||||
max: MAX_IMAGES as u32,
|
||||
provided: media_tokens.len() as u32,
|
||||
}));
|
||||
}
|
||||
|
||||
let request = BytedanceSeedreamV4MultiFunctionImageGenRequest {
|
||||
uuid_idempotency_token,
|
||||
prompt: Some(request.prompt.clone()),
|
||||
image_media_tokens: Some(media_tokens),
|
||||
image_size,
|
||||
num_images,
|
||||
// Not provided
|
||||
max_images: None,
|
||||
};
|
||||
|
||||
let result = bytedance_seedream_v4_multi_function_image_gen(
|
||||
&app_env_configs.storyteller_host,
|
||||
Some(&creds),
|
||||
request,
|
||||
).await;
|
||||
|
||||
let job_id = match result {
|
||||
Ok(enqueued) => {
|
||||
// TODO(bt,2025-07-05): Enqueue job token?
|
||||
info!("Successfully enqueued Artcraft seedream 4. Job token: {}",
|
||||
enqueued.inference_job_token);
|
||||
enqueued.inference_job_token
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Failed to use Artcraft seedream 4: {:?}", err);
|
||||
return Err(GenerateError::from(err));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(TaskEnqueueSuccess {
|
||||
provider: GenerationProvider::Artcraft,
|
||||
model: Some(GenerationModel::Seedream4),
|
||||
provider_job_id: Some(job_id.to_string()),
|
||||
task_type: TaskType::ImageGeneration,
|
||||
})
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError};
|
||||
use crate::core::commands::enqueue::image_edit::enqueue_edit_image_command::{EditImageQuality, EditImageSize, EnqueueEditImageCommand};
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::events::basic_sendable_event_trait::BasicSendableEvent;
|
||||
use crate::core::events::generation_events::common::{GenerationAction, GenerationModel, GenerationServiceProvider};
|
||||
use crate::core::events::generation_events::generation_enqueue_failure_event::GenerationEnqueueFailureEvent;
|
||||
use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::provider_priority::ProviderPriorityStore;
|
||||
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::multi_function::bytedance_seedream_v4p5_multi_function_image_gen::{BytedanceSeedreamV4p5MultiFunctionImageGenImageSize, BytedanceSeedreamV4p5MultiFunctionImageGenNumImages, BytedanceSeedreamV4p5MultiFunctionImageGenRequest};
|
||||
use enums::common::generation_provider::GenerationProvider;
|
||||
use enums::tauri::tasks::task_type::TaskType;
|
||||
use idempotency::uuid::generate_random_uuid;
|
||||
use log::{error, info};
|
||||
use storyteller_client::endpoints::generate::image::multi_function::bytedance_seedream_v4p5_multi_function_image_gen_image::bytedance_seedream_v4p5_multi_function_image_gen;
|
||||
use tauri::AppHandle;
|
||||
|
||||
const MAX_IMAGES: usize = 4;
|
||||
|
||||
pub async fn handle_seedream_4p5_edit_artcraft(
|
||||
request: &EnqueueEditImageCommand,
|
||||
app: &AppHandle,
|
||||
app_data_root: &AppDataRoot,
|
||||
app_env_configs: &AppEnvConfigs,
|
||||
storyteller_creds_manager: &StorytellerCredentialManager,
|
||||
) -> Result<TaskEnqueueSuccess, GenerateError> {
|
||||
|
||||
let creds = match storyteller_creds_manager.get_credentials()? {
|
||||
Some(creds) => creds,
|
||||
None => {
|
||||
return Err(GenerateError::needs_storyteller_credentials());
|
||||
},
|
||||
};
|
||||
|
||||
info!("Calling Artcraft seedream 4.5 (edit) ...");
|
||||
|
||||
let uuid_idempotency_token = generate_random_uuid();
|
||||
|
||||
let image_size = request.aspect_ratio
|
||||
.map(|size| match size {
|
||||
EditImageSize::Auto => BytedanceSeedreamV4p5MultiFunctionImageGenImageSize::Square,
|
||||
EditImageSize::Square => BytedanceSeedreamV4p5MultiFunctionImageGenImageSize::Square,
|
||||
EditImageSize::Tall => BytedanceSeedreamV4p5MultiFunctionImageGenImageSize::PortraitSixteenNine,
|
||||
EditImageSize::Wide => BytedanceSeedreamV4p5MultiFunctionImageGenImageSize::LandscapeSixteenNine,
|
||||
});
|
||||
|
||||
let num_images = match request.image_count {
|
||||
None => None,
|
||||
Some(1) => Some(BytedanceSeedreamV4p5MultiFunctionImageGenNumImages::One),
|
||||
Some(2) => Some(BytedanceSeedreamV4p5MultiFunctionImageGenNumImages::Two),
|
||||
Some(3) => Some(BytedanceSeedreamV4p5MultiFunctionImageGenNumImages::Three),
|
||||
Some(4) => Some(BytedanceSeedreamV4p5MultiFunctionImageGenNumImages::Four),
|
||||
Some(other) => {
|
||||
return Err(GenerateError::BadInput(BadInputReason::InvalidNumberOfRequestedImages {
|
||||
min: 1,
|
||||
max: 4,
|
||||
requested: other,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
let mut media_tokens = Vec::with_capacity(10);
|
||||
|
||||
if let Some(scene_image_media_token) = request.scene_image_media_token.clone() {
|
||||
media_tokens.push(scene_image_media_token);
|
||||
}
|
||||
|
||||
if let Some(image_media_tokens) = request.image_media_tokens.as_ref() {
|
||||
media_tokens.extend_from_slice(image_media_tokens);
|
||||
}
|
||||
|
||||
if media_tokens.len() > MAX_IMAGES {
|
||||
return Err(GenerateError::BadInput(BadInputReason::InvalidNumberOfInputImages {
|
||||
min: 1,
|
||||
max: MAX_IMAGES as u32,
|
||||
provided: media_tokens.len() as u32,
|
||||
}));
|
||||
}
|
||||
|
||||
let request = BytedanceSeedreamV4p5MultiFunctionImageGenRequest {
|
||||
uuid_idempotency_token,
|
||||
prompt: Some(request.prompt.clone()),
|
||||
image_media_tokens: Some(media_tokens),
|
||||
image_size,
|
||||
num_images,
|
||||
// Not provided
|
||||
max_images: None,
|
||||
};
|
||||
|
||||
let result = bytedance_seedream_v4p5_multi_function_image_gen(
|
||||
&app_env_configs.storyteller_host,
|
||||
Some(&creds),
|
||||
request,
|
||||
).await;
|
||||
|
||||
let job_id = match result {
|
||||
Ok(enqueued) => {
|
||||
// TODO(bt,2025-07-05): Enqueue job token?
|
||||
info!("Successfully enqueued Artcraft seedream 4.5. Job token: {}",
|
||||
enqueued.inference_job_token);
|
||||
enqueued.inference_job_token
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Failed to use Artcraft seedream 4.5: {:?}", err);
|
||||
return Err(GenerateError::from(err));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(TaskEnqueueSuccess {
|
||||
provider: GenerationProvider::Artcraft,
|
||||
model: Some(GenerationModel::Seedream4p5),
|
||||
provider_job_id: Some(job_id.to_string()),
|
||||
task_type: TaskType::ImageGeneration,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub (super) mod handle_seedream_4p5_artcraft;
|
||||
pub (super) mod handle_seedream_4_artcraft;
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
use crate::core::commands::enqueue::common::notify_frontend_of_errors::notify_frontend_of_errors;
|
||||
use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError};
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit::handle_gpt_image_1_edit;
|
||||
use crate::core::commands::enqueue::image_inpaint::flux_dev_juggernaut_inpaint::handle_flux_dev_juggernaut_inpaint::handle_flux_dev_juggernaut_inpaint;
|
||||
use crate::core::commands::enqueue::image_inpaint::flux_pro_1_inpaint::handle_flux_pro_1_inpaint::handle_flux_pro_1_inpaint;
|
||||
use crate::core::commands::enqueue::image_inpaint::flux_pro_kontext_inpaint::handle_flux_pro_kontext_inpaint::handle_flux_pro_kontext_inpaint;
|
||||
|
||||
-2
@@ -1,7 +1,5 @@
|
||||
use crate::core::commands::enqueue::generate_error::GenerateError;
|
||||
use crate::core::commands::enqueue::image_edit::enqueue_edit_image_command::EnqueueEditImageCommand;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_artcraft::handle_gpt_image_1_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_sora::handle_gpt_image_1_edit_sora;
|
||||
use crate::core::commands::enqueue::image_inpaint::enqueue_image_inpaint_command::EnqueueInpaintImageCommand;
|
||||
use crate::core::commands::enqueue::image_inpaint::flux_dev_juggernaut_inpaint::handle_flux_dev_juggernaut_inpaint_artcraft::handle_flux_dev_juggernaut_inpaint_artcraft;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
|
||||
-2
@@ -1,7 +1,5 @@
|
||||
use crate::core::commands::enqueue::generate_error::GenerateError;
|
||||
use crate::core::commands::enqueue::image_edit::enqueue_edit_image_command::EnqueueEditImageCommand;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_artcraft::handle_gpt_image_1_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_sora::handle_gpt_image_1_edit_sora;
|
||||
use crate::core::commands::enqueue::image_inpaint::enqueue_image_inpaint_command::EnqueueInpaintImageCommand;
|
||||
use crate::core::commands::enqueue::image_inpaint::flux_pro_1_inpaint::handle_flux_pro_1_inpaint_artcraft::handle_flux_pro_1_inpaint_artcraft;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
|
||||
-2
@@ -1,6 +1,4 @@
|
||||
use crate::core::commands::enqueue::generate_error::GenerateError;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_artcraft::handle_gpt_image_1_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_sora::handle_gpt_image_1_edit_sora;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::commands::enqueue::text_to_image::enqueue_text_to_image_command::{EnqueueTextToImageRequest, TextToImageSize};
|
||||
use crate::core::commands::enqueue::text_to_image::gpt_image::handle_gpt_image_1_artcraft::handle_gpt_image_1_artcraft;
|
||||
|
||||
-2
@@ -1,6 +1,4 @@
|
||||
use crate::core::commands::enqueue::generate_error::GenerateError;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_artcraft::handle_gpt_image_1_edit_artcraft;
|
||||
use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_sora::handle_gpt_image_1_edit_sora;
|
||||
use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess;
|
||||
use crate::core::commands::enqueue::text_to_image::enqueue_text_to_image_command::{EnqueueTextToImageRequest, TextToImageSize};
|
||||
use crate::core::commands::enqueue::text_to_image::nano_banana::handle_nano_banana_artcraft::handle_nano_banana_artcraft;
|
||||
|
||||
@@ -159,6 +159,60 @@ export const IMAGE_MODELS: ImageModel[] = [
|
||||
progressBarTime: 60000,
|
||||
canChangeAspectRatio: true,
|
||||
}),
|
||||
new ImageModel({
|
||||
id: "gpt_image_1p5",
|
||||
tauriId: "gpt_image_1p5",
|
||||
fullName: "GPT Image 1.5",
|
||||
category: "image",
|
||||
creator: ModelCreator.OpenAi,
|
||||
selectorName: "GPT Image 1.5",
|
||||
selectorDescription: "Faster, improved",
|
||||
selectorBadges: ["60 sec."],
|
||||
maxGenerationCount: 4,
|
||||
defaultGenerationCount: 1,
|
||||
tags: [ModelTag.InstructiveEdit],
|
||||
canEditImages: true,
|
||||
canUseImagePrompt: true,
|
||||
maxImagePromptCount: 6,
|
||||
progressBarTime: 60000,
|
||||
canChangeAspectRatio: true,
|
||||
}),
|
||||
new ImageModel({
|
||||
id: "seedream_4",
|
||||
tauriId: "seedream_4",
|
||||
fullName: "Seedream 4",
|
||||
category: "image",
|
||||
creator: ModelCreator.OpenAi,
|
||||
selectorName: "Seedream 4",
|
||||
selectorDescription: "Fast",
|
||||
selectorBadges: ["60 sec."],
|
||||
maxGenerationCount: 4,
|
||||
defaultGenerationCount: 1,
|
||||
tags: [ModelTag.InstructiveEdit],
|
||||
canEditImages: true,
|
||||
canUseImagePrompt: true,
|
||||
maxImagePromptCount: 6,
|
||||
progressBarTime: 60000,
|
||||
canChangeAspectRatio: true,
|
||||
}),
|
||||
new ImageModel({
|
||||
id: "seedream_4p5",
|
||||
tauriId: "seedream_4p5",
|
||||
fullName: "Seedream 4.5",
|
||||
category: "image",
|
||||
creator: ModelCreator.OpenAi,
|
||||
selectorName: "Seedream 4.5",
|
||||
selectorDescription: "Fast",
|
||||
selectorBadges: ["60 sec."],
|
||||
maxGenerationCount: 4,
|
||||
defaultGenerationCount: 1,
|
||||
tags: [ModelTag.InstructiveEdit],
|
||||
canEditImages: true,
|
||||
canUseImagePrompt: true,
|
||||
maxImagePromptCount: 6,
|
||||
progressBarTime: 60000,
|
||||
canChangeAspectRatio: true,
|
||||
}),
|
||||
new ImageModel({
|
||||
id: "flux_pro_kontext_max",
|
||||
tauriId: "flux_pro_kontext_max",
|
||||
|
||||
Reference in New Issue
Block a user