diff --git a/crates/desktop/tauri-artcraft/src/commands/sora/sora_image_remix_command.rs b/crates/desktop/tauri-artcraft/src/commands/sora/sora_image_remix_command.rs index fb47e76f8f..70d6efe7b7 100644 --- a/crates/desktop/tauri-artcraft/src/commands/sora/sora_image_remix_command.rs +++ b/crates/desktop/tauri-artcraft/src/commands/sora/sora_image_remix_command.rs @@ -22,6 +22,7 @@ use std::io::Cursor; use storyteller_client::media_files::get_media_file::get_media_file; use storyteller_client::utils::api_host::ApiHost; use tauri::{AppHandle, Manager, State}; +use openai_sora_client::recipes::maybe_upgrade_or_renew_session::maybe_upgrade_or_renew_session; use tokens::tokens::media_files::MediaFileToken; #[derive(Deserialize)] @@ -82,32 +83,24 @@ pub async fn generate_image( let files_to_upload = vec![filename]; - // TODO(bt,2025-04-21): Read from in-memory cache instead, but allow for desktop replacement. - let mut creds = read_sora_credentials_from_disk(app_data_root) - .map_err(|err| { - error!("Failed to read Sora credentials from disk: {:?}", err); - err - })?; + let mut creds = sora_creds_manager.get_credentials_required()?; - let no_sentinel = !app_data_root.get_sora_sentinel_file_path().is_file() - || creds.sora_sentinel.is_none(); + let credential_updated = maybe_upgrade_or_renew_session(&mut creds) + .await + .map_err(|err| { + error!("Failed to upgrade or renew session: {:?}", err); + err + })?; - if no_sentinel { - info!("Refreshing credentials..."); - - creds = sora_creds_manager.call_sentinel_refresh() - .await - .map_err(|err| { - error!("Failed to refresh: {:?}", err); - err - })?; - - // TODO: Write to disk. + if credential_updated { + info!("Storing updated credentials"); + sora_creds_manager.set_credentials(&creds)?; } let mut sora_media_tokens = Vec::with_capacity(files_to_upload.len()); for file_path in files_to_upload { + // TODO(bt,2025-04-24): Handle JWT reset error. let sora_upload_response = sora_media_upload_from_file(file_path, CredentialMigrationRef::New(&creds)) .await?; @@ -126,6 +119,8 @@ pub async fn generate_image( credentials: CredentialMigrationRef::New(&creds), }).await; + // TODO(bt,2025-04-24): Handle state management better. Different errors imply different conditions. + if let Err(err) = &response { error!("Error in generating image: {:?}", err); diff --git a/crates/desktop/tauri-artcraft/src/state/sora/read_sora_credentials_from_disk_with_upgrade.rs b/crates/desktop/tauri-artcraft/src/state/sora/read_sora_credentials_from_disk_with_upgrade.rs index 20e89f6d3b..d5200c1cfd 100644 --- a/crates/desktop/tauri-artcraft/src/state/sora/read_sora_credentials_from_disk_with_upgrade.rs +++ b/crates/desktop/tauri-artcraft/src/state/sora/read_sora_credentials_from_disk_with_upgrade.rs @@ -6,7 +6,7 @@ use openai_sora_client::creds::sora_cookies::SoraCookies; use openai_sora_client::creds::sora_credential_set::SoraCredentialSet; use openai_sora_client::creds::sora_jwt_bearer_token::SoraJwtBearerToken; use openai_sora_client::creds::sora_sentinel::SoraSentinel; -use openai_sora_client::recipes::upgrade_or_renew_session::upgrade_or_renew_session; +use openai_sora_client::recipes::maybe_upgrade_or_renew_session::maybe_upgrade_or_renew_session; use std::fs::{read_to_string, OpenOptions}; use std::io::Write; @@ -49,7 +49,7 @@ pub async fn read_sora_credentials_from_disk_with_upgrade(app_data_root: &AppDat sentinel, ); - let response = upgrade_or_renew_session(&mut credentials).await; + let response = maybe_upgrade_or_renew_session(&mut credentials).await; if let Err(err) = response { // NB: Make this portion infallible. Don't die on setup. We can recover downstream. diff --git a/crates/lib/api_clients/openai_sora_client/src/recipes/upgrade_or_renew_session.rs b/crates/lib/api_clients/openai_sora_client/src/recipes/maybe_upgrade_or_renew_session.rs similarity index 88% rename from crates/lib/api_clients/openai_sora_client/src/recipes/upgrade_or_renew_session.rs rename to crates/lib/api_clients/openai_sora_client/src/recipes/maybe_upgrade_or_renew_session.rs index 7af04831d5..98b2f284f0 100644 --- a/crates/lib/api_clients/openai_sora_client/src/recipes/upgrade_or_renew_session.rs +++ b/crates/lib/api_clients/openai_sora_client/src/recipes/maybe_upgrade_or_renew_session.rs @@ -13,7 +13,7 @@ const EXPIRATION_DEADLINE : TimeDelta = TimeDelta::hours(12); /// Call this at session startup to generate the tokens for the first time. /// Call this periodically to refresh the JWT as it nears its expiration date. /// This will not refresh the sentinel token once it's been generated - we can use other flows to accomplish that. -pub async fn upgrade_or_renew_session(sora_credentials: &mut SoraCredentialSet) -> AnyhowResult<()> { +pub async fn maybe_upgrade_or_renew_session(sora_credentials: &mut SoraCredentialSet) -> AnyhowResult { let mut refresh_jwt = !sora_credentials.jwt_bearer_token.is_some(); let refresh_sentinel = !sora_credentials.sora_sentinel.is_some(); @@ -29,6 +29,8 @@ pub async fn upgrade_or_renew_session(sora_credentials: &mut SoraCredentialSet) } } + let mut credential_updated = false; + if refresh_jwt { let cookies = sora_credentials.cookies.as_str(); @@ -38,6 +40,7 @@ pub async fn upgrade_or_renew_session(sora_credentials: &mut SoraCredentialSet) info!("Parsing JWT bearer token."); let token = SoraJwtBearerToken::new(token)?; sora_credentials.jwt_bearer_token = Some(token); + credential_updated = true; } if refresh_sentinel { @@ -45,7 +48,8 @@ pub async fn upgrade_or_renew_session(sora_credentials: &mut SoraCredentialSet) let token = generate_token().await?; let token = SoraSentinel::new(token); sora_credentials.sora_sentinel = Some(token); + credential_updated = true; } - Ok(()) + Ok(credential_updated) } diff --git a/crates/lib/api_clients/openai_sora_client/src/recipes/mod.rs b/crates/lib/api_clients/openai_sora_client/src/recipes/mod.rs index cd0b166bf0..d773fbb220 100644 --- a/crates/lib/api_clients/openai_sora_client/src/recipes/mod.rs +++ b/crates/lib/api_clients/openai_sora_client/src/recipes/mod.rs @@ -1,2 +1,2 @@ -pub mod upgrade_or_renew_session; +pub mod maybe_upgrade_or_renew_session; pub mod wait_for_image_gen_status; \ No newline at end of file