diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/video/handle_video_artcraft.rs b/crates/desktop/artcraft/src/core/commands/enqueue/video/handle_video_artcraft.rs index 98543bf10d..1c8bc6fe4a 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/video/handle_video_artcraft.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/video/handle_video_artcraft.rs @@ -131,7 +131,6 @@ pub async fn handle_video_artcraft( } } Some(VideoModel::Kling21Pro) => { - info!("enqueue Kling 2.1 Pro with Artcraft API"); selected_model = Some(GenerationModel::Kling21Pro); let request = GenerateKling21ProImageToVideoRequest { diff --git a/crates/lib/api_clients/storyteller_client/src/generate/object/generate_hunyuan_3d_2_0_image_to_3d.rs b/crates/lib/api_clients/storyteller_client/src/generate/object/generate_hunyuan_3d_2_0_image_to_3d.rs index 1a5480af37..5b92bc41a0 100644 --- a/crates/lib/api_clients/storyteller_client/src/generate/object/generate_hunyuan_3d_2_0_image_to_3d.rs +++ b/crates/lib/api_clients/storyteller_client/src/generate/object/generate_hunyuan_3d_2_0_image_to_3d.rs @@ -1,68 +1,18 @@ 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 crate::utils::basic_json_post_request::basic_json_post_request; use artcraft_api_defs::generate::object::generate_hunyuan_2_0_image_to_3d::{GenerateHunyuan20ImageTo3dRequest, GenerateHunyuan20ImageTo3dResponse, GENERATE_HUNYUAN_2_0_IMAGE_TO_3D_URL_PATH}; -use log::{debug, info}; -use reqwest::Client; pub async fn generate_hunyuan3d_2_0_image_to_3d( api_host: &ApiHost, maybe_creds: Option<&StorytellerCredentialSet>, request: GenerateHunyuan20ImageTo3dRequest, ) -> 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_HUNYUAN_2_0_IMAGE_TO_3D_URL_PATH) + Ok(basic_json_post_request( + api_host, + GENERATE_HUNYUAN_2_0_IMAGE_TO_3D_URL_PATH, + maybe_creds, + request, + ).await?) } diff --git a/crates/lib/api_clients/storyteller_client/src/generate/object/generate_hunyuan_3d_2_1_image_to_3d.rs b/crates/lib/api_clients/storyteller_client/src/generate/object/generate_hunyuan_3d_2_1_image_to_3d.rs index cffe72ebaf..d8fcacd3d3 100644 --- a/crates/lib/api_clients/storyteller_client/src/generate/object/generate_hunyuan_3d_2_1_image_to_3d.rs +++ b/crates/lib/api_clients/storyteller_client/src/generate/object/generate_hunyuan_3d_2_1_image_to_3d.rs @@ -1,68 +1,18 @@ 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 crate::utils::basic_json_post_request::basic_json_post_request; use artcraft_api_defs::generate::object::generate_hunyuan_2_1_image_to_3d::{GenerateHunyuan21ImageTo3dRequest, GenerateHunyuan21ImageTo3dResponse, GENERATE_HUNYUAN_2_1_IMAGE_TO_3D_URL_PATH}; -use log::{debug, info}; -use reqwest::Client; pub async fn generate_hunyuan3d_2_1_image_to_3d( api_host: &ApiHost, maybe_creds: Option<&StorytellerCredentialSet>, request: GenerateHunyuan21ImageTo3dRequest, ) -> 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_HUNYUAN_2_1_IMAGE_TO_3D_URL_PATH) + Ok(basic_json_post_request( + api_host, + GENERATE_HUNYUAN_2_1_IMAGE_TO_3D_URL_PATH, + maybe_creds, + request, + ).await?) } diff --git a/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_16_pro_image_to_video.rs b/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_16_pro_image_to_video.rs index c3164adf65..96d0247d66 100644 --- a/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_16_pro_image_to_video.rs +++ b/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_16_pro_image_to_video.rs @@ -1,68 +1,18 @@ 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 crate::utils::basic_json_post_request::basic_json_post_request; use artcraft_api_defs::generate::video::generate_kling_1_6_pro_image_to_video::{GenerateKling16ProImageToVideoRequest, GenerateKling16ProImageToVideoResponse, GENERATE_KLING_1_6_PRO_IMAGE_TO_VIDEO_URL_PATH}; -use log::{debug, info}; -use reqwest::Client; pub async fn generate_kling_16_pro_image_to_video( api_host: &ApiHost, maybe_creds: Option<&StorytellerCredentialSet>, request: GenerateKling16ProImageToVideoRequest, ) -> 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_KLING_1_6_PRO_IMAGE_TO_VIDEO_URL_PATH) + Ok(basic_json_post_request( + api_host, + GENERATE_KLING_1_6_PRO_IMAGE_TO_VIDEO_URL_PATH, + maybe_creds, + request, + ).await?) } diff --git a/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_21_master_image_to_video.rs b/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_21_master_image_to_video.rs index 598084fb39..10af6506d0 100644 --- a/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_21_master_image_to_video.rs +++ b/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_21_master_image_to_video.rs @@ -1,68 +1,18 @@ 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 crate::utils::basic_json_post_request::basic_json_post_request; use artcraft_api_defs::generate::video::generate_kling_2_1_master_image_to_video::{GenerateKling21MasterImageToVideoRequest, GenerateKling21MasterImageToVideoResponse, GENERATE_KLING_2_1_MASTER_IMAGE_TO_VIDEO_URL_PATH}; -use log::{debug, info}; -use reqwest::Client; pub async fn generate_kling_21_master_image_to_video( api_host: &ApiHost, maybe_creds: Option<&StorytellerCredentialSet>, request: GenerateKling21MasterImageToVideoRequest, ) -> 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_KLING_2_1_MASTER_IMAGE_TO_VIDEO_URL_PATH) + Ok(basic_json_post_request( + api_host, + GENERATE_KLING_2_1_MASTER_IMAGE_TO_VIDEO_URL_PATH, + maybe_creds, + request, + ).await?) } diff --git a/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_21_pro_image_to_video.rs b/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_21_pro_image_to_video.rs index 0570a58f13..098401113f 100644 --- a/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_21_pro_image_to_video.rs +++ b/crates/lib/api_clients/storyteller_client/src/generate/video/generate_kling_21_pro_image_to_video.rs @@ -1,68 +1,18 @@ 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 crate::utils::basic_json_post_request::basic_json_post_request; use artcraft_api_defs::generate::video::generate_kling_2_1_pro_image_to_video::{GenerateKling21ProImageToVideoRequest, GenerateKling21ProImageToVideoResponse, GENERATE_KLING_2_1_PRO_IMAGE_TO_VIDEO_URL_PATH}; -use log::{debug, info}; -use reqwest::Client; pub async fn generate_kling_21_pro_image_to_video( api_host: &ApiHost, maybe_creds: Option<&StorytellerCredentialSet>, request: GenerateKling21ProImageToVideoRequest, ) -> 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_KLING_2_1_PRO_IMAGE_TO_VIDEO_URL_PATH) + Ok(basic_json_post_request( + api_host, + GENERATE_KLING_2_1_PRO_IMAGE_TO_VIDEO_URL_PATH, + maybe_creds, + request, + ).await?) } diff --git a/crates/lib/api_clients/storyteller_client/src/generate/video/generate_seedance_1_0_lite_image_to_video.rs b/crates/lib/api_clients/storyteller_client/src/generate/video/generate_seedance_1_0_lite_image_to_video.rs index 4b2c436114..743bea4e81 100644 --- a/crates/lib/api_clients/storyteller_client/src/generate/video/generate_seedance_1_0_lite_image_to_video.rs +++ b/crates/lib/api_clients/storyteller_client/src/generate/video/generate_seedance_1_0_lite_image_to_video.rs @@ -1,68 +1,18 @@ 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 crate::utils::basic_json_post_request::basic_json_post_request; use artcraft_api_defs::generate::video::generate_seedance_1_0_lite_image_to_video::{GenerateSeedance10LiteImageToVideoRequest, GenerateSeedance10LiteImageToVideoResponse, GENERATE_SEEDANCE_1_0_LITE_IMAGE_TO_VIDEO_URL_PATH}; -use log::{debug, info}; -use reqwest::Client; pub async fn generate_seedance_1_0_lite_image_to_video( api_host: &ApiHost, maybe_creds: Option<&StorytellerCredentialSet>, request: GenerateSeedance10LiteImageToVideoRequest, ) -> 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_SEEDANCE_1_0_LITE_IMAGE_TO_VIDEO_URL_PATH) + Ok(basic_json_post_request( + api_host, + GENERATE_SEEDANCE_1_0_LITE_IMAGE_TO_VIDEO_URL_PATH, + maybe_creds, + request, + ).await?) } diff --git a/crates/lib/api_clients/storyteller_client/src/generate/video/generate_veo_2_image_to_video.rs b/crates/lib/api_clients/storyteller_client/src/generate/video/generate_veo_2_image_to_video.rs index 03c06d6a99..cb7897fb53 100644 --- a/crates/lib/api_clients/storyteller_client/src/generate/video/generate_veo_2_image_to_video.rs +++ b/crates/lib/api_clients/storyteller_client/src/generate/video/generate_veo_2_image_to_video.rs @@ -1,68 +1,18 @@ 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 crate::utils::basic_json_post_request::basic_json_post_request; use artcraft_api_defs::generate::video::generate_veo_2_image_to_video::{GenerateVeo2ImageToVideoRequest, GenerateVeo2ImageToVideoResponse, GENERATE_VEO_2_IMAGE_TO_VIDEO_URL_PATH}; -use log::{debug, info}; -use reqwest::Client; pub async fn generate_veo_2_image_to_video( api_host: &ApiHost, maybe_creds: Option<&StorytellerCredentialSet>, request: GenerateVeo2ImageToVideoRequest, ) -> 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_VEO_2_IMAGE_TO_VIDEO_URL_PATH) + Ok(basic_json_post_request( + api_host, + GENERATE_VEO_2_IMAGE_TO_VIDEO_URL_PATH, + maybe_creds, + request, + ).await?) } diff --git a/frontend/apps/editor3d/app/src/pages/PageImage/TextToImage.tsx b/frontend/apps/editor3d/app/src/pages/PageImage/TextToImage.tsx index c0c6279806..a599f7edea 100644 --- a/frontend/apps/editor3d/app/src/pages/PageImage/TextToImage.tsx +++ b/frontend/apps/editor3d/app/src/pages/PageImage/TextToImage.tsx @@ -26,11 +26,6 @@ const TextToImage = ({ imageMediaId, imageUrl }: TextToImageProps) => { const selectedModelInfo : ModelInfo | undefined = IMAGE_MODELS_BY_LABEL[selectedModel]; - console.log("TextToImage - selectedModels", selectedModels); - console.log("TextToImage - selectedModel", selectedModel); - console.log("TextToImage - selectedModelInfo", selectedModelInfo); - - const jobContext: JobContextType = { jobTokens: [], addJobToken: () => {}, diff --git a/frontend/apps/editor3d/app/src/pages/PageVideo/ImageToVideo.tsx b/frontend/apps/editor3d/app/src/pages/PageVideo/ImageToVideo.tsx index 70b46e5c81..e59df75b11 100644 --- a/frontend/apps/editor3d/app/src/pages/PageVideo/ImageToVideo.tsx +++ b/frontend/apps/editor3d/app/src/pages/PageVideo/ImageToVideo.tsx @@ -8,6 +8,8 @@ import { useModelSelectorStore, videoGenerationModels, } from "@storyteller/ui-model-selector"; +import { VIDEO_MODELS_BY_LABEL } from "@storyteller/model-list"; +import { ModelInfo } from "@storyteller/model-list"; interface ImageToVideoProps { imageMediaId?: string; @@ -17,13 +19,12 @@ interface ImageToVideoProps { const ImageToVideo = ({ imageMediaId, imageUrl }: ImageToVideoProps) => { const containerRef = useRef(null); const { selectedModels } = useModelSelectorStore(); + const selectedModel = selectedModels[ModelCategory.ImageToVideo] || videoGenerationModels[0]?.label; - console.log("Selected model:", selectedModel) - console.log("Image Media Id:", imageMediaId) - console.log("Image URL:", imageUrl) + const selectedModelInfo : ModelInfo | undefined = VIDEO_MODELS_BY_LABEL[selectedModel]; const jobContext: JobContextType = { jobTokens: [], @@ -53,6 +54,7 @@ const ImageToVideo = ({ imageMediaId, imageUrl }: ImageToVideoProps) => { return jobContext; }} model={selectedModel} + modelInfo={selectedModelInfo} imageMediaId={imageMediaId} url={imageUrl ?? undefined} onEnqueuePressed={async () => { diff --git a/frontend/libs/components/promptbox/src/lib/PromptBoxVideo.tsx b/frontend/libs/components/promptbox/src/lib/PromptBoxVideo.tsx index 6fd173dadb..33088159c1 100644 --- a/frontend/libs/components/promptbox/src/lib/PromptBoxVideo.tsx +++ b/frontend/libs/components/promptbox/src/lib/PromptBoxVideo.tsx @@ -6,7 +6,7 @@ import { PopoverMenu, PopoverItem } from "@storyteller/ui-popover"; import { Tooltip } from "@storyteller/ui-tooltip"; import { Button, ToggleButton } from "@storyteller/ui-button"; import { Modal } from "@storyteller/ui-modal"; -import { FalKlingImageToVideo } from "@storyteller/tauri-api"; +import { EnqueueImageToVideo } from "@storyteller/tauri-api"; import { faMessageXmark, faMessageCheck, @@ -20,6 +20,7 @@ import { faRectangle } from "@fortawesome/pro-regular-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { IsDesktopApp } from "@storyteller/tauri-utils"; import { GalleryItem, GalleryModal } from "@storyteller/ui-gallery-modal"; +import { ModelInfo } from "@storyteller/model-list"; interface ReferenceImage { id: string; @@ -32,6 +33,7 @@ interface PromptBoxVideoProps { useJobContext: () => JobContextType; onEnqueuePressed?: () => void | Promise; model: string; + modelInfo?: ModelInfo; imageMediaId?: string; url?: string; } @@ -40,6 +42,7 @@ export const PromptBoxVideo = ({ useJobContext, onEnqueuePressed, model, + modelInfo, imageMediaId, url, }: PromptBoxVideoProps) => { @@ -183,7 +186,7 @@ export const PromptBoxVideo = ({ const handleEnqueue = async () => { setIsEnqueueing(true); - console.log("Handle Enqueue"); + console.log("PromptBoxVideo - Prompting with model", modelInfo); setTimeout(() => { // TODO(bt,2025-05-08): This is a hack so we don't accidentally wind up with a permanently disabled prompt box if @@ -192,8 +195,10 @@ export const PromptBoxVideo = ({ setIsEnqueueing(false); }, 10000); - const generateResponse = await FalKlingImageToVideo({ + const generateResponse = await EnqueueImageToVideo({ + model: modelInfo, image_media_token: referenceImages[0].mediaToken, + //prompt: prompt, }); console.log("generateResponse", generateResponse); diff --git a/frontend/libs/model-list/src/index.ts b/frontend/libs/model-list/src/index.ts index e724faed08..2013b446c3 100644 --- a/frontend/libs/model-list/src/index.ts +++ b/frontend/libs/model-list/src/index.ts @@ -2,4 +2,5 @@ export * from './lib/model-list.js'; export * from './lib/ModelInfo.js'; export * from './lib/ModelCreator.js'; export * from './lib/ImageModels.js'; +export * from './lib/VideoModels.js'; diff --git a/frontend/libs/model-list/src/lib/VideoModels.ts b/frontend/libs/model-list/src/lib/VideoModels.ts new file mode 100644 index 0000000000..f66caa9fcb --- /dev/null +++ b/frontend/libs/model-list/src/lib/VideoModels.ts @@ -0,0 +1,41 @@ +import { ModelCreator } from "./ModelCreator.js"; +import { ModelInfo } from "./ModelInfo.js"; + +export const VIDEO_MODELS: Record = { + kling_1_6_pro: { + name: "Kling 1.6 Pro", + tauri_id: "kling_1.6_pro", + creator: ModelCreator.Kling, + }, + kling_2_1_pro: { + name: "Kling 2.1 Pro", + tauri_id: "kling_2.1_pro", + creator: ModelCreator.Kling, + }, + kling_2_1_master: { + name: "Kling 2.1 Master", + tauri_id: "kling_2.1_master", + creator: ModelCreator.Kling, + }, + seedance_1_0_lite: { + name: "Seedance 1.0 Lite", + tauri_id: "seedance_1.0_lite", + creator: ModelCreator.Bytedance, + }, + veo_2: { + name: "Google Veo 2", + tauri_id: "veo_2", + creator: ModelCreator.Google, + } +} + +// This is a hack to get the old model selector code to work since it's keyed off +// of the human-readable label of the model. Long term, that should be fixed. +export const VIDEO_MODELS_BY_LABEL: Record = { + "Kling 1.6 Pro": VIDEO_MODELS.kling_1_6_pro, + "Kling 2.1 Pro": VIDEO_MODELS.kling_2_1_pro, + "Kling 2.1 Master": VIDEO_MODELS.kling_2_1_master, + "Seedance 1.0 Lite": VIDEO_MODELS.seedance_1_0_lite, + "Google Veo 2": VIDEO_MODELS.veo_2, +} + diff --git a/frontend/libs/tauri-api/src/index.ts b/frontend/libs/tauri-api/src/index.ts index 9ee15d125b..f32a3b435a 100644 --- a/frontend/libs/tauri-api/src/index.ts +++ b/frontend/libs/tauri-api/src/index.ts @@ -1,18 +1,19 @@ export * from "./lib/common/CommandStatus.js"; -export * from "./lib/enqueue/EnqueueTextToImage.js"; export * from "./lib/enqueue/EnqueueImageTo3dObject.js"; +export * from "./lib/enqueue/EnqueueTextToImage.js"; +export * from "./lib/enqueue/EnqueueImageToVideo.js"; export * from "./lib/fal/FalBackgroundRemoval.js"; export * from "./lib/fal/FalHunyuanImageTo3d.js"; export * from "./lib/fal/FalKlingImageToVideo.js"; export * from "./lib/fal/GetFalApiKey.js"; export * from "./lib/fal/SetFalApiKey.js"; -export * from "./lib/openai/SetOpenAIApiKey.js"; export * from "./lib/openai/GetOpenAIApiKey.js"; +export * from "./lib/openai/SetOpenAIApiKey.js"; export * from "./lib/settings/GetAppPreferences.js"; export * from "./lib/settings/UpdateAppPreference.js"; export * from "./lib/sora/CheckSoraSession.js"; export * from "./lib/sora/LogoutSoraSession.js"; export * from "./lib/sora/SoraImageRemix.js"; export * from "./lib/sora/useSoraLoginListener.js"; -export * from "./lib/system/GetAppInfo.js"; export * from "./lib/sora/waitForSoraLogin.js"; +export * from "./lib/system/GetAppInfo.js"; diff --git a/frontend/libs/tauri-api/src/lib/enqueue/EnqueueImageToVideo.ts b/frontend/libs/tauri-api/src/lib/enqueue/EnqueueImageToVideo.ts new file mode 100644 index 0000000000..da8e1098e1 --- /dev/null +++ b/frontend/libs/tauri-api/src/lib/enqueue/EnqueueImageToVideo.ts @@ -0,0 +1,49 @@ +import { invoke } from "@tauri-apps/api/core"; +import { CommandResult } from "../common/CommandStatus"; +import { ModelInfo } from "@storyteller/model-list"; + +export enum EnqueueImageToVideoErrorType { + /// Caller didn't specify a model + ModelNotSpecified = "model_not_specified", + /// Generic server error + ServerError = "server_error", + /// No Fal API key available + NeedsFalApiKey = "needs_fal_api_key", + /// Fal had an API error + FalError = "fal_error", +} + +export interface EnqueueImageToVideoRequest { + image_media_token?: string; + model?: ModelInfo; +} + +export interface EnqueueImageToVideoError extends CommandResult { + error_type: EnqueueImageToVideoErrorType; + error_message?: string; +} + +export interface EnqueueImageToVideoPayload { + media_token: string; + cdn_url: string; + base64_bytes: string; +} + +export interface EnqueueImageToVideoSuccess extends CommandResult { + payload: EnqueueImageToVideoPayload; +} + +export type EnqueueImageToVideoResult = EnqueueImageToVideoSuccess | EnqueueImageToVideoError; + +export const EnqueueImageToVideo = async (request: EnqueueImageToVideoRequest) : Promise => { + const modelName = request.model?.tauri_id; + + const result = await invoke("enqueue_image_to_video_command", { + request: { + image_media_token: request.image_media_token, + model: modelName, + } + }); + + return (result as EnqueueImageToVideoResult); +} diff --git a/frontend/libs/tauri-api/src/lib/enqueue/EnqueueTextToImage.ts b/frontend/libs/tauri-api/src/lib/enqueue/EnqueueTextToImage.ts index 1ed009ef5d..009d77012b 100644 --- a/frontend/libs/tauri-api/src/lib/enqueue/EnqueueTextToImage.ts +++ b/frontend/libs/tauri-api/src/lib/enqueue/EnqueueTextToImage.ts @@ -52,7 +52,7 @@ export const EnqueueTextToImage = async (request: EnqueueTextToImageRequest) : P } } - let result = await invoke("enqueue_text_to_image_command", { + const result = await invoke("enqueue_text_to_image_command", { request: { prompt: request.prompt, model: modelName,