Compare commits

...
Author SHA1 Message Date
Brandon Thomas fcbd24d0b2 codegen 2026-05-22 12:36:45 -04:00
Brandon Thomas 0577855a67 query clenaup 2026-05-21 23:43:28 -04:00
Brandon Thomas fc701fa06b consolidate queries 2026-05-21 23:28:49 -04:00
20 changed files with 595 additions and 689 deletions
@@ -0,0 +1,12 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n job_type = ?,\n\n maybe_external_third_party = ?,\n maybe_external_third_party_id = ?,\n\n product_category = ?,\n inference_category = ?,\n\n maybe_model_type = ?,\n maybe_model_token = ?,\n\n maybe_input_source_token = ?,\n maybe_input_source_token_type = ?,\n\n maybe_download_url = ?,\n maybe_cover_image_media_file_token = ?,\n\n maybe_prompt_token = ?,\n maybe_wallet_ledger_entry_token = ?,\n\n maybe_raw_inference_text = ?,\n\n maybe_inference_args = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n\n priority_level = ?,\n is_keepalive_required = ?,\n max_duration_seconds = ?,\n is_debug_request = ?,\n\n maybe_routing_tag = ?,\n\n maybe_debug_log_event_token = ?,\n\n frontend_failure_category = ?,\n failure_reason = ?,\n\n status = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 30
},
"nullable": []
},
"hash": "161febbb30cf6c669a813fe036d405ef428422297440abd240482a6aae51f6f9"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n job_type = ?,\n\n maybe_external_third_party = ?,\n maybe_external_third_party_id = ?,\n\n product_category = ?,\n inference_category = ?,\n\n maybe_model_type = NULL,\n maybe_model_token = NULL,\n\n maybe_input_source_token = NULL,\n maybe_input_source_token_type = NULL,\n\n maybe_download_url = NULL,\n maybe_cover_image_media_file_token = NULL,\n\n maybe_prompt_token = ?,\n\n maybe_wallet_ledger_entry_token = ?,\n\n maybe_raw_inference_text = NULL,\n\n maybe_inference_args = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n\n priority_level = 0,\n is_keepalive_required = FALSE,\n max_duration_seconds = 0,\n\n is_debug_request = FALSE,\n maybe_routing_tag = NULL,\n\n maybe_debug_log_event_token = ?,\n\n status = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 16
},
"nullable": []
},
"hash": "8f8b64c0af5383ff3baaa8aa2f2aa22cc760addd850d618ce543fe05816d11e0"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n job_type = ?,\n\n maybe_external_third_party = ?,\n maybe_external_third_party_id = ?,\n\n product_category = ?,\n inference_category = ?,\n\n maybe_model_type = NULL,\n maybe_model_token = NULL,\n\n maybe_input_source_token = NULL,\n maybe_input_source_token_type = NULL,\n\n maybe_download_url = NULL,\n maybe_cover_image_media_file_token = NULL,\n\n maybe_prompt_token = ?,\n\n maybe_raw_inference_text = NULL,\n\n maybe_inference_args = NULL,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n\n priority_level = 0,\n is_keepalive_required = FALSE,\n max_duration_seconds = 0,\n\n is_debug_request = FALSE,\n maybe_routing_tag = NULL,\n\n maybe_debug_log_event_token = ?,\n\n frontend_failure_category = NULL,\n failure_reason = NULL,\n\n status = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 14
},
"nullable": []
},
"hash": "99dae5c5f3b3a8e9ce105bff9a9754c3aee92dbf217288c9a7eb925004e3d259"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n job_type = ?,\n\n maybe_external_third_party = ?,\n maybe_external_third_party_id = ?,\n\n product_category = ?,\n inference_category = ?,\n\n maybe_model_type = NULL,\n maybe_model_token = NULL,\n\n maybe_input_source_token = NULL,\n maybe_input_source_token_type = NULL,\n\n maybe_download_url = NULL,\n maybe_cover_image_media_file_token = NULL,\n\n maybe_prompt_token = NULL,\n\n maybe_wallet_ledger_entry_token = NULL,\n\n maybe_raw_inference_text = NULL,\n\n maybe_inference_args = NULL,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n\n priority_level = 0,\n is_keepalive_required = FALSE,\n max_duration_seconds = 0,\n\n is_debug_request = FALSE,\n maybe_routing_tag = NULL,\n\n status = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 12
},
"nullable": []
},
"hash": "b0ba0fe63908df3d66b4820ca47cbb773786e480464c84a278fe63b1fa8913b4"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n job_type = ?,\n\n product_category = ?,\n\n inference_category = ?,\n maybe_model_type = ?,\n maybe_model_token = ?,\n\n maybe_input_source_token = ?,\n maybe_input_source_token_type = ?,\n\n maybe_download_url = ?,\n maybe_cover_image_media_file_token = ?,\n\n maybe_raw_inference_text = ?,\n\n maybe_inference_args = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n\n creator_set_visibility = ?,\n\n priority_level = ?,\n is_keepalive_required = ?,\n max_duration_seconds = ?,\n\n is_debug_request = ?,\n maybe_routing_tag = ?,\n\n status = \"pending\"\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 22
},
"nullable": []
},
"hash": "b48e80845d80a6c07099918807d0495b8d70dca339cb1332e05bb3943fbb24c4"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n job_type = ?,\n\n maybe_external_third_party = ?,\n maybe_external_third_party_id = ?,\n\n product_category = ?,\n inference_category = ?,\n\n maybe_model_type = NULL,\n maybe_model_token = NULL,\n\n maybe_input_source_token = NULL,\n maybe_input_source_token_type = NULL,\n\n maybe_download_url = NULL,\n maybe_cover_image_media_file_token = NULL,\n\n maybe_prompt_token = ?,\n\n maybe_raw_inference_text = NULL,\n\n maybe_inference_args = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n\n priority_level = 0,\n is_keepalive_required = FALSE,\n max_duration_seconds = 0,\n\n is_debug_request = FALSE,\n maybe_routing_tag = NULL,\n\n maybe_debug_log_event_token = ?,\n\n frontend_failure_category = ?,\n failure_reason = ?,\n\n status = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 17
},
"nullable": []
},
"hash": "c73be10c5677f78f81bc1c29872fd5af889790c3b2a8de27eb8ab64383c638d6"
}
@@ -1,12 +0,0 @@
{
"db_name": "MySQL",
"query": "\nINSERT INTO generic_inference_jobs\nSET\n token = ?,\n uuid_idempotency_token = ?,\n\n job_type = ?,\n\n maybe_external_third_party = ?,\n maybe_external_third_party_id = ?,\n\n product_category = ?,\n inference_category = ?,\n\n maybe_model_type = NULL,\n maybe_model_token = NULL,\n\n maybe_input_source_token = NULL,\n maybe_input_source_token_type = NULL,\n\n maybe_download_url = NULL,\n maybe_cover_image_media_file_token = NULL,\n\n maybe_prompt_token = ?,\n\n maybe_wallet_ledger_entry_token = ?,\n\n maybe_raw_inference_text = NULL,\n\n maybe_inference_args = ?,\n\n maybe_creator_user_token = ?,\n maybe_creator_anonymous_visitor_token = ?,\n creator_ip_address = ?,\n creator_set_visibility = ?,\n\n priority_level = 0,\n is_keepalive_required = FALSE,\n max_duration_seconds = 0,\n\n is_debug_request = FALSE,\n maybe_routing_tag = NULL,\n\n status = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 15
},
"nullable": []
},
"hash": "ee228ab4a079fde6b3683b6cde2a2384d3def27a5d09baa5caf00a521d5d2bcd"
}
@@ -1,4 +1,3 @@
use anyhow::anyhow;
use log::info;
use sqlx::{Executor, MySql};
use std::marker::PhantomData;
@@ -18,6 +17,10 @@ use tokens::tokens::users::UserToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::payloads::generic_inference_args::generic_inference_args::GenericInferenceArgs;
use crate::queries::generic_inference::api_providers::common::insert_generic_inference_job_for_provider::{
insert_generic_inference_job_for_provider,
InsertGenericInferenceJobForProviderArgs,
};
pub struct InsertGenericInferenceForBeebleWithAprioriJobTokenArgs<'e, 'c, E>
@@ -61,107 +64,31 @@ pub async fn insert_generic_inference_job_for_beeble_queue_with_apriori_job_toke
) -> Result<InferenceJobToken, DatabaseQueryError>
where E: 'e + Executor<'c, Database = MySql>
{
let serialized_args_payload = serde_json::ser::to_string(&args.maybe_inference_args)
.map_err(|_e| anyhow!("could not encode inference args"))?;
const JOB_TYPE: InferenceJobType = InferenceJobType::BeebleQueue;
const INFERENCE_CATEGORY: InferenceCategory = InferenceCategory::VideoGeneration;
const PRODUCT_CATEGORY: InferenceJobProductCategory = InferenceJobProductCategory::BeebleVideo;
const EXTERNAL_THIRD_PARTY: InferenceJobExternalThirdParty = InferenceJobExternalThirdParty::Beeble;
let status = args.starting_job_status_override.unwrap_or(JobStatusPlus::Pending);
let maybe_frontend_failure_category_str = args.maybe_frontend_failure_category
.map(|c| c.to_str());
let maybe_truncated_failure_reason = args.maybe_failure_reason
.map(|s| if s.len() > 255 { &s[..255] } else { s });
let query = sqlx::query!(
r#"
INSERT INTO generic_inference_jobs
SET
token = ?,
uuid_idempotency_token = ?,
job_type = ?,
maybe_external_third_party = ?,
maybe_external_third_party_id = ?,
product_category = ?,
inference_category = ?,
maybe_model_type = NULL,
maybe_model_token = NULL,
maybe_input_source_token = NULL,
maybe_input_source_token_type = NULL,
maybe_download_url = NULL,
maybe_cover_image_media_file_token = NULL,
maybe_prompt_token = ?,
maybe_raw_inference_text = NULL,
maybe_inference_args = ?,
maybe_creator_user_token = ?,
maybe_creator_anonymous_visitor_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
priority_level = 0,
is_keepalive_required = FALSE,
max_duration_seconds = 0,
is_debug_request = FALSE,
maybe_routing_tag = NULL,
maybe_debug_log_event_token = ?,
frontend_failure_category = ?,
failure_reason = ?,
status = ?
"#,
args.apriori_job_token.as_str(),
args.uuid_idempotency_token,
JOB_TYPE.to_str(),
EXTERNAL_THIRD_PARTY.to_str(),
args.maybe_external_third_party_id,
PRODUCT_CATEGORY.to_str(),
INFERENCE_CATEGORY.to_str(),
args.maybe_prompt_token.map(|t| t.to_string()),
serialized_args_payload,
args.maybe_creator_user_token.map(|t| t.to_string()),
args.maybe_avt_token.map(|t| t.to_string()),
args.creator_ip_address,
args.creator_set_visibility.to_str(),
args.maybe_debug_log_event_token.map(|t| t.as_str()),
maybe_frontend_failure_category_str,
maybe_truncated_failure_reason,
status.to_str(),
);
let query_result = query.execute(args.mysql_executor)
.await;
let record_id = match query_result {
Err(err) => return Err(DatabaseQueryError::from(err)),
Ok(res) => res.last_insert_id(),
let inner_args = InsertGenericInferenceJobForProviderArgs {
apriori_job_token: args.apriori_job_token,
uuid_idempotency_token: args.uuid_idempotency_token,
job_type: InferenceJobType::BeebleQueue,
external_third_party: InferenceJobExternalThirdParty::Beeble,
external_third_party_id: args.maybe_external_third_party_id,
product_category: InferenceJobProductCategory::BeebleVideo,
inference_category: InferenceCategory::VideoGeneration,
maybe_prompt_token: args.maybe_prompt_token,
maybe_wallet_ledger_entry_token: None,
maybe_inference_args: args.maybe_inference_args,
maybe_creator_user_token: args.maybe_creator_user_token,
maybe_avt_token: args.maybe_avt_token,
creator_ip_address: args.creator_ip_address,
creator_set_visibility: args.creator_set_visibility,
maybe_debug_log_event_token: args.maybe_debug_log_event_token,
maybe_frontend_failure_category: args.maybe_frontend_failure_category,
maybe_failure_reason: args.maybe_failure_reason,
status: args.starting_job_status_override.unwrap_or(JobStatusPlus::Pending),
mysql_executor: args.mysql_executor,
phantom: args.phantom,
};
let record_id = insert_generic_inference_job_for_provider(inner_args).await?;
info!("Insert generic inference job for Beeble queue: {} with record ID {}", args.apriori_job_token, record_id);
Ok(args.apriori_job_token.clone())
@@ -0,0 +1,132 @@
//! Provider-flavored wrapper around the inner-most record insert.
//!
//! All provider-side inserts (Fal, Beeble, GmiCloud, Seedance2Pro,
//! Worldlabs, …) share the same shape:
//!
//! - `maybe_external_third_party*` is always present (the external API was
//! called and gave us back an id).
//! - Web-only fields (`maybe_model_type`, `maybe_input_source_token`,
//! `maybe_download_url`, `maybe_cover_image_media_file_token`,
//! `maybe_raw_inference_text`, `maybe_routing_tag`, `priority_level`,
//! `requires_keepalive`, `max_duration_seconds`, `is_debug_request`) are
//! hard-coded to None / 0 / false here.
//! - `maybe_inference_args` is passed as-is and serialized in the root.
//! `None` writes DB `NULL`.
//!
//! Visibility is `pub(crate)`: external callers must use a leaf function.
use sqlx::{Executor, MySql};
use std::marker::PhantomData;
use enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use enums::by_table::generic_inference_jobs::inference_job_external_third_party::InferenceJobExternalThirdParty;
use enums::by_table::generic_inference_jobs::inference_job_product_category::InferenceJobProductCategory;
use enums::by_table::generic_inference_jobs::inference_job_type::InferenceJobType;
use enums::common::job_status_plus::JobStatusPlus;
use enums::common::visibility::Visibility;
use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken;
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken;
use tokens::tokens::prompts::PromptToken;
use tokens::tokens::users::UserToken;
use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::payloads::generic_inference_args::generic_inference_args::GenericInferenceArgs;
use crate::queries::generic_inference::common::insert_full_generic_inference_job_record::{
insert_full_generic_inference_job_record,
InsertFullGenericInferenceJobRecordArgs,
};
pub(crate) struct InsertGenericInferenceJobForProviderArgs<'e, 'c, E>
where E: 'e + Executor<'c, Database = MySql>
{
pub apriori_job_token: &'e InferenceJobToken,
pub uuid_idempotency_token: &'e str,
pub job_type: InferenceJobType,
pub external_third_party: InferenceJobExternalThirdParty,
pub external_third_party_id: &'e str,
pub product_category: InferenceJobProductCategory,
pub inference_category: InferenceCategory,
pub maybe_prompt_token: Option<&'e PromptToken>,
pub maybe_wallet_ledger_entry_token: Option<&'e WalletLedgerEntryToken>,
/// Forwarded to the root, which serializes to JSON. `None` writes DB NULL.
pub maybe_inference_args: Option<GenericInferenceArgs>,
pub maybe_creator_user_token: Option<&'e UserToken>,
pub maybe_avt_token: Option<&'e AnonymousVisitorTrackingToken>,
pub creator_ip_address: &'e str,
pub creator_set_visibility: Visibility,
pub maybe_debug_log_event_token: Option<&'e DebugLogEventToken>,
pub maybe_frontend_failure_category: Option<FrontendFailureCategory>,
pub maybe_failure_reason: Option<&'e str>,
pub status: JobStatusPlus,
pub mysql_executor: E,
pub phantom: PhantomData<&'c E>,
}
pub(crate) async fn insert_generic_inference_job_for_provider<'e, 'c: 'e, E>(
args: InsertGenericInferenceJobForProviderArgs<'e, 'c, E>,
) -> Result<u64, DatabaseQueryError>
where E: 'e + Executor<'c, Database = MySql>
{
let inner_args = InsertFullGenericInferenceJobRecordArgs {
token: args.apriori_job_token,
uuid_idempotency_token: args.uuid_idempotency_token,
job_type: args.job_type,
maybe_external_third_party: Some(args.external_third_party),
maybe_external_third_party_id: Some(args.external_third_party_id),
maybe_product_category: Some(args.product_category),
inference_category: args.inference_category,
// Web-only fields — providers never set these.
maybe_model_type: None,
maybe_model_token: None,
maybe_input_source_token: None,
maybe_input_source_token_type: None,
maybe_download_url: None,
maybe_cover_image_media_file_token: None,
maybe_raw_inference_text: None,
maybe_routing_tag: None,
priority_level: 0,
requires_keepalive: false,
max_duration_seconds: 0,
is_debug_request: false,
maybe_prompt_token: args.maybe_prompt_token,
maybe_wallet_ledger_entry_token: args.maybe_wallet_ledger_entry_token,
maybe_inference_args: args.maybe_inference_args,
maybe_creator_user_token: args.maybe_creator_user_token,
maybe_avt_token: args.maybe_avt_token,
creator_ip_address: args.creator_ip_address,
creator_set_visibility: args.creator_set_visibility,
maybe_debug_log_event_token: args.maybe_debug_log_event_token,
maybe_frontend_failure_category: args.maybe_frontend_failure_category,
maybe_failure_reason: args.maybe_failure_reason,
status: args.status,
mysql_executor: args.mysql_executor,
phantom: args.phantom,
};
insert_full_generic_inference_job_record(inner_args).await
}
@@ -0,0 +1 @@
pub(crate) mod insert_generic_inference_job_for_provider;
@@ -1,6 +1,4 @@
use anyhow::anyhow;
use log::info;
use sqlx::MySqlPool;
use sqlx::{Executor, MySql};
use std::marker::PhantomData;
@@ -19,6 +17,10 @@ use tokens::tokens::users::UserToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::payloads::generic_inference_args::generic_inference_args::GenericInferenceArgs;
use crate::queries::generic_inference::api_providers::common::insert_generic_inference_job_for_provider::{
insert_generic_inference_job_for_provider,
InsertGenericInferenceJobForProviderArgs,
};
use crate::queries::generic_inference::api_providers::fal::insert_generic_inference_job_for_fal_queue::FalCategory;
@@ -64,12 +66,6 @@ pub async fn insert_generic_inference_job_for_fal_queue_with_apriori_job_token<'
-> Result<InferenceJobToken, DatabaseQueryError>
where E: 'e + Executor<'c, Database = MySql>
{
let serialized_args_payload = serde_json::ser::to_string(&args.maybe_inference_args)
.map_err(|_e| anyhow!("could not encode inference args"))?;
const JOB_TYPE : InferenceJobType = InferenceJobType::FalQueue;
let (inference_category, product_category) =
match args.fal_category {
FalCategory::ImageGeneration => (
@@ -90,101 +86,31 @@ pub async fn insert_generic_inference_job_for_fal_queue_with_apriori_job_token<'
),
};
let maybe_external_third_party = InferenceJobExternalThirdParty::Fal;
let status = args.starting_job_status_override.unwrap_or(JobStatusPlus::Pending);
let maybe_frontend_failure_category_str = args.maybe_frontend_failure_category
.map(|c| c.to_str());
let maybe_truncated_failure_reason = args.maybe_failure_reason
.map(|s| if s.len() > 255 { &s[..255] } else { s });
let query = sqlx::query!(
r#"
INSERT INTO generic_inference_jobs
SET
token = ?,
uuid_idempotency_token = ?,
job_type = ?,
maybe_external_third_party = ?,
maybe_external_third_party_id = ?,
product_category = ?,
inference_category = ?,
maybe_model_type = NULL,
maybe_model_token = NULL,
maybe_input_source_token = NULL,
maybe_input_source_token_type = NULL,
maybe_download_url = NULL,
maybe_cover_image_media_file_token = NULL,
maybe_prompt_token = ?,
maybe_raw_inference_text = NULL,
maybe_inference_args = ?,
maybe_creator_user_token = ?,
maybe_creator_anonymous_visitor_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
priority_level = 0,
is_keepalive_required = FALSE,
max_duration_seconds = 0,
is_debug_request = FALSE,
maybe_routing_tag = NULL,
maybe_debug_log_event_token = ?,
frontend_failure_category = ?,
failure_reason = ?,
status = ?
"#,
args.apriori_job_token.as_str(),
args.uuid_idempotency_token,
JOB_TYPE.to_str(),
maybe_external_third_party.to_str(),
args.maybe_external_third_party_id,
product_category.to_str(),
inference_category.to_str(),
args.maybe_prompt_token.map(|t| t.to_string()),
serialized_args_payload,
args.maybe_creator_user_token.map(|t| t.to_string()),
args.maybe_avt_token.map(|t| t.to_string()),
args.creator_ip_address,
args.creator_set_visibility.to_str(),
args.maybe_debug_log_event_token.map(|t| t.as_str()),
maybe_frontend_failure_category_str,
maybe_truncated_failure_reason,
status.to_str(),
);
let query_result = query.execute(args.mysql_executor)
.await;
let record_id = match query_result {
Err(err) => return Err(DatabaseQueryError::from(err)),
Ok(res) => res.last_insert_id(),
let inner_args = InsertGenericInferenceJobForProviderArgs {
apriori_job_token: args.apriori_job_token,
uuid_idempotency_token: args.uuid_idempotency_token,
job_type: InferenceJobType::FalQueue,
external_third_party: InferenceJobExternalThirdParty::Fal,
external_third_party_id: args.maybe_external_third_party_id,
product_category,
inference_category,
maybe_prompt_token: args.maybe_prompt_token,
maybe_wallet_ledger_entry_token: None,
maybe_inference_args: args.maybe_inference_args,
maybe_creator_user_token: args.maybe_creator_user_token,
maybe_avt_token: args.maybe_avt_token,
creator_ip_address: args.creator_ip_address,
creator_set_visibility: args.creator_set_visibility,
maybe_debug_log_event_token: args.maybe_debug_log_event_token,
maybe_frontend_failure_category: args.maybe_frontend_failure_category,
maybe_failure_reason: args.maybe_failure_reason,
status: args.starting_job_status_override.unwrap_or(JobStatusPlus::Pending),
mysql_executor: args.mysql_executor,
phantom: args.phantom,
};
let record_id = insert_generic_inference_job_for_provider(inner_args).await?;
info!("Insert generic inference job for FAL queue: {} with record ID {}", args.apriori_job_token, record_id);
Ok(args.apriori_job_token.clone())
@@ -15,6 +15,10 @@ use tokens::tokens::prompts::PromptToken;
use tokens::tokens::users::UserToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::queries::generic_inference::api_providers::common::insert_generic_inference_job_for_provider::{
insert_generic_inference_job_for_provider,
InsertGenericInferenceJobForProviderArgs,
};
pub struct InsertGmiCloudInferenceJobArgs<'e, 'c, E>
where
@@ -38,78 +42,32 @@ pub async fn insert_generic_inference_job_for_gmicloud<'e, 'c: 'e, E>(
where
E: 'e + Executor<'c, Database = MySql>,
{
let query = sqlx::query!(
r#"
INSERT INTO generic_inference_jobs
SET
token = ?,
uuid_idempotency_token = ?,
job_type = ?,
maybe_external_third_party = ?,
maybe_external_third_party_id = ?,
product_category = ?,
inference_category = ?,
maybe_model_type = NULL,
maybe_model_token = NULL,
maybe_input_source_token = NULL,
maybe_input_source_token_type = NULL,
maybe_download_url = NULL,
maybe_cover_image_media_file_token = NULL,
maybe_prompt_token = ?,
maybe_raw_inference_text = NULL,
maybe_inference_args = NULL,
maybe_creator_user_token = ?,
maybe_creator_anonymous_visitor_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
priority_level = 0,
is_keepalive_required = FALSE,
max_duration_seconds = 0,
is_debug_request = FALSE,
maybe_routing_tag = NULL,
maybe_debug_log_event_token = ?,
frontend_failure_category = NULL,
failure_reason = NULL,
status = ?
"#,
args.apriori_job_token.as_str(),
args.uuid_idempotency_token,
InferenceJobType::GmiCloudQueue.to_str(),
InferenceJobExternalThirdParty::GmiCloud.to_str(),
args.external_request_id,
InferenceJobProductCategory::GmiCloudVideo.to_str(),
InferenceCategory::VideoGeneration.to_str(),
args.maybe_prompt_token.map(|t| t.to_string()),
args.maybe_creator_user_token.map(|t| t.to_string()),
args.maybe_avt_token.map(|t| t.to_string()),
args.creator_ip_address,
Visibility::Public.to_str(),
args.maybe_debug_log_event_token.map(|t| t.as_str()),
JobStatusPlus::Pending.to_str(),
);
let query_result = query.execute(args.mysql_executor).await;
let record_id = match query_result {
Err(err) => return Err(DatabaseQueryError::from(err)),
Ok(res) => res.last_insert_id(),
let inner_args = InsertGenericInferenceJobForProviderArgs {
apriori_job_token: args.apriori_job_token,
uuid_idempotency_token: args.uuid_idempotency_token,
job_type: InferenceJobType::GmiCloudQueue,
external_third_party: InferenceJobExternalThirdParty::GmiCloud,
external_third_party_id: args.external_request_id,
product_category: InferenceJobProductCategory::GmiCloudVideo,
inference_category: InferenceCategory::VideoGeneration,
maybe_prompt_token: args.maybe_prompt_token,
maybe_wallet_ledger_entry_token: None,
// GmiCloud doesn't take inference args.
maybe_inference_args: None,
maybe_creator_user_token: args.maybe_creator_user_token,
maybe_avt_token: args.maybe_avt_token,
creator_ip_address: args.creator_ip_address,
creator_set_visibility: Visibility::Public,
maybe_debug_log_event_token: args.maybe_debug_log_event_token,
maybe_frontend_failure_category: None,
maybe_failure_reason: None,
status: JobStatusPlus::Pending,
mysql_executor: args.mysql_executor,
phantom: args.phantom,
};
let record_id = insert_generic_inference_job_for_provider(inner_args).await?;
info!(
"Insert generic inference job for GmiCloud: {} with record ID {}",
args.apriori_job_token, record_id
@@ -1,4 +1,5 @@
pub mod beeble;
pub(crate) mod common;
pub mod fal;
pub mod gmicloud;
pub mod seedance2pro;
@@ -1,4 +1,3 @@
use anyhow::anyhow;
use log::info;
use sqlx::{Executor, MySql};
use std::marker::PhantomData;
@@ -14,6 +13,10 @@ use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::users::UserToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::queries::generic_inference::api_providers::common::insert_generic_inference_job_for_provider::{
insert_generic_inference_job_for_provider,
InsertGenericInferenceJobForProviderArgs,
};
pub struct InsertGenericInferenceForSeedance2ProCharacterWithAprioriJobTokenArgs<'e, 'c, E>
where E: 'e + Executor<'c, Database = MySql>
@@ -40,85 +43,32 @@ pub async fn insert_generic_inference_job_for_seedance2pro_character_with_aprior
) -> Result<InferenceJobToken, DatabaseQueryError>
where E: 'e + Executor<'c, Database = MySql>
{
const JOB_TYPE: InferenceJobType = InferenceJobType::Seedance2ProCharacter;
const INFERENCE_CATEGORY: InferenceCategory = InferenceCategory::CharacterGeneration;
const PRODUCT_CATEGORY: InferenceJobProductCategory = InferenceJobProductCategory::Seedance2ProCharacter;
const EXTERNAL_THIRD_PARTY: InferenceJobExternalThirdParty = InferenceJobExternalThirdParty::Seedance2Pro;
const STATUS: JobStatusPlus = JobStatusPlus::Pending;
let query = sqlx::query!(
r#"
INSERT INTO generic_inference_jobs
SET
token = ?,
uuid_idempotency_token = ?,
job_type = ?,
maybe_external_third_party = ?,
maybe_external_third_party_id = ?,
product_category = ?,
inference_category = ?,
maybe_model_type = NULL,
maybe_model_token = NULL,
maybe_input_source_token = NULL,
maybe_input_source_token_type = NULL,
maybe_download_url = NULL,
maybe_cover_image_media_file_token = NULL,
maybe_prompt_token = NULL,
maybe_wallet_ledger_entry_token = NULL,
maybe_raw_inference_text = NULL,
maybe_inference_args = NULL,
maybe_creator_user_token = ?,
maybe_creator_anonymous_visitor_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
priority_level = 0,
is_keepalive_required = FALSE,
max_duration_seconds = 0,
is_debug_request = FALSE,
maybe_routing_tag = NULL,
status = ?
"#,
args.apriori_job_token.as_str(),
args.uuid_idempotency_token,
JOB_TYPE.to_str(),
EXTERNAL_THIRD_PARTY.to_str(),
args.kinovi_character_id,
PRODUCT_CATEGORY.to_str(),
INFERENCE_CATEGORY.to_str(),
args.maybe_creator_user_token.map(|t| t.to_string()),
args.maybe_avt_token.map(|t| t.to_string()),
args.creator_ip_address,
args.creator_set_visibility.to_str(),
STATUS.to_str(),
);
let query_result = query.execute(args.mysql_executor)
.await;
let record_id = match query_result {
Err(err) => return Err(DatabaseQueryError::from(err)),
Ok(res) => res.last_insert_id(),
let inner_args = InsertGenericInferenceJobForProviderArgs {
apriori_job_token: args.apriori_job_token,
uuid_idempotency_token: args.uuid_idempotency_token,
job_type: InferenceJobType::Seedance2ProCharacter,
external_third_party: InferenceJobExternalThirdParty::Seedance2Pro,
external_third_party_id: args.kinovi_character_id,
product_category: InferenceJobProductCategory::Seedance2ProCharacter,
inference_category: InferenceCategory::CharacterGeneration,
maybe_prompt_token: None,
maybe_wallet_ledger_entry_token: None,
// Character variant doesn't take inference args.
maybe_inference_args: None,
maybe_creator_user_token: args.maybe_creator_user_token,
maybe_avt_token: args.maybe_avt_token,
creator_ip_address: args.creator_ip_address,
creator_set_visibility: args.creator_set_visibility,
maybe_debug_log_event_token: None,
maybe_frontend_failure_category: None,
maybe_failure_reason: None,
status: JobStatusPlus::Pending,
mysql_executor: args.mysql_executor,
phantom: args.phantom,
};
let record_id = insert_generic_inference_job_for_provider(inner_args).await?;
info!("Insert generic inference job for Seedance2Pro character: {} with record ID {}", args.apriori_job_token, record_id);
Ok(args.apriori_job_token.clone())
@@ -1,4 +1,3 @@
use anyhow::anyhow;
use log::info;
use sqlx::{Executor, MySql};
use std::marker::PhantomData;
@@ -18,6 +17,10 @@ use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::payloads::generic_inference_args::generic_inference_args::GenericInferenceArgs;
use crate::queries::generic_inference::api_providers::common::insert_generic_inference_job_for_provider::{
insert_generic_inference_job_for_provider,
InsertGenericInferenceJobForProviderArgs,
};
pub struct InsertGenericInferenceForSeedance2ProWithAprioriJobTokenArgs<'e, 'c, E>
where E: 'e + Executor<'c, Database = MySql>
@@ -56,109 +59,45 @@ pub async fn insert_generic_inference_job_for_seedance2pro_queue_with_apriori_jo
) -> Result<InferenceJobToken, DatabaseQueryError>
where E: 'e + Executor<'c, Database = MySql>
{
let serialized_args_payload = serde_json::ser::to_string(&args.maybe_inference_args)
.map_err(|_e| anyhow!("could not encode inference args"))?;
const INFERENCE_CATEGORY: InferenceCategory = InferenceCategory::VideoGeneration;
const STATUS: JobStatusPlus = JobStatusPlus::Pending;
let job_type;
let external_third_party;
let product_category;
if args.use_alternate_kinovi {
job_type = InferenceJobType::Seedance2ProAltQueue;
external_third_party = InferenceJobExternalThirdParty::Seedance2ProAlt;
product_category = InferenceJobProductCategory::Seedance2ProVideoAlt;
let (job_type, external_third_party, product_category) = if args.use_alternate_kinovi {
(
InferenceJobType::Seedance2ProAltQueue,
InferenceJobExternalThirdParty::Seedance2ProAlt,
InferenceJobProductCategory::Seedance2ProVideoAlt,
)
} else {
job_type = InferenceJobType::Seedance2ProQueue;
external_third_party = InferenceJobExternalThirdParty::Seedance2Pro;
product_category = InferenceJobProductCategory::Seedance2ProVideo;
}
let query = sqlx::query!(
r#"
INSERT INTO generic_inference_jobs
SET
token = ?,
uuid_idempotency_token = ?,
job_type = ?,
maybe_external_third_party = ?,
maybe_external_third_party_id = ?,
product_category = ?,
inference_category = ?,
maybe_model_type = NULL,
maybe_model_token = NULL,
maybe_input_source_token = NULL,
maybe_input_source_token_type = NULL,
maybe_download_url = NULL,
maybe_cover_image_media_file_token = NULL,
maybe_prompt_token = ?,
maybe_wallet_ledger_entry_token = ?,
maybe_raw_inference_text = NULL,
maybe_inference_args = ?,
maybe_creator_user_token = ?,
maybe_creator_anonymous_visitor_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
priority_level = 0,
is_keepalive_required = FALSE,
max_duration_seconds = 0,
is_debug_request = FALSE,
maybe_routing_tag = NULL,
maybe_debug_log_event_token = ?,
status = ?
"#,
args.apriori_job_token.as_str(),
args.uuid_idempotency_token,
job_type.to_str(),
external_third_party.to_str(),
args.maybe_external_third_party_id,
product_category.to_str(),
INFERENCE_CATEGORY.to_str(),
args.maybe_prompt_token.map(|t| t.to_string()),
args.maybe_wallet_ledger_entry_token.map(|t| t.to_string()),
serialized_args_payload,
args.maybe_creator_user_token.map(|t| t.to_string()),
args.maybe_avt_token.map(|t| t.to_string()),
args.creator_ip_address,
args.creator_set_visibility.to_str(),
args.maybe_debug_log_event_token.map(|t| t.as_str()),
STATUS.to_str(),
);
let query_result = query.execute(args.mysql_executor)
.await;
let record_id = match query_result {
Err(err) => return Err(DatabaseQueryError::from(err)),
Ok(res) => res.last_insert_id(),
(
InferenceJobType::Seedance2ProQueue,
InferenceJobExternalThirdParty::Seedance2Pro,
InferenceJobProductCategory::Seedance2ProVideo,
)
};
let inner_args = InsertGenericInferenceJobForProviderArgs {
apriori_job_token: args.apriori_job_token,
uuid_idempotency_token: args.uuid_idempotency_token,
job_type,
external_third_party,
external_third_party_id: args.maybe_external_third_party_id,
product_category,
inference_category: InferenceCategory::VideoGeneration,
maybe_prompt_token: args.maybe_prompt_token,
maybe_wallet_ledger_entry_token: args.maybe_wallet_ledger_entry_token,
maybe_inference_args: args.maybe_inference_args,
maybe_creator_user_token: args.maybe_creator_user_token,
maybe_avt_token: args.maybe_avt_token,
creator_ip_address: args.creator_ip_address,
creator_set_visibility: args.creator_set_visibility,
maybe_debug_log_event_token: args.maybe_debug_log_event_token,
maybe_frontend_failure_category: None,
maybe_failure_reason: None,
status: JobStatusPlus::Pending,
mysql_executor: args.mysql_executor,
phantom: args.phantom,
};
let record_id = insert_generic_inference_job_for_provider(inner_args).await?;
info!("Insert generic inference job for Seedance 2 Pro queue: {} with record ID {}", args.apriori_job_token, record_id);
Ok(args.apriori_job_token.clone())
@@ -1,4 +1,3 @@
use anyhow::anyhow;
use log::info;
use sqlx::{Executor, MySql};
use std::marker::PhantomData;
@@ -17,6 +16,10 @@ use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::payloads::generic_inference_args::generic_inference_args::GenericInferenceArgs;
use crate::queries::generic_inference::api_providers::common::insert_generic_inference_job_for_provider::{
insert_generic_inference_job_for_provider,
InsertGenericInferenceJobForProviderArgs,
};
pub struct InsertGenericInferenceForWorldlabsWithAprioriJobTokenArgs<'e, 'c, E>
where E: 'e + Executor<'c, Database = MySql>
@@ -49,94 +52,32 @@ pub async fn insert_generic_inference_job_for_worldlabs_queue_with_apriori_job_t
) -> Result<InferenceJobToken, DatabaseQueryError>
where E: 'e + Executor<'c, Database = MySql>
{
let serialized_args_payload = serde_json::ser::to_string(&args.maybe_inference_args)
.map_err(|_e| anyhow!("could not encode inference args"))?;
const JOB_TYPE: InferenceJobType = InferenceJobType::WorldlabsQueue;
const INFERENCE_CATEGORY: InferenceCategory = InferenceCategory::SplatGeneration;
const PRODUCT_CATEGORY: InferenceJobProductCategory = InferenceJobProductCategory::WorldlabsSplat;
const EXTERNAL_THIRD_PARTY: InferenceJobExternalThirdParty = InferenceJobExternalThirdParty::Worldlabs;
const STATUS: JobStatusPlus = JobStatusPlus::Pending;
let query = sqlx::query!(
r#"
INSERT INTO generic_inference_jobs
SET
token = ?,
uuid_idempotency_token = ?,
job_type = ?,
maybe_external_third_party = ?,
maybe_external_third_party_id = ?,
product_category = ?,
inference_category = ?,
maybe_model_type = NULL,
maybe_model_token = NULL,
maybe_input_source_token = NULL,
maybe_input_source_token_type = NULL,
maybe_download_url = NULL,
maybe_cover_image_media_file_token = NULL,
maybe_prompt_token = ?,
maybe_wallet_ledger_entry_token = ?,
maybe_raw_inference_text = NULL,
maybe_inference_args = ?,
maybe_creator_user_token = ?,
maybe_creator_anonymous_visitor_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
priority_level = 0,
is_keepalive_required = FALSE,
max_duration_seconds = 0,
is_debug_request = FALSE,
maybe_routing_tag = NULL,
status = ?
"#,
args.apriori_job_token.as_str(),
args.uuid_idempotency_token,
JOB_TYPE.to_str(),
EXTERNAL_THIRD_PARTY.to_str(),
args.maybe_external_third_party_id,
PRODUCT_CATEGORY.to_str(),
INFERENCE_CATEGORY.to_str(),
args.maybe_prompt_token.map(|t| t.to_string()),
args.maybe_wallet_ledger_entry_token.map(|t| t.to_string()),
serialized_args_payload,
args.maybe_creator_user_token.map(|t| t.to_string()),
args.maybe_avt_token.map(|t| t.to_string()),
args.creator_ip_address,
args.creator_set_visibility.to_str(),
STATUS.to_str(),
);
let query_result = query.execute(args.mysql_executor)
.await;
let record_id = match query_result {
Err(err) => return Err(DatabaseQueryError::from(err)),
Ok(res) => res.last_insert_id(),
let inner_args = InsertGenericInferenceJobForProviderArgs {
apriori_job_token: args.apriori_job_token,
uuid_idempotency_token: args.uuid_idempotency_token,
job_type: InferenceJobType::WorldlabsQueue,
external_third_party: InferenceJobExternalThirdParty::Worldlabs,
external_third_party_id: args.maybe_external_third_party_id,
product_category: InferenceJobProductCategory::WorldlabsSplat,
inference_category: InferenceCategory::SplatGeneration,
maybe_prompt_token: args.maybe_prompt_token,
maybe_wallet_ledger_entry_token: args.maybe_wallet_ledger_entry_token,
maybe_inference_args: args.maybe_inference_args,
maybe_creator_user_token: args.maybe_creator_user_token,
maybe_avt_token: args.maybe_avt_token,
creator_ip_address: args.creator_ip_address,
creator_set_visibility: args.creator_set_visibility,
// The original Worldlabs query never set this column — preserved (default NULL).
maybe_debug_log_event_token: None,
maybe_frontend_failure_category: None,
maybe_failure_reason: None,
status: JobStatusPlus::Pending,
mysql_executor: args.mysql_executor,
phantom: args.phantom,
};
let record_id = insert_generic_inference_job_for_provider(inner_args).await?;
info!("Insert generic inference job for World Labs queue: {} with record ID {}", args.apriori_job_token, record_id);
Ok(args.apriori_job_token.clone())
@@ -0,0 +1,226 @@
//! Inner-most insert for the `generic_inference_jobs` table.
//!
//! This is the *only* place in the crate that owns the raw `INSERT` query.
//! Every other "insert" function — provider-specific leaves and the
//! web-flavored convenience function — must funnel through here so that
//! the column list and all the marshaling logic (inference_args JSON,
//! routing_tag trim/truncate, failure_reason 255-char clamp) lives in
//! exactly one place.
//!
//! The args struct is a superset: web fields (model/input/download/etc.) and
//! provider fields (external_third_party, wallet_ledger_entry, debug log
//! event, failure category/reason) are all here as `Option`. Leaves pass
//! `None` for fields that don't apply, and `None` writes DB `NULL`.
//!
//! Visibility is `pub(crate)`: external callers must use a leaf function,
//! never this directly.
use anyhow::anyhow;
use sqlx::{Executor, MySql};
use std::marker::PhantomData;
use enums::by_table::generic_inference_jobs::frontend_failure_category::FrontendFailureCategory;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
use enums::by_table::generic_inference_jobs::inference_input_source_token_type::InferenceInputSourceTokenType;
use enums::by_table::generic_inference_jobs::inference_job_external_third_party::InferenceJobExternalThirdParty;
use enums::by_table::generic_inference_jobs::inference_job_product_category::InferenceJobProductCategory;
use enums::by_table::generic_inference_jobs::inference_job_type::InferenceJobType;
use enums::by_table::generic_inference_jobs::inference_model_type::InferenceModelType;
use enums::common::job_status_plus::JobStatusPlus;
use enums::common::visibility::Visibility;
use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken;
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use tokens::tokens::non_unique::debug_logs_event_token::DebugLogEventToken;
use tokens::tokens::prompts::PromptToken;
use tokens::tokens::users::UserToken;
use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::payloads::generic_inference_args::generic_inference_args::GenericInferenceArgs;
pub(crate) struct InsertFullGenericInferenceJobRecordArgs<'e, 'c, E>
where E: 'e + Executor<'c, Database = MySql>
{
pub token: &'e InferenceJobToken,
pub uuid_idempotency_token: &'e str,
pub job_type: InferenceJobType,
pub maybe_external_third_party: Option<InferenceJobExternalThirdParty>,
pub maybe_external_third_party_id: Option<&'e str>,
pub maybe_product_category: Option<InferenceJobProductCategory>,
pub inference_category: InferenceCategory,
pub maybe_model_type: Option<InferenceModelType>,
pub maybe_model_token: Option<&'e str>,
pub maybe_input_source_token: Option<&'e str>,
pub maybe_input_source_token_type: Option<InferenceInputSourceTokenType>,
pub maybe_download_url: Option<&'e str>,
pub maybe_cover_image_media_file_token: Option<&'e MediaFileToken>,
pub maybe_prompt_token: Option<&'e PromptToken>,
pub maybe_wallet_ledger_entry_token: Option<&'e WalletLedgerEntryToken>,
pub maybe_raw_inference_text: Option<&'e str>,
/// Serialized to JSON here and written to `maybe_inference_args`. `None`
/// writes DB `NULL` (never the four-character `"null"` literal).
pub maybe_inference_args: Option<GenericInferenceArgs>,
pub maybe_creator_user_token: Option<&'e UserToken>,
pub maybe_avt_token: Option<&'e AnonymousVisitorTrackingToken>,
pub creator_ip_address: &'e str,
pub creator_set_visibility: Visibility,
pub priority_level: u8,
pub requires_keepalive: bool,
pub max_duration_seconds: i32,
pub is_debug_request: bool,
pub maybe_routing_tag: Option<&'e str>,
pub maybe_debug_log_event_token: Option<&'e DebugLogEventToken>,
pub maybe_frontend_failure_category: Option<FrontendFailureCategory>,
pub maybe_failure_reason: Option<&'e str>,
pub status: JobStatusPlus,
pub mysql_executor: E,
pub phantom: PhantomData<&'c E>,
}
pub(crate) async fn insert_full_generic_inference_job_record<'e, 'c: 'e, E>(
args: InsertFullGenericInferenceJobRecordArgs<'e, 'c, E>,
) -> Result<u64, DatabaseQueryError>
where E: 'e + Executor<'c, Database = MySql>
{
// VARCHAR(32) historically, but the web insert was truncating to 64 and
// trimming — preserve exactly so the refactor is behavior-neutral.
let maybe_routing_tag = args.maybe_routing_tag
.map(|tag| {
let mut tag = tag.trim().to_string();
tag.truncate(64);
tag
});
let maybe_truncated_failure_reason = args.maybe_failure_reason
.map(|s| if s.len() > 255 { &s[..255] } else { s });
// Serialize Some(args) → JSON string; None → DB NULL.
let maybe_inference_args_json = match args.maybe_inference_args.as_ref() {
Some(payload) => Some(
serde_json::ser::to_string(payload)
.map_err(|_e| anyhow!("could not encode inference args"))?
),
None => None,
};
let query = sqlx::query!(
r#"
INSERT INTO generic_inference_jobs
SET
token = ?,
uuid_idempotency_token = ?,
job_type = ?,
maybe_external_third_party = ?,
maybe_external_third_party_id = ?,
product_category = ?,
inference_category = ?,
maybe_model_type = ?,
maybe_model_token = ?,
maybe_input_source_token = ?,
maybe_input_source_token_type = ?,
maybe_download_url = ?,
maybe_cover_image_media_file_token = ?,
maybe_prompt_token = ?,
maybe_wallet_ledger_entry_token = ?,
maybe_raw_inference_text = ?,
maybe_inference_args = ?,
maybe_creator_user_token = ?,
maybe_creator_anonymous_visitor_token = ?,
creator_ip_address = ?,
creator_set_visibility = ?,
priority_level = ?,
is_keepalive_required = ?,
max_duration_seconds = ?,
is_debug_request = ?,
maybe_routing_tag = ?,
maybe_debug_log_event_token = ?,
frontend_failure_category = ?,
failure_reason = ?,
status = ?
"#,
args.token.as_str(),
args.uuid_idempotency_token,
args.job_type.to_str(),
args.maybe_external_third_party.map(|e| e.to_str()),
args.maybe_external_third_party_id,
args.maybe_product_category.map(|c| c.to_str()),
args.inference_category.to_str(),
args.maybe_model_type.map(|t| t.to_str()),
args.maybe_model_token,
args.maybe_input_source_token,
args.maybe_input_source_token_type.map(|t| t.to_str()),
args.maybe_download_url,
args.maybe_cover_image_media_file_token.map(|t| t.as_str()),
args.maybe_prompt_token.map(|t| t.to_string()),
args.maybe_wallet_ledger_entry_token.map(|t| t.to_string()),
args.maybe_raw_inference_text,
maybe_inference_args_json,
args.maybe_creator_user_token.map(|t| t.to_string()),
args.maybe_avt_token.map(|t| t.to_string()),
args.creator_ip_address,
args.creator_set_visibility.to_str(),
args.priority_level,
args.requires_keepalive,
args.max_duration_seconds,
args.is_debug_request,
maybe_routing_tag,
args.maybe_debug_log_event_token.map(|t| t.as_str()),
args.maybe_frontend_failure_category.map(|c| c.to_str()),
maybe_truncated_failure_reason,
args.status.to_str(),
);
let record_id = query.execute(args.mysql_executor)
.await?
.last_insert_id();
Ok(record_id)
}
@@ -0,0 +1 @@
pub(crate) mod insert_full_generic_inference_job_record;
@@ -1,4 +1,5 @@
pub mod api_providers;
pub(crate) mod common;
pub mod job;
pub mod moderation;
pub mod web;
@@ -1,5 +1,5 @@
use anyhow::anyhow;
use sqlx::error::DatabaseError;
use std::marker::PhantomData;
use sqlx::MySqlPool;
use enums::by_table::generic_inference_jobs::inference_category::InferenceCategory;
@@ -7,6 +7,7 @@ use enums::by_table::generic_inference_jobs::inference_input_source_token_type::
use enums::by_table::generic_inference_jobs::inference_job_product_category::InferenceJobProductCategory;
use enums::by_table::generic_inference_jobs::inference_job_type::InferenceJobType;
use enums::by_table::generic_inference_jobs::inference_model_type::InferenceModelType;
use enums::common::job_status_plus::JobStatusPlus;
use enums::common::visibility::Visibility;
use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken;
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
@@ -15,6 +16,10 @@ use tokens::tokens::users::UserToken;
use crate::errors::database_query_error::DatabaseQueryError;
use crate::payloads::generic_inference_args::generic_inference_args::GenericInferenceArgs;
use crate::queries::generic_inference::common::insert_full_generic_inference_job_record::{
insert_full_generic_inference_job_record,
InsertFullGenericInferenceJobRecordArgs,
};
pub struct InsertGenericInferenceArgs<'a> {
pub uuid_idempotency_token: &'a str,
@@ -69,105 +74,63 @@ pub async fn insert_generic_inference_job(args: InsertGenericInferenceArgs<'_>)
{
let job_token = InferenceJobToken::generate();
let serialized_args_payload = serde_json::ser::to_string(&args.maybe_inference_args)
.map_err(|_e| anyhow!("could not encode inference args"))?;
// The routing tag column is VARCHAR(32), so we should truncate.
let maybe_routing_tag = args.maybe_routing_tag
.map(|routing_tag| {
let mut routing_tag = routing_tag.trim().to_string();
routing_tag.truncate(64);
routing_tag
});
// This only applies to certain types of inference.
// "0" is the default value, typically 12 seconds for TTS.
// "-1" means "unlimited"
let max_duration_seconds = args.maybe_max_duration_seconds.unwrap_or(0);
let query = sqlx::query!(
r#"
INSERT INTO generic_inference_jobs
SET
token = ?,
uuid_idempotency_token = ?,
let inner_args = InsertFullGenericInferenceJobRecordArgs {
token: &job_token,
uuid_idempotency_token: args.uuid_idempotency_token,
job_type = ?,
job_type: args.job_type,
product_category = ?,
// Web-driven jobs are not bound to a specific upstream provider here.
maybe_external_third_party: None,
maybe_external_third_party_id: None,
inference_category = ?,
maybe_model_type = ?,
maybe_model_token = ?,
maybe_product_category: args.maybe_product_category,
inference_category: args.inference_category,
maybe_input_source_token = ?,
maybe_input_source_token_type = ?,
maybe_model_type: args.maybe_model_type,
maybe_model_token: args.maybe_model_token,
maybe_download_url = ?,
maybe_cover_image_media_file_token = ?,
maybe_input_source_token: args.maybe_input_source_token,
maybe_input_source_token_type: args.maybe_input_source_token_type,
maybe_raw_inference_text = ?,
maybe_download_url: args.maybe_download_url,
maybe_cover_image_media_file_token: args.maybe_cover_image_media_file_token,
maybe_inference_args = ?,
// Web variant didn't set these — pass None to keep DB NULL.
maybe_prompt_token: None,
maybe_wallet_ledger_entry_token: None,
maybe_creator_user_token = ?,
maybe_creator_anonymous_visitor_token = ?,
creator_ip_address = ?,
maybe_raw_inference_text: args.maybe_raw_inference_text,
creator_set_visibility = ?,
maybe_inference_args: args.maybe_inference_args,
priority_level = ?,
is_keepalive_required = ?,
max_duration_seconds = ?,
maybe_creator_user_token: args.maybe_creator_user_token,
maybe_avt_token: args.maybe_avt_token,
creator_ip_address: args.creator_ip_address,
creator_set_visibility: args.creator_set_visibility,
is_debug_request = ?,
maybe_routing_tag = ?,
priority_level: args.priority_level,
requires_keepalive: args.requires_keepalive,
max_duration_seconds,
is_debug_request: args.is_debug_request,
status = "pending"
"#,
job_token.as_str(),
args.uuid_idempotency_token,
maybe_routing_tag: args.maybe_routing_tag,
args.job_type.to_str(),
maybe_debug_log_event_token: None,
maybe_frontend_failure_category: None,
maybe_failure_reason: None,
args.maybe_product_category.map(|c| c.to_str()),
status: JobStatusPlus::Pending,
args.inference_category.to_str(),
args.maybe_model_type.map(|t| t.to_str()),
args.maybe_model_token,
args.maybe_input_source_token,
args.maybe_input_source_token_type,
args.maybe_download_url,
args.maybe_cover_image_media_file_token.map(|t| t.as_str()),
args.maybe_raw_inference_text,
serialized_args_payload,
args.maybe_creator_user_token.map(|t| t.to_string()),
args.maybe_avt_token.map(|t| t.to_string()),
args.creator_ip_address,
args.creator_set_visibility.to_str(),
args.priority_level,
args.requires_keepalive,
max_duration_seconds,
args.is_debug_request,
maybe_routing_tag,
);
let query_result = query.execute(args.mysql_pool)
.await;
let record_id = match query_result {
Err(err) => return Err(DatabaseQueryError::from(err)),
Ok(res) => res.last_insert_id(),
mysql_executor: args.mysql_pool,
phantom: PhantomData,
};
let record_id = insert_full_generic_inference_job_record(inner_args).await?;
Ok((job_token, record_id))
}