mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 01:18:34 +00:00
cleanup
This commit is contained in:
1 parent
4f79fb4601
commit
4ea9c8b8aa
1 file changed
+80
-50
+80
-50
@@ -7,11 +7,14 @@ use artcraft_api_defs::omni_gen::cost_and_generate_requests::omni_gen_video_cost
|
||||
use artcraft_router::api::provider::Provider;
|
||||
use artcraft_router::client::router_client::RouterClient;
|
||||
use artcraft_router::client::router_seedance2pro_client::RouterSeedance2ProClient;
|
||||
use artcraft_router::generate::generate_video::generate_video_response::GenerateVideoResponse;
|
||||
use artcraft_router::generate::generate_video_v2::video_generation_draft_context::VideoGenerationDraftContext;
|
||||
use artcraft_router::generate::generate_video_v2::video_generation_draft_or_request::VideoGenerationDraftOrRequest;
|
||||
use artcraft_router::generate::generate_video_v2::video_generation_request::VideoGenerationRequest;
|
||||
use seedance2pro_client::creds::seedance2pro_session::Seedance2ProSession;
|
||||
use tokens::tokens::characters::CharacterToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
|
||||
|
||||
use crate::http_server::common_responses::advanced_common_web_error::AdvancedCommonWebError;
|
||||
use crate::http_server::endpoint_helpers::refund_wallet_after_api_failure::refund_wallet_after_api_failure;
|
||||
@@ -37,6 +40,8 @@ pub async fn run_pipeline_v2(
|
||||
AdvancedCommonWebError::from_error(e)
|
||||
})?;
|
||||
|
||||
let provider = draft_or_request.get_provider();
|
||||
|
||||
// 2. Calculate cost (swap provider to Artcraft for billing)
|
||||
let mut cost_builder = hydrate_to_router_request(request)?;
|
||||
cost_builder.provider = Provider::Artcraft;
|
||||
@@ -65,54 +70,24 @@ pub async fn run_pipeline_v2(
|
||||
map.iter().map(|(k, v)| (k.clone(), v.to_string())).collect()
|
||||
});
|
||||
|
||||
let kinovi_character_id_map = resolve_kinovi_character_ids(
|
||||
request.reference_character_tokens.as_deref(),
|
||||
mysql_connection,
|
||||
).await?;
|
||||
let kinovi_character_id_map: Option<HashMap<CharacterToken, String>> =
|
||||
resolve_kinovi_character_ids(
|
||||
request.reference_character_tokens.as_deref(),
|
||||
mysql_connection,
|
||||
).await?;
|
||||
|
||||
// 5. Finalize draft → request (or use request directly)
|
||||
let (video_request, is_kinovi) = match draft_or_request {
|
||||
VideoGenerationDraftOrRequest::Request(request) => {
|
||||
let is_kinovi = matches!(
|
||||
request,
|
||||
VideoGenerationRequest::KinoviSeedance2p0(_) | VideoGenerationRequest::KinoviSeedance2p0Fast(_)
|
||||
);
|
||||
(request, is_kinovi)
|
||||
}
|
||||
VideoGenerationDraftOrRequest::Draft(draft) => {
|
||||
let seedance2pro_session = Seedance2ProSession::from_cookies_string(
|
||||
server_state.seedance2pro.cookies.clone()
|
||||
);
|
||||
let seedance2pro_client = RouterSeedance2ProClient::new(seedance2pro_session);
|
||||
let router_client = RouterClient::Seedance2Pro(seedance2pro_client);
|
||||
// 5. Upload media (if draft) and generate video.
|
||||
// The entire block is wrapped so Kinovi failures trigger a refund.
|
||||
let result = upload_and_generate(
|
||||
draft_or_request,
|
||||
server_state,
|
||||
media_file_urls_as_strings.as_ref(),
|
||||
kinovi_character_id_map.as_ref(),
|
||||
).await;
|
||||
|
||||
let draft_context = VideoGenerationDraftContext {
|
||||
client: Some(&router_client),
|
||||
media_file_to_artcraft_url_map: media_file_urls_as_strings.as_ref(),
|
||||
character_token_to_kinovi_id_map: kinovi_character_id_map.as_ref(),
|
||||
};
|
||||
|
||||
let request = draft.finalize(draft_context).await.map_err(|err| {
|
||||
warn!("Failed to finalize v2 draft: {:?}", err);
|
||||
AdvancedCommonWebError::from_error(err)
|
||||
})?;
|
||||
|
||||
// Drafts are always Kinovi (Artcraft never produces drafts).
|
||||
(request, true)
|
||||
}
|
||||
};
|
||||
|
||||
// 6. Build client and send
|
||||
let session = Seedance2ProSession::from_cookies_string(
|
||||
server_state.seedance2pro.cookies.clone()
|
||||
);
|
||||
let client = RouterClient::Seedance2Pro(RouterSeedance2ProClient::new(session));
|
||||
|
||||
let result = video_request.send_request(&client).await;
|
||||
|
||||
// 7. On failure, refund wallet if this is a Kinovi request
|
||||
// 6. On failure, refund wallet for Kinovi requests.
|
||||
if let Err(ref err) = result {
|
||||
if is_kinovi {
|
||||
if matches!(provider, Provider::Seedance2Pro) {
|
||||
if let Some(ledger_entry_token) = billing.maybe_wallet_ledger_entry_token.as_ref() {
|
||||
warn!("Kinovi v2 generation failed, issuing refund for {}: {:?}", ledger_entry_token.as_str(), err);
|
||||
if let Err(refund_err) = refund_wallet_after_api_failure(ledger_entry_token, mysql_connection).await {
|
||||
@@ -122,12 +97,67 @@ pub async fn run_pipeline_v2(
|
||||
}
|
||||
}
|
||||
|
||||
let response = result.map_err(|err| {
|
||||
warn!("v2 video generation failed: {:?}", err);
|
||||
AdvancedCommonWebError::from_error(err)
|
||||
})?;
|
||||
|
||||
let response = result?;
|
||||
info!("v2 generation response: {:?}", response);
|
||||
|
||||
Ok(PipelineResult { billing, response })
|
||||
}
|
||||
|
||||
/// Finalize the draft (uploading media if needed), then send the generation request.
|
||||
///
|
||||
/// This is the block that gets refunded on failure for Kinovi providers.
|
||||
async fn upload_and_generate(
|
||||
draft_or_request: VideoGenerationDraftOrRequest,
|
||||
server_state: &ServerState,
|
||||
media_file_urls_by_token: Option<&HashMap<MediaFileToken, String>>,
|
||||
kinovi_character_ids: Option<&HashMap<CharacterToken, String>>,
|
||||
) -> Result<GenerateVideoResponse, AdvancedCommonWebError> {
|
||||
// Finalize draft → request (or use request directly)
|
||||
let video_request = match draft_or_request {
|
||||
VideoGenerationDraftOrRequest::Request(request) => request,
|
||||
VideoGenerationDraftOrRequest::Draft(draft) => {
|
||||
let session = Seedance2ProSession::from_cookies_string(
|
||||
server_state.seedance2pro.cookies.clone()
|
||||
);
|
||||
let seedance2pro_client = RouterSeedance2ProClient::new(session);
|
||||
let router_client = RouterClient::Seedance2Pro(seedance2pro_client);
|
||||
|
||||
let draft_context = VideoGenerationDraftContext {
|
||||
client: Some(&router_client),
|
||||
media_file_to_artcraft_url_map: media_file_urls_by_token,
|
||||
character_token_to_kinovi_id_map: kinovi_character_ids,
|
||||
};
|
||||
|
||||
draft.finalize(draft_context).await.map_err(|err| {
|
||||
warn!("Failed to finalize v2 draft: {:?}", err);
|
||||
AdvancedCommonWebError::from_error(err)
|
||||
})?
|
||||
}
|
||||
};
|
||||
|
||||
// Build client and send
|
||||
let client = build_client(&video_request, server_state);
|
||||
|
||||
video_request.send_request(&client).await.map_err(|err| {
|
||||
warn!("v2 video generation failed: {:?}", err);
|
||||
AdvancedCommonWebError::from_error(err)
|
||||
})
|
||||
}
|
||||
|
||||
fn build_client(request: &VideoGenerationRequest, server_state: &ServerState) -> RouterClient {
|
||||
match request.get_provider() {
|
||||
Provider::Seedance2Pro => {
|
||||
let session = Seedance2ProSession::from_cookies_string(
|
||||
server_state.seedance2pro.cookies.clone()
|
||||
);
|
||||
RouterClient::Seedance2Pro(RouterSeedance2ProClient::new(session))
|
||||
}
|
||||
// For future providers, add arms here.
|
||||
_ => {
|
||||
let session = Seedance2ProSession::from_cookies_string(
|
||||
server_state.seedance2pro.cookies.clone()
|
||||
);
|
||||
RouterClient::Seedance2Pro(RouterSeedance2ProClient::new(session))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user