mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-27 12:10:08 -04:00
Compare commits
78
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1b8128036 | ||
|
|
bf1bc62346 | ||
|
|
1e681a5825 | ||
|
|
4fbf8625cc | ||
|
|
c4d063beb9 | ||
|
|
1bd8c46e51 | ||
|
|
288ba16ab4 | ||
|
|
e106b2179f | ||
|
|
fa9e95187f | ||
|
|
cfa14769cd | ||
|
|
56d1649a9f | ||
|
|
e070028bf1 | ||
|
|
52fdf237ad | ||
|
|
15d286135a | ||
|
|
dc1845becb | ||
|
|
a654e9ada1 | ||
|
|
2843916852 | ||
|
|
4d89caf6ff | ||
|
|
d68a92e7cf | ||
|
|
2b9e168d36 | ||
|
|
12542cb684 | ||
|
|
db24eff600 | ||
|
|
d265cecdce | ||
|
|
6be0ce86eb | ||
|
|
573da67788 | ||
|
|
0651afd6fa | ||
|
|
650cf55421 | ||
|
|
338210a568 | ||
|
|
555740dd7e | ||
|
|
f688e83ee9 | ||
|
|
2cfcc04b92 | ||
|
|
7cb7ae9e54 | ||
|
|
1feb4be5f9 | ||
|
|
9e13c7c307 | ||
|
|
1076ea1b31 | ||
|
|
2a101487b0 | ||
|
|
d374317a77 | ||
|
|
f342befb0b | ||
|
|
13d1afd88d | ||
|
|
135dea926b | ||
|
|
4f68100c8f | ||
|
|
908f5cd3d6 | ||
|
|
5a57e48fcb | ||
|
|
69666c2646 | ||
|
|
4ed8b2111b | ||
|
|
d0fe9e1676 | ||
|
|
d455056c61 | ||
|
|
f17388c9de | ||
|
|
7665a07227 | ||
|
|
6dc55c1b62 | ||
|
|
0d565563b2 | ||
|
|
0125539cd4 | ||
|
|
f141434821 | ||
|
|
af12616426 | ||
|
|
62c5836176 | ||
|
|
520117d5d3 | ||
|
|
2e23c0c1b4 | ||
|
|
cd76b7c87f | ||
|
|
668300d280 | ||
|
|
1650fff9dc | ||
|
|
91a4fa8da0 | ||
|
|
621d404992 | ||
|
|
96c751e038 | ||
|
|
4c1eb5fce1 | ||
|
|
2a2e1ddf30 | ||
|
|
367f4fb675 | ||
|
|
074ae52190 | ||
|
|
77297c7a36 | ||
|
|
0337e64f9d | ||
|
|
7ee421cfbe | ||
|
|
cb2f43cc43 | ||
|
|
20d4c9a9e7 | ||
|
|
711078a4e4 | ||
|
|
d45b82109d | ||
|
|
e5bd4b2577 | ||
|
|
841a44d923 | ||
|
|
5ac0088b47 | ||
|
|
3654676a13 |
@@ -36,6 +36,7 @@ script/socat_dev_database_connect.sh
|
||||
venv/
|
||||
|
||||
# Testing
|
||||
/prompts/
|
||||
/requests/
|
||||
|
||||
# Scratch data
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n j.status as `job_status: enums::common::job_status_plus::JobStatusPlus`,\n j.failure_reason as job_failure_reason,\n wle.credits_delta,\n wle.maybe_linked_refund_ledger_token as `maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`,\n j.on_success_result_entity_token as `on_success_result_media_token: tokens::tokens::media_files::MediaFileToken`,\n j.token as `job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken`,\n wle.token as `wallet_ledger_entry_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`,\n wle.entry_type as `wallet_ledger_entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType`\nFROM generic_inference_jobs as j\nLEFT OUTER JOIN users as u\n ON j.maybe_creator_user_token = u.token\nLEFT OUTER JOIN wallet_ledger_entries as wle\n ON wle.maybe_entity_ref = j.token\nWHERE u.token = ?\nORDER BY j.id DESC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "job_status: enums::common::job_status_plus::JobStatusPlus",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | ENUM",
|
||||
"char_set": 224,
|
||||
"max_size": 76
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "job_failure_reason",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 2048
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "credits_delta",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "",
|
||||
"char_set": 63,
|
||||
"max_size": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "on_success_result_media_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "job_token: tokens::tokens::generic_inference_jobs::InferenceJobToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "wallet_ledger_entry_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "wallet_ledger_entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "0757d81ba153b2ad2df25df3dd92b655ef08b95f5f83251bf3573f9be3a9f8d1"
|
||||
}
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nINSERT INTO users\nSET\n token = ?,\n \n is_temporary = ?,\n \n username = ?,\n display_name = ?,\n\n username_is_generated = ?,\n username_is_not_customized = ?,\n\n email_address = ?,\n email_gravatar_hash = ?,\n\n email_confirmed = FALSE,\n email_confirmed_by_google = ?,\n email_is_synthetic = ?,\n \n was_eagerly_provisioned = ?,\n\n profile_markdown = ?,\n profile_rendered_html = ?,\n user_role_slug = ?,\n\n password_hash = ?,\n is_without_password = ?,\n\n maybe_feature_flags = ?,\n\n ip_address_creation = ?,\n ip_address_last_login = ?,\n ip_address_last_update = ?,\n\n maybe_source = ?,\n\n maybe_signup_method = ?\n ",
|
||||
"query": "\nINSERT INTO users\nSET\n token = ?,\n \n is_temporary = ?,\n \n username = ?,\n display_name = ?,\n\n username_is_generated = ?,\n username_is_not_customized = ?,\n\n email_address = ?,\n email_gravatar_hash = ?,\n\n email_confirmed = FALSE,\n email_confirmed_by_google = ?,\n email_is_synthetic = ?,\n \n was_eagerly_provisioned = ?,\n\n profile_markdown = ?,\n profile_rendered_html = ?,\n user_role_slug = ?,\n\n password_hash = ?,\n is_without_password = ?,\n\n maybe_feature_flags = ?,\n\n ip_address_creation = ?,\n ip_address_last_login = ?,\n ip_address_last_update = ?,\n\n maybe_source = ?,\n\n maybe_signup_method = ?,\n\n maybe_referral_url = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 22
|
||||
"Right": 23
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "56746bcb993cb33f5492f401ce4fc3fd44d91fed660c2f106cb22e482dffa740"
|
||||
"hash": "08996721482fe897c2721298c04cf0eba5fcf1d04d57397b8afab3dd59feaa8c"
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n user_subscriptions.subscription_namespace as `subscription_namespace: enums::common::payments_namespace::PaymentsNamespace`,\n user_subscriptions.maybe_stripe_subscription_id,\n users.token as `user_token: tokens::tokens::users::UserToken`,\n users.email_address,\n users.username,\n users.display_name\nFROM user_subscriptions\nINNER JOIN users ON users.token = user_subscriptions.user_token\nWHERE\n user_subscriptions.maybe_stripe_customer_id = ?\n AND user_subscriptions.deleted_at IS NULL\n AND users.user_deleted_at IS NULL\n AND users.mod_deleted_at IS NULL\nORDER BY user_subscriptions.created_at DESC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "subscription_namespace: enums::common::payments_namespace::PaymentsNamespace",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "maybe_stripe_subscription_id",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "UNIQUE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "email_address",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "3390084f700ef2444691a02c691a59ccdd66bc8b096547e89c68b58b04dd44e4"
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n w.token as `token: tokens::tokens::wallets::WalletToken`,\n w.wallet_namespace as `wallet_namespace: enums::common::payments_namespace::PaymentsNamespace`,\n w.owner_user_token as `owner_user_token: tokens::tokens::users::UserToken`,\n w.banked_credits as `banked_credits: u32`,\n w.monthly_credits as `monthly_credits: u32`,\n w.version,\n w.created_at as `created_at: DateTime<Utc>`,\n w.updated_at as `updated_at: DateTime<Utc>`\nFROM wallets as w\nWHERE w.token = ?\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token: tokens::tokens::wallets::WalletToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "wallet_namespace: enums::common::payments_namespace::PaymentsNamespace",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "owner_user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "banked_credits: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "monthly_credits: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "version",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "created_at: DateTime<Utc>",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "updated_at: DateTime<Utc>",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "35b09082ebb923c8c3191eaee8553b7c3badbd9152ee43999f7c8ff1a6410fe9"
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n w.token as `token: tokens::tokens::wallets::WalletToken`,\n w.wallet_namespace as `wallet_namespace: enums::common::payments_namespace::PaymentsNamespace`,\n w.banked_credits as `banked_credits: u32`,\n w.monthly_credits as `monthly_credits: u32`,\n w.version,\n w.created_at as `created_at: DateTime<Utc>`,\n w.updated_at as `updated_at: DateTime<Utc>`\nFROM wallets as w\nWHERE w.owner_user_token = ?\nORDER BY w.id DESC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token: tokens::tokens::wallets::WalletToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "wallet_namespace: enums::common::payments_namespace::PaymentsNamespace",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "banked_credits: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "monthly_credits: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "version",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "created_at: DateTime<Utc>",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "updated_at: DateTime<Utc>",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "69b6e933ad400bc574204de301dde6748d2a1723f47c12e86afc05033a60d3a2"
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n token as `token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`,\n wallet_token as `wallet_token: tokens::tokens::wallets::WalletToken`,\n entry_type as `entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType`,\n maybe_entity_ref,\n credits_delta,\n banked_credits_before as `banked_credits_before: u32`,\n banked_credits_after as `banked_credits_after: u32`,\n monthly_credits_before as `monthly_credits_before: u32`,\n monthly_credits_after as `monthly_credits_after: u32`,\n created_at as `created_at: DateTime<Utc>`,\n is_refunded as `is_refunded: bool`,\n maybe_linked_refund_ledger_token as `maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`\nFROM wallet_ledger_entries\nWHERE wallet_token = ?\nORDER BY id DESC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "wallet_token: tokens::tokens::wallets::WalletToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "maybe_entity_ref",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "credits_delta",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "banked_credits_before: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "banked_credits_after: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "monthly_credits_before: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "monthly_credits_after: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "created_at: DateTime<Utc>",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "is_refunded: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "7f874f4ac43d8c66e3ea8cb2fb56f57b93047355dd9faee4df48799f6d1be00a"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\n INSERT INTO web_referrals (\n url,\n domain,\n utm_source,\n utm_medium,\n utm_campaign,\n ip_address,\n anonymous_visitor_token\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 7
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "80f73702374593c141d183d86bd8af73d37fd7118914d0ba12a02f53c1b84c78"
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n users.token as `user_token: tokens::tokens::users::UserToken`,\n username,\n display_name,\n username_is_generated as `username_is_generated: bool`,\n is_temporary as `is_temporary: bool`,\n username_is_not_customized as `username_is_not_customized: bool`,\n email_address,\n email_confirmed as `email_confirmed: bool`,\n email_is_synthetic as `email_is_synthetic: bool`,\n is_without_password as `is_without_password: bool`,\n ip_address_creation,\n ip_address_last_login,\n maybe_avatar_media_file_token as `maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n email_gravatar_hash,\n is_banned as `is_banned: bool`,\n created_at,\n updated_at\nFROM users\nWHERE\n users.username = ?\n AND users.user_deleted_at IS NULL\n AND users.mod_deleted_at IS NULL\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "username_is_generated: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "is_temporary: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "username_is_not_customized: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "email_address",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "email_confirmed: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "email_is_synthetic: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "is_without_password: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "ip_address_creation",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "ip_address_last_login",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "email_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "is_banned: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "97599bdc5467b8750d2546cc6f78457c26d93c3be52921ad9b3531fd88498194"
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n token as `token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`,\n entry_type as `entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType`,\n maybe_entity_ref,\n credits_delta,\n banked_credits_before as `banked_credits_before: u32`,\n banked_credits_after as `banked_credits_after: u32`,\n monthly_credits_before as `monthly_credits_before: u32`,\n monthly_credits_after as `monthly_credits_after: u32`,\n is_refunded as `is_refunded: bool`,\n maybe_linked_refund_ledger_token as `maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken`,\n created_at as `created_at: DateTime<Utc>`\nFROM wallet_ledger_entries\nWHERE token = ?\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "entry_type: enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "maybe_entity_ref",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "credits_delta",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "banked_credits_before: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "banked_credits_after: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "monthly_credits_before: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "monthly_credits_after: u32",
|
||||
"type_info": {
|
||||
"type": "Long",
|
||||
"flags": "NOT_NULL | UNSIGNED",
|
||||
"char_set": 63,
|
||||
"max_size": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "is_refunded: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "maybe_linked_refund_ledger_token: tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "created_at: DateTime<Utc>",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "9c28e9f8f163407755acaca1fb4a72849679b6bf98b8c87e1761200300111232"
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n users.token as `user_token: tokens::tokens::users::UserToken`,\n username,\n display_name,\n username_is_generated as `username_is_generated: bool`,\n is_temporary as `is_temporary: bool`,\n username_is_not_customized as `username_is_not_customized: bool`,\n email_address,\n email_confirmed as `email_confirmed: bool`,\n email_is_synthetic as `email_is_synthetic: bool`,\n is_without_password as `is_without_password: bool`,\n ip_address_creation,\n ip_address_last_login,\n maybe_avatar_media_file_token as `maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n email_gravatar_hash,\n is_banned as `is_banned: bool`,\n created_at,\n updated_at\nFROM users\nWHERE\n users.email_address = ?\n AND users.user_deleted_at IS NULL\n AND users.mod_deleted_at IS NULL\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "username_is_generated: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "is_temporary: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "username_is_not_customized: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "email_address",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "email_confirmed: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "email_is_synthetic: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "is_without_password: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "ip_address_creation",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "ip_address_last_login",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "email_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "is_banned: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "d023eb33c9a06f8b07b1e5d1e255dbb730244bbd764a49d519473e50751a3ddc"
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n users.token as `user_token: tokens::tokens::users::UserToken`,\n username,\n display_name,\n username_is_generated as `username_is_generated: bool`,\n is_temporary as `is_temporary: bool`,\n username_is_not_customized as `username_is_not_customized: bool`,\n email_address,\n email_confirmed as `email_confirmed: bool`,\n email_is_synthetic as `email_is_synthetic: bool`,\n is_without_password as `is_without_password: bool`,\n ip_address_creation,\n ip_address_last_login,\n maybe_avatar_media_file_token as `maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken`,\n email_gravatar_hash,\n is_banned as `is_banned: bool`,\n created_at,\n updated_at\nFROM users\nWHERE\n users.token = ?\n AND users.user_deleted_at IS NULL\n AND users.mod_deleted_at IS NULL\nLIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "user_token: tokens::tokens::users::UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "username",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "display_name",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "username_is_generated: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "is_temporary: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "username_is_not_customized: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "email_address",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "email_confirmed: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "email_is_synthetic: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "is_without_password: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "ip_address_creation",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "ip_address_last_login",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 160
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "maybe_avatar_media_file_token: tokens::tokens::media_files::MediaFileToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "MULTIPLE_KEY | BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 13,
|
||||
"name": "email_gravatar_hash",
|
||||
"type_info": {
|
||||
"type": "String",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 14,
|
||||
"name": "is_banned: bool",
|
||||
"type_info": {
|
||||
"type": "Tiny",
|
||||
"flags": "NOT_NULL",
|
||||
"char_set": 63,
|
||||
"max_size": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 15,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 16,
|
||||
"name": "updated_at",
|
||||
"type_info": {
|
||||
"type": "Timestamp",
|
||||
"flags": "NOT_NULL | BINARY | TIMESTAMP | ON_UPDATE_NOW",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "fd92483d9f1849d5b7f04076446fa98688fec46bb1cba20d005bc8dad4d1c093"
|
||||
}
|
||||
Generated
+57
-12
@@ -791,11 +791,13 @@ dependencies = [
|
||||
"seedance2pro",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"strum 0.28.0",
|
||||
"test_data",
|
||||
"tokens",
|
||||
"tokio",
|
||||
"uuid 1.18.1",
|
||||
"workspace-build-acceleration",
|
||||
"world_labs_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1523,7 +1525,7 @@ dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.13.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
@@ -3471,7 +3473,7 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||
dependencies = [
|
||||
"libloading 0.7.4",
|
||||
"libloading 0.8.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3776,7 +3778,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"storyteller_root",
|
||||
"strum",
|
||||
"strum 0.26.2",
|
||||
"tokens",
|
||||
"tokio",
|
||||
"workspace-build-acceleration",
|
||||
@@ -3938,7 +3940,7 @@ dependencies = [
|
||||
"sqlx",
|
||||
"sqlx-core",
|
||||
"sqlx-mysql",
|
||||
"strum",
|
||||
"strum 0.26.2",
|
||||
"toml 0.8.23",
|
||||
"utoipa",
|
||||
"workspace-build-acceleration",
|
||||
@@ -3952,7 +3954,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"strum",
|
||||
"strum 0.26.2",
|
||||
"toml 0.8.23",
|
||||
"utoipa",
|
||||
"workspace-build-acceleration",
|
||||
@@ -4184,6 +4186,7 @@ dependencies = [
|
||||
"log",
|
||||
"reqwest 0.12.23",
|
||||
"serde",
|
||||
"strum 0.28.0",
|
||||
"test_data",
|
||||
"testing",
|
||||
"tokio",
|
||||
@@ -6501,7 +6504,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.48.5",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7066,7 +7069,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"storyteller_root",
|
||||
"strum",
|
||||
"strum 0.26.2",
|
||||
"tempdir",
|
||||
"tokens",
|
||||
"tokio",
|
||||
@@ -11581,8 +11584,8 @@ dependencies = [
|
||||
"server_environment",
|
||||
"speculoos",
|
||||
"sqlx",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"strum 0.26.2",
|
||||
"strum_macros 0.26.4",
|
||||
"tempdir",
|
||||
"tempfile",
|
||||
"testing",
|
||||
@@ -11601,6 +11604,7 @@ dependencies = [
|
||||
"utoipa-swagger-ui",
|
||||
"videos",
|
||||
"workspace-build-acceleration",
|
||||
"world_labs_api",
|
||||
"wreq",
|
||||
"zip 0.6.6",
|
||||
]
|
||||
@@ -11667,7 +11671,16 @@ version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
"strum_macros 0.26.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd"
|
||||
dependencies = [
|
||||
"strum_macros 0.28.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -11683,6 +11696,18 @@ dependencies = [
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subprocess"
|
||||
version = "0.2.9"
|
||||
@@ -12679,7 +12704,7 @@ dependencies = [
|
||||
"sqlx",
|
||||
"sqlx-core",
|
||||
"sqlx-mysql",
|
||||
"strum",
|
||||
"strum 0.26.2",
|
||||
"utoipa",
|
||||
"workspace-build-acceleration",
|
||||
]
|
||||
@@ -14029,7 +14054,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"strum",
|
||||
"strum 0.26.2",
|
||||
"workspace-build-acceleration",
|
||||
]
|
||||
|
||||
@@ -14984,6 +15009,26 @@ dependencies = [
|
||||
"zstd-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "world_labs_api"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
"env",
|
||||
"env_logger 0.11.9",
|
||||
"errors",
|
||||
"filesys",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum 0.28.0",
|
||||
"tokio",
|
||||
"uuid 1.18.1",
|
||||
"workspace-build-acceleration",
|
||||
"wreq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "world_labs_client"
|
||||
version = "0.0.1"
|
||||
|
||||
+4
-1
@@ -19,6 +19,7 @@ members = [
|
||||
"crates/api_clients/seedance2pro",
|
||||
"crates/api_clients/runwayml_client",
|
||||
"crates/api_clients/thumbnail_generator",
|
||||
"crates/api_clients/world_labs_api",
|
||||
"crates/api_clients/world_labs_client",
|
||||
|
||||
# CLI tools for operations, etc.
|
||||
@@ -248,6 +249,7 @@ tokens = { path = "crates/schema/public/tokens" }
|
||||
url_utils = { path = "crates/lib/url_utils" }
|
||||
users = { path = "crates/lib/users" }
|
||||
web_base64 = { path = "crates/lib/data/web_base64" }
|
||||
world_labs_api = { path = "crates/api_clients/world_labs_api" }
|
||||
world_labs_client = { path = "crates/api_clients/world_labs_client" }
|
||||
|
||||
# External libs
|
||||
@@ -283,12 +285,13 @@ redis = { version = "1.0.2", features = ["r2d2", "tokio-rustls-comp", "tokio-com
|
||||
regex = "1.12.3"
|
||||
reqwest = { version = "0.12.23", default-features = false, features = [ "charset", "http2", "system-proxy", "json", "cookies", "rustls-tls", "gzip" ] }
|
||||
reqwest-websocket = { version = "0.5.0" }
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
serde_derive = "1.0.219"
|
||||
serde_json = "1.0.140"
|
||||
serde_yaml = "0.9.34+deprecated"
|
||||
sha2 = "0.11.0-rc.2"
|
||||
sha3 = "0.10.8"
|
||||
strum = { version = "0.28.0", features = ["derive"] }
|
||||
tauri = { version = "2.8.3", features = ["unstable", "devtools"] } # NB: "devtools" prevents App Store distribution; "ubstable" is needed for window access
|
||||
tauri-plugin-dialog = "2.3.3"
|
||||
tauri-plugin-fs = "2.4.2"
|
||||
|
||||
@@ -55,7 +55,7 @@ We haven't abandoned text-to-asset generation for quick prototyping and ideation
|
||||
|
||||
| Provider | Features |
|
||||
|------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Artcraft | Nano Banana, Nano Banana Pro, GPT-Image-1 / 1.5, Seedance 2 / Seedream 4 / 4.5, Flux 1.1 / Kontext, Veo 2 / 3 / 3.1, Kling 1.6 / 2.1 / 2.5 / 2.6, Seedance, Sora 2 / Pro, Hunyuan 3d 2 / 3 |
|
||||
| Artcraft | Nano Banana, Nano Banana Pro, GPT-Image-1 / 1.5, Seedance 1.0 Lite / 1.5 Pro / 2.0, Seedream 4 / 4.5, Flux 1.1 / Kontext, Veo 2 / 3 / 3.1, Kling 1.6 / 2.1 / 2.5 / 2.6, Sora 2 / Pro, Hunyuan 3d 2 / 3 |
|
||||
| Grok | Grok Imagine, Grok Video |
|
||||
| Midjourney | Image Gen (all versions) |
|
||||
| Sora | Sora 1, Sora 2, GPT-Image-1 |
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE users
|
||||
DROP COLUMN
|
||||
maybe_referral_url;
|
||||
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE users
|
||||
ADD COLUMN
|
||||
maybe_referral_url VARCHAR(255) DEFAULT NULL;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
DROP TABLE web_referrals;
|
||||
@@ -0,0 +1,27 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- Records of web referrals
|
||||
CREATE TABLE web_referrals (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- The referral URL
|
||||
url VARCHAR(255) NOT NULL,
|
||||
|
||||
-- The parsed out referral domain
|
||||
domain VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
utm_source VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
utm_medium VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
utm_campaign VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- ========== INDICES ==========
|
||||
PRIMARY KEY (id)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE web_referrals
|
||||
DROP COLUMN ip_address,
|
||||
DROP COLUMN anonymous_visitor_token;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE web_referrals
|
||||
ADD COLUMN ip_address VARCHAR(40) NOT NULL,
|
||||
ADD COLUMN anonymous_visitor_token VARCHAR(32) DEFAULT NULL;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE web_referrals
|
||||
MODIFY COLUMN utm_source VARCHAR(32) DEFAULT NULL,
|
||||
MODIFY COLUMN utm_medium VARCHAR(32) DEFAULT NULL,
|
||||
MODIFY COLUMN utm_campaign VARCHAR(255) DEFAULT NULL;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
ALTER TABLE web_referrals
|
||||
MODIFY COLUMN utm_source VARCHAR(150) DEFAULT NULL,
|
||||
MODIFY COLUMN utm_medium VARCHAR(150) DEFAULT NULL,
|
||||
MODIFY COLUMN utm_campaign VARCHAR(150) DEFAULT NULL;
|
||||
@@ -220,6 +220,9 @@ CREATE TABLE users (
|
||||
-- statistical evaluation.)
|
||||
was_eagerly_provisioned BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- The referral URL the user arrived from when signing up.
|
||||
maybe_referral_url VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- ========== MODERATION DETAILS ==========
|
||||
|
||||
-- Different than deleted.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
-- Records of web referrals
|
||||
CREATE TABLE web_referrals (
|
||||
-- Not used for anything except replication.
|
||||
id BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- The referral URL
|
||||
url VARCHAR(255) NOT NULL,
|
||||
|
||||
-- The parsed out referral domain
|
||||
domain VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
utm_source VARCHAR(150) DEFAULT NULL,
|
||||
|
||||
utm_medium VARCHAR(150) DEFAULT NULL,
|
||||
|
||||
utm_campaign VARCHAR(150) DEFAULT NULL,
|
||||
|
||||
ip_address VARCHAR(40) NOT NULL,
|
||||
|
||||
anonymous_visitor_token VARCHAR(32) DEFAULT NULL,
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- ========== INDICES ==========
|
||||
PRIMARY KEY (id)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use enums::common::generation::common_splat_model::CommonSplatModel;
|
||||
use enums::common::generation_provider::GenerationProvider;
|
||||
|
||||
pub const ESTIMATE_SPLAT_COST_PATH: &str = "/v1/generate/cost_estimate/splat";
|
||||
|
||||
/// Request body for the splat cost estimate endpoint.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct EstimateSplatCostRequest {
|
||||
/// The splat model to estimate costs for.
|
||||
pub model: CommonSplatModel,
|
||||
|
||||
/// The provider to route the generation through.
|
||||
pub provider: GenerationProvider,
|
||||
|
||||
/// Whether the request includes a reference image.
|
||||
pub has_reference_image: Option<bool>,
|
||||
}
|
||||
|
||||
/// Response body for the splat cost estimate endpoint.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct EstimateSplatCostResponse {
|
||||
pub success: bool,
|
||||
|
||||
/// Estimated cost in credits.
|
||||
pub cost_in_credits: Option<u64>,
|
||||
|
||||
/// Estimated cost in USD cents.
|
||||
pub cost_in_usd_cents: Option<u64>,
|
||||
|
||||
/// Whether the generation is free for this user/plan.
|
||||
pub is_free: bool,
|
||||
|
||||
/// Whether the user has unlimited generations.
|
||||
pub is_unlimited: bool,
|
||||
|
||||
/// Whether the user is rate limited.
|
||||
pub is_rate_limited: bool,
|
||||
|
||||
/// Whether the output will have a watermark.
|
||||
pub has_watermark: bool,
|
||||
}
|
||||
|
||||
/// Error response for the splat cost estimate endpoint.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct EstimateSplatCostError {
|
||||
pub success: bool,
|
||||
pub error_type: EstimateSplatCostErrorType,
|
||||
pub error_message: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum EstimateSplatCostErrorType {
|
||||
InvalidProviderForModel,
|
||||
InvalidInput,
|
||||
}
|
||||
+10
-2
@@ -9,7 +9,10 @@ use enums::common::generation_provider::GenerationProvider;
|
||||
pub const ESTIMATE_VIDEO_COST_PATH: &str = "/v1/generate/cost_estimate/video";
|
||||
|
||||
/// Request body for the video cost estimate endpoint.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
///
|
||||
/// Every model cares about its own set of parameters and not all
|
||||
/// parameters may be relevant for every model.
|
||||
#[derive(Serialize, Deserialize, ToSchema, Debug)]
|
||||
pub struct EstimateVideoCostRequest {
|
||||
/// The video model to estimate costs for.
|
||||
pub model: CommonVideoModel,
|
||||
@@ -34,10 +37,13 @@ pub struct EstimateVideoCostRequest {
|
||||
|
||||
/// Number of videos to generate in parallel.
|
||||
pub video_batch_count: Option<u16>,
|
||||
|
||||
/// Whether to generate audio for the video.
|
||||
pub generate_audio: Option<bool>,
|
||||
}
|
||||
|
||||
/// Describes the type of video generation being requested.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Serialize, Deserialize, ToSchema, Debug)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum GenerationMode {
|
||||
TextToVideo,
|
||||
@@ -99,6 +105,7 @@ mod tests {
|
||||
resolution: None,
|
||||
duration_seconds: None,
|
||||
video_batch_count: None,
|
||||
generate_audio: None,
|
||||
};
|
||||
let serialized = serde_json::to_string(&request).unwrap();
|
||||
assert!(serialized.contains("\"generation_mode\":{\"type\":\"text_to_video\"}"));
|
||||
@@ -115,6 +122,7 @@ mod tests {
|
||||
resolution: None,
|
||||
duration_seconds: None,
|
||||
video_batch_count: None,
|
||||
generate_audio: None,
|
||||
};
|
||||
let serialized = serde_json::to_string(&request).unwrap();
|
||||
assert!(serialized.contains("\"generation_mode\":{\"type\":\"reference_image_to_video\",\"count\":1}"));
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod estimate_image_cost;
|
||||
pub mod estimate_splat_cost;
|
||||
pub mod estimate_video_cost;
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const FLUX_2_LORA_EDIT_IMAGE_ANGLE_PATH: &str = "/v1/generate/image/angle/flux_2_lora";
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema, Debug)]
|
||||
pub struct Flux2LoraEditImageAngleRequest {
|
||||
/// Idempotency token to prevent duplicate requests.
|
||||
pub uuid_idempotency_token: String,
|
||||
|
||||
/// The image to edit with angle adjustment.
|
||||
pub image_media_token: MediaFileToken,
|
||||
|
||||
/// Horizontal rotation angle in degrees.
|
||||
pub horizontal_angle: Option<f64>,
|
||||
|
||||
/// Vertical rotation angle in degrees.
|
||||
pub vertical_angle: Option<f64>,
|
||||
|
||||
/// Zoom level.
|
||||
pub zoom: Option<f64>,
|
||||
|
||||
/// Number of images to generate. Default is one.
|
||||
pub num_images: Option<Flux2LoraEditImageAngleNumImages>,
|
||||
|
||||
/// Output image size. Default is square_hd.
|
||||
pub image_size: Option<Flux2LoraEditImageAngleImageSize>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Flux2LoraEditImageAngleNumImages {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Flux2LoraEditImageAngleImageSize {
|
||||
Square,
|
||||
SquareHd,
|
||||
PortraitFourThree,
|
||||
PortraitSixteenNine,
|
||||
LandscapeFourThree,
|
||||
LandscapeSixteenNine,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct Flux2LoraEditImageAngleResponse {
|
||||
pub success: bool,
|
||||
pub inference_job_token: InferenceJobToken,
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod flux_2_lora_edit_image_angle;
|
||||
pub mod qwen_edit_2511_edit_image_angle;
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const QWEN_EDIT_2511_EDIT_IMAGE_ANGLE_PATH: &str = "/v1/generate/image/angle/qwen_edit_2511";
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema, Debug)]
|
||||
pub struct QwenEdit2511EditImageAngleRequest {
|
||||
/// Idempotency token to prevent duplicate requests.
|
||||
pub uuid_idempotency_token: String,
|
||||
|
||||
/// The image to edit with angle adjustment.
|
||||
pub image_media_token: MediaFileToken,
|
||||
|
||||
/// Horizontal rotation angle in degrees.
|
||||
pub horizontal_angle: Option<f64>,
|
||||
|
||||
/// Vertical rotation angle in degrees.
|
||||
pub vertical_angle: Option<f64>,
|
||||
|
||||
/// Zoom level.
|
||||
pub zoom: Option<f64>,
|
||||
|
||||
/// Additional text prompt to guide the generation.
|
||||
pub additional_prompt: Option<String>,
|
||||
|
||||
/// Number of images to generate. Default is one.
|
||||
pub num_images: Option<QwenEdit2511EditImageAngleNumImages>,
|
||||
|
||||
/// Output image size. Default is square_hd.
|
||||
pub image_size: Option<QwenEdit2511EditImageAngleImageSize>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum QwenEdit2511EditImageAngleNumImages {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum QwenEdit2511EditImageAngleImageSize {
|
||||
Square,
|
||||
SquareHd,
|
||||
PortraitFourThree,
|
||||
PortraitSixteenNine,
|
||||
LandscapeFourThree,
|
||||
LandscapeSixteenNine,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct QwenEdit2511EditImageAngleResponse {
|
||||
pub success: bool,
|
||||
pub inference_job_token: InferenceJobToken,
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod angle;
|
||||
pub mod bg_removal;
|
||||
pub mod edit;
|
||||
pub mod inpaint;
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const BYTEDANCE_SEEDREAM_5_LITE_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/bytedance_seedream_5_lite";
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct BytedanceSeedream5LiteMultiFunctionImageGenRequest {
|
||||
/// Idempotency token to prevent duplicate requests.
|
||||
pub uuid_idempotency_token: String,
|
||||
|
||||
/// Text prompt to generate the image from.
|
||||
pub prompt: Option<String>,
|
||||
|
||||
/// Image media tokens to include in the editing context.
|
||||
/// If present, we're doing image editing (image-to-image / image-editing)
|
||||
/// If absent, we're doing image generation (text-to-image)
|
||||
pub image_media_tokens: Option<Vec<MediaFileToken>>,
|
||||
|
||||
/// Number of images to generate. Default is one.
|
||||
pub num_images: Option<BytedanceSeedream5LiteMultiFunctionImageGenNumImages>,
|
||||
|
||||
pub max_images: Option<BytedanceSeedream5LiteMultiFunctionImageGenMaxImages>,
|
||||
|
||||
pub image_size: Option<BytedanceSeedream5LiteMultiFunctionImageGenImageSize>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BytedanceSeedream5LiteMultiFunctionImageGenNumImages {
|
||||
One, // Default
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BytedanceSeedream5LiteMultiFunctionImageGenMaxImages {
|
||||
One, // Default
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BytedanceSeedream5LiteMultiFunctionImageGenImageSize {
|
||||
// Square
|
||||
Square,
|
||||
SquareHd,
|
||||
// Tall
|
||||
PortraitFourThree,
|
||||
PortraitSixteenNine,
|
||||
// Wide
|
||||
LandscapeFourThree,
|
||||
LandscapeSixteenNine,
|
||||
// Auto (NB: 5 Lite max is auto_3K, not auto_4K like V4.5)
|
||||
Auto2k,
|
||||
Auto3k,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct BytedanceSeedream5LiteMultiFunctionImageGenResponse {
|
||||
pub success: bool,
|
||||
pub inference_job_token: InferenceJobToken,
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
pub mod bytedance_seedream_v4_multi_function_image_gen;
|
||||
pub mod bytedance_seedream_v4p5_multi_function_image_gen;
|
||||
pub mod bytedance_seedream_5_lite_multi_function_image_gen;
|
||||
pub mod gpt_image_1p5_multi_function_image_gen;
|
||||
pub mod nano_banana_2_multi_function_image_gen;
|
||||
pub mod nano_banana_multi_function_image_gen;
|
||||
pub mod nano_banana_pro_multi_function_image_gen;
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const NANO_BANANA_2_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/nano_banana_2";
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema, Debug)]
|
||||
pub struct NanaBanana2MultiFunctionImageGenRequest {
|
||||
/// Idempotency token to prevent duplicate requests.
|
||||
pub uuid_idempotency_token: String,
|
||||
|
||||
/// Text prompt to generate the image from.
|
||||
pub prompt: Option<String>,
|
||||
|
||||
/// Image media tokens to include in the editing context.
|
||||
/// If present, we're doing image editing (image-to-image / image-editing)
|
||||
/// If absent, we're doing image generation (text-to-image)
|
||||
pub image_media_tokens: Option<Vec<MediaFileToken>>,
|
||||
|
||||
/// Number of images to generate. Default is one.
|
||||
pub num_images: Option<NanaBanana2MultiFunctionImageGenNumImages>,
|
||||
|
||||
/// Resolution of the image to generate. Default is OneK (1K).
|
||||
pub resolution: Option<NanaBanana2MultiFunctionImageGenImageResolution>,
|
||||
|
||||
/// Aspect ratio of the images to generate. Default is "1:1"
|
||||
pub aspect_ratio: Option<NanaBanana2MultiFunctionImageGenAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum NanaBanana2MultiFunctionImageGenNumImages {
|
||||
One, // Default
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum NanaBanana2MultiFunctionImageGenImageResolution {
|
||||
HalfK,
|
||||
OneK,
|
||||
TwoK,
|
||||
FourK,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum NanaBanana2MultiFunctionImageGenAspectRatio {
|
||||
// Auto (only for image editing)
|
||||
Auto, // Default for image editing.
|
||||
// Square
|
||||
OneByOne, // Default for text-to-image
|
||||
// Wide
|
||||
FiveByFour,
|
||||
FourByThree,
|
||||
ThreeByTwo,
|
||||
SixteenByNine,
|
||||
TwentyOneByNine,
|
||||
// Tall
|
||||
FourByFive,
|
||||
ThreeByFour,
|
||||
TwoByThree,
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct NanaBanana2MultiFunctionImageGenResponse {
|
||||
pub success: bool,
|
||||
pub inference_job_token: InferenceJobToken,
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod cost_estimate;
|
||||
pub mod image;
|
||||
pub mod object;
|
||||
pub mod splat;
|
||||
pub mod video;
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const GENERATE_WORLDLABS_MARBLE_0P1_MINI_SPLAT_URL_PATH: &str = "/v1/generate/splat/worldlabs_marble_0p1_mini";
|
||||
|
||||
/// World Labs Marble 0.1-mini Splat Generation
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct GenerateWorldlabsMarble0p1MiniSplatRequest {
|
||||
/// Idempotency token to prevent duplicate requests.
|
||||
pub uuid_idempotency_token: String,
|
||||
|
||||
/// Optional image to use as input for world generation.
|
||||
pub image_media_file_token: Option<MediaFileToken>,
|
||||
|
||||
/// Optional text prompt for world generation.
|
||||
pub prompt: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct GenerateWorldlabsMarble0p1MiniSplatResponse {
|
||||
pub success: bool,
|
||||
pub inference_job_token: InferenceJobToken,
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const GENERATE_WORLDLABS_MARBLE_0P1_PLUS_SPLAT_URL_PATH: &str = "/v1/generate/splat/worldlabs_marble_0p1_plus";
|
||||
|
||||
/// World Labs Marble 0.1-plus Splat Generation
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct GenerateWorldlabsMarble0p1PlusSplatRequest {
|
||||
/// Idempotency token to prevent duplicate requests.
|
||||
pub uuid_idempotency_token: String,
|
||||
|
||||
/// Optional image to use as input for world generation.
|
||||
pub image_media_file_token: Option<MediaFileToken>,
|
||||
|
||||
/// Optional text prompt for world generation.
|
||||
pub prompt: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct GenerateWorldlabsMarble0p1PlusSplatResponse {
|
||||
pub success: bool,
|
||||
pub inference_job_token: InferenceJobToken,
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod generate_worldlabs_marble_0p1_mini_splat;
|
||||
pub mod generate_worldlabs_marble_0p1_plus_splat;
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const KLING_3P0_PRO_MULTI_FUNCTION_VIDEO_PATH: &str = "/v1/generate/video/multi_function/kling_3p0_pro";
|
||||
|
||||
/// Both text-to-video and image-to-video in one request.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct Kling3p0ProMultiFunctionVideoGenRequest {
|
||||
/// Idempotency token to prevent duplicate requests.
|
||||
pub uuid_idempotency_token: String,
|
||||
|
||||
/// Text prompt.
|
||||
pub prompt: Option<String>,
|
||||
|
||||
/// Optional negative prompt.
|
||||
pub negative_prompt: Option<String>,
|
||||
|
||||
/// If present, we're doing image-to-video. If absent, text-to-video.
|
||||
pub image_media_token: Option<MediaFileToken>,
|
||||
|
||||
/// Optional end frame image.
|
||||
pub end_image_media_token: Option<MediaFileToken>,
|
||||
|
||||
/// Duration of the video (3-15 seconds).
|
||||
pub duration: Option<Kling3p0ProMultiFunctionVideoGenDuration>,
|
||||
|
||||
/// Whether to generate audio.
|
||||
pub generate_audio: Option<bool>,
|
||||
|
||||
/// Aspect ratio (only for text-to-video).
|
||||
pub aspect_ratio: Option<Kling3p0ProMultiFunctionVideoGenAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling3p0ProMultiFunctionVideoGenDuration {
|
||||
ThreeSeconds,
|
||||
FourSeconds,
|
||||
FiveSeconds,
|
||||
SixSeconds,
|
||||
SevenSeconds,
|
||||
EightSeconds,
|
||||
NineSeconds,
|
||||
TenSeconds,
|
||||
ElevenSeconds,
|
||||
TwelveSeconds,
|
||||
ThirteenSeconds,
|
||||
FourteenSeconds,
|
||||
FifteenSeconds,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling3p0ProMultiFunctionVideoGenAspectRatio {
|
||||
Square,
|
||||
SixteenByNine,
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct Kling3p0ProMultiFunctionVideoGenResponse {
|
||||
pub success: bool,
|
||||
pub inference_job_token: InferenceJobToken,
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const KLING_3P0_STANDARD_MULTI_FUNCTION_VIDEO_PATH: &str = "/v1/generate/video/multi_function/kling_3p0_standard";
|
||||
|
||||
/// Both text-to-video and image-to-video in one request.
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct Kling3p0StandardMultiFunctionVideoGenRequest {
|
||||
/// Idempotency token to prevent duplicate requests.
|
||||
pub uuid_idempotency_token: String,
|
||||
|
||||
/// Text prompt.
|
||||
pub prompt: Option<String>,
|
||||
|
||||
/// Optional negative prompt.
|
||||
pub negative_prompt: Option<String>,
|
||||
|
||||
/// If present, we're doing image-to-video. If absent, text-to-video.
|
||||
pub image_media_token: Option<MediaFileToken>,
|
||||
|
||||
/// Optional end frame image.
|
||||
pub end_image_media_token: Option<MediaFileToken>,
|
||||
|
||||
/// Duration of the video (3-15 seconds).
|
||||
pub duration: Option<Kling3p0StandardMultiFunctionVideoGenDuration>,
|
||||
|
||||
/// Whether to generate audio.
|
||||
pub generate_audio: Option<bool>,
|
||||
|
||||
/// Aspect ratio (only for text-to-video).
|
||||
pub aspect_ratio: Option<Kling3p0StandardMultiFunctionVideoGenAspectRatio>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling3p0StandardMultiFunctionVideoGenDuration {
|
||||
ThreeSeconds,
|
||||
FourSeconds,
|
||||
FiveSeconds,
|
||||
SixSeconds,
|
||||
SevenSeconds,
|
||||
EightSeconds,
|
||||
NineSeconds,
|
||||
TenSeconds,
|
||||
ElevenSeconds,
|
||||
TwelveSeconds,
|
||||
ThirteenSeconds,
|
||||
FourteenSeconds,
|
||||
FifteenSeconds,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Kling3p0StandardMultiFunctionVideoGenAspectRatio {
|
||||
Square,
|
||||
SixteenByNine,
|
||||
NineBySixteen,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct Kling3p0StandardMultiFunctionVideoGenResponse {
|
||||
pub success: bool,
|
||||
pub inference_job_token: InferenceJobToken,
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
pub mod kling_2_5_turbo_multi_function_video_gen;
|
||||
pub mod kling_2_6_multi_function_video_gen;
|
||||
pub mod kling_3p0_pro_multi_function_video_gen;
|
||||
pub mod kling_3p0_standard_multi_function_video_gen;
|
||||
pub mod seedance_1p5_pro_multi_function_video_gen;
|
||||
pub mod seedance_2p0_multi_function_video_gen;
|
||||
pub mod sora_2_multi_function_video_gen;
|
||||
pub mod sora_2_pro_multi_function_video_gen;
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const SEEDANCE_1P5_PRO_MULTI_FUNCTION_VIDEO_GEN_PATH: &str = "/v1/generate/video/multi_function/seedance_1p5_pro";
|
||||
|
||||
/// Both text-to-video and image-to-video in one request.
|
||||
#[derive(Serialize, Deserialize, ToSchema, Debug)]
|
||||
pub struct Seedance1p5ProMultiFunctionVideoGenRequest {
|
||||
/// Idempotency token to prevent duplicate requests.
|
||||
pub uuid_idempotency_token: String,
|
||||
|
||||
/// "Required".
|
||||
/// Required downstream, but we'll coerce null to empty string.
|
||||
/// Text prompt.
|
||||
pub prompt: Option<String>,
|
||||
|
||||
/// Optional.
|
||||
/// Only for image-to-video.
|
||||
/// Source of the starting frame.
|
||||
/// If present, we're doing image-to-video.
|
||||
/// If absent, we're doing text-to-video.
|
||||
pub start_frame_image_media_token: Option<MediaFileToken>,
|
||||
|
||||
/// Optional.
|
||||
/// Only for image-to-video.
|
||||
/// Source of the ending frame.
|
||||
pub end_frame_image_media_token: Option<MediaFileToken>,
|
||||
|
||||
/// Optional.
|
||||
pub resolution: Option<Seedance1p5ProMultiFunctionVideoGenResolution>,
|
||||
|
||||
/// Optional.
|
||||
/// Duration of the video.
|
||||
/// (this is uniform against all modes)
|
||||
pub duration: Option<Seedance1p5ProMultiFunctionVideoGenDuration>,
|
||||
|
||||
/// Optional.
|
||||
pub aspect_ratio: Option<Seedance1p5ProMultiFunctionVideoGenAspectRatio>,
|
||||
|
||||
/// Whether to generate audio.
|
||||
pub generate_audio: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema, Copy, Clone, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Seedance1p5ProMultiFunctionVideoGenResolution {
|
||||
FourEightyP,
|
||||
SevenTwentyP,
|
||||
TenEightyP,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema, Copy, Clone, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Seedance1p5ProMultiFunctionVideoGenDuration {
|
||||
FourSeconds,
|
||||
FiveSeconds,
|
||||
SixSeconds,
|
||||
SevenSeconds,
|
||||
EightSeconds,
|
||||
NineSeconds,
|
||||
TenSeconds,
|
||||
ElevenSeconds,
|
||||
TwelveSeconds,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema, Copy, Clone, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Seedance1p5ProMultiFunctionVideoGenAspectRatio {
|
||||
TwentyOneByNine,
|
||||
SixteenByNine,
|
||||
FourByThree,
|
||||
Square,
|
||||
ThreeByFour,
|
||||
NineBySixteen,
|
||||
Auto,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct Seedance1p5ProMultiFunctionVideoGenResponse {
|
||||
pub success: bool,
|
||||
pub inference_job_token: InferenceJobToken,
|
||||
}
|
||||
@@ -4,8 +4,10 @@ pub mod credits;
|
||||
pub mod generate;
|
||||
pub mod jobs;
|
||||
pub mod media_file;
|
||||
pub mod moderation;
|
||||
pub mod prompts;
|
||||
pub mod stripe_artcraft;
|
||||
pub mod subscriptions;
|
||||
pub mod users;
|
||||
pub mod utils;
|
||||
pub mod utils;
|
||||
pub mod web_referrals;
|
||||
@@ -0,0 +1 @@
|
||||
pub mod user;
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
use enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType;
|
||||
use enums::common::job_status_plus::JobStatusPlus;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const LIST_USER_JOBS_PATH: &str = "/v1/moderation/jobs/user/{user_token}/list";
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct ListUserJobsPathInfo {
|
||||
pub user_token: UserToken,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ListUserJobsResponse {
|
||||
pub success: bool,
|
||||
pub jobs: Vec<ListUserJobsEntry>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ListUserJobsEntry {
|
||||
pub job_status: JobStatusPlus,
|
||||
pub job_failure_reason: Option<String>,
|
||||
pub credits_delta: Option<i32>,
|
||||
pub maybe_linked_refund_ledger_token: Option<WalletLedgerEntryToken>,
|
||||
pub on_success_result_media_token: Option<MediaFileToken>,
|
||||
pub job_token: InferenceJobToken,
|
||||
pub wallet_ledger_entry_token: Option<WalletLedgerEntryToken>,
|
||||
pub wallet_ledger_entry_type: Option<WalletLedgerEntryType>,
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod list_user_jobs;
|
||||
@@ -0,0 +1,4 @@
|
||||
pub mod jobs;
|
||||
pub mod user;
|
||||
pub mod wallet_ledger_entries;
|
||||
pub mod wallets;
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod user_lookup;
|
||||
pub mod user_lookup_by_stripe_customer_id;
|
||||
@@ -0,0 +1,39 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const MODERATOR_USER_LOOKUP_PATH: &str = "/v1/moderation/users/lookup";
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct ModeratorUserLookupRequest {
|
||||
pub search: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ModeratorUserLookupSuccessResponse {
|
||||
pub success: bool,
|
||||
pub maybe_user: Option<ModeratorUserLookupUserDetails>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ModeratorUserLookupUserDetails {
|
||||
pub token: UserToken,
|
||||
pub username: String,
|
||||
pub display_name: String,
|
||||
pub username_is_generated: bool,
|
||||
pub is_temporary: bool,
|
||||
pub username_is_not_customized: bool,
|
||||
pub email_address: String,
|
||||
pub email_confirmed: bool,
|
||||
pub email_is_synthetic: bool,
|
||||
pub is_without_password: bool,
|
||||
pub ip_address_creation: String,
|
||||
pub ip_address_last_login: String,
|
||||
pub maybe_avatar_media_file_token: Option<MediaFileToken>,
|
||||
pub email_gravatar_hash: String,
|
||||
pub is_banned: bool,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
use enums::common::payments_namespace::PaymentsNamespace;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::users::UserToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const MODERATOR_USER_LOOKUP_BY_STRIPE_CUSTOMER_ID_PATH: &str = "/v1/moderation/users/lookup_by_stripe_customer_id";
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct ModeratorUserLookupByStripeCustomerIdRequest {
|
||||
pub stripe_customer_id: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ModeratorUserLookupByStripeCustomerIdResponse {
|
||||
pub success: bool,
|
||||
pub users: Vec<ModeratorUserLookupByStripeCustomerIdEntry>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ModeratorUserLookupByStripeCustomerIdEntry {
|
||||
pub subscription_namespace: PaymentsNamespace,
|
||||
pub maybe_stripe_subscription_id: Option<String>,
|
||||
pub token: UserToken,
|
||||
pub email_address: String,
|
||||
pub username: String,
|
||||
pub display_name: String,
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
|
||||
use tokens::tokens::wallets::WalletToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const LIST_WALLET_LEDGER_ENTRIES_BY_WALLET_PATH: &str = "/v1/moderation/wallet_ledger_entries/wallet/{wallet_token}/list";
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct ListWalletLedgerEntriesByWalletPathInfo {
|
||||
pub wallet_token: WalletToken,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ListWalletLedgerEntriesByWalletResponse {
|
||||
pub success: bool,
|
||||
pub entries: Vec<ListWalletLedgerEntriesByWalletEntry>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ListWalletLedgerEntriesByWalletEntry {
|
||||
pub token: WalletLedgerEntryToken,
|
||||
pub wallet_token: WalletToken,
|
||||
pub entry_type: WalletLedgerEntryType,
|
||||
pub maybe_entity_ref: Option<String>,
|
||||
pub credits_delta: i32,
|
||||
pub banked_credits_before: u32,
|
||||
pub banked_credits_after: u32,
|
||||
pub monthly_credits_before: u32,
|
||||
pub monthly_credits_after: u32,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub is_refunded: bool,
|
||||
pub maybe_linked_refund_ledger_token: Option<WalletLedgerEntryToken>,
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
pub mod list_wallet_ledger_entries_by_wallet;
|
||||
pub mod moderator_get_wallet_ledger_entry;
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use enums::by_table::wallet_ledger_entries::wallet_ledger_entry_type::WalletLedgerEntryType;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::wallet_ledger_entries::WalletLedgerEntryToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const MODERATOR_GET_WALLET_LEDGER_ENTRY_PATH: &str = "/v1/moderation/wallet_ledger_entry/{wallet_ledger_entry_token}";
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct ModeratorGetWalletLedgerEntryPathInfo {
|
||||
pub wallet_ledger_entry_token: WalletLedgerEntryToken,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ModeratorGetWalletLedgerEntryResponse {
|
||||
pub success: bool,
|
||||
pub maybe_entry: Option<ModeratorGetWalletLedgerEntryDetails>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ModeratorGetWalletLedgerEntryDetails {
|
||||
pub token: WalletLedgerEntryToken,
|
||||
pub entry_type: WalletLedgerEntryType,
|
||||
pub maybe_entity_ref: Option<String>,
|
||||
pub credits_delta: i32,
|
||||
pub banked_credits_before: u32,
|
||||
pub banked_credits_after: u32,
|
||||
pub monthly_credits_before: u32,
|
||||
pub monthly_credits_after: u32,
|
||||
pub is_refunded: bool,
|
||||
pub maybe_linked_refund_ledger_token: Option<WalletLedgerEntryToken>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use enums::common::payments_namespace::PaymentsNamespace;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::users::UserToken;
|
||||
use tokens::tokens::wallets::WalletToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const LIST_USER_WALLETS_PATH: &str = "/v1/moderation/wallets/user/{user_token}/list";
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct ListUserWalletsPathInfo {
|
||||
pub user_token: UserToken,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ListUserWalletsResponse {
|
||||
pub success: bool,
|
||||
pub wallets: Vec<ListUserWalletsEntry>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ListUserWalletsEntry {
|
||||
pub token: WalletToken,
|
||||
pub wallet_namespace: PaymentsNamespace,
|
||||
pub banked_credits: u32,
|
||||
pub monthly_credits: u32,
|
||||
pub version: i32,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod list_user_wallets;
|
||||
pub mod moderator_add_banked_balance_to_wallet;
|
||||
pub mod moderator_get_wallet;
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::wallets::WalletToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const MODERATOR_ADD_BANKED_BALANCE_TO_WALLET_PATH: &str = "/v1/moderation/wallet/{wallet_token}/add_banked_balance";
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct ModeratorAddBankedBalanceToWalletPathInfo {
|
||||
pub wallet_token: WalletToken,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct ModeratorAddBankedBalanceToWalletRequest {
|
||||
pub credits: u16,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ModeratorAddBankedBalanceToWalletResponse {
|
||||
pub success: bool,
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use enums::common::payments_namespace::PaymentsNamespace;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokens::tokens::users::UserToken;
|
||||
use tokens::tokens::wallets::WalletToken;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const MODERATOR_GET_WALLET_PATH: &str = "/v1/moderation/wallet/{wallet_token}";
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct ModeratorGetWalletPathInfo {
|
||||
pub wallet_token: WalletToken,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ModeratorGetWalletResponse {
|
||||
pub success: bool,
|
||||
pub maybe_wallet: Option<ModeratorGetWalletDetails>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ModeratorGetWalletDetails {
|
||||
pub token: WalletToken,
|
||||
pub wallet_namespace: PaymentsNamespace,
|
||||
pub owner_user_token: UserToken,
|
||||
pub banked_credits: u32,
|
||||
pub monthly_credits: u32,
|
||||
pub version: i32,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
+5
@@ -11,6 +11,11 @@ pub struct StripeArtcraftCreateSubscriptionCheckoutWithUserSignupRequest {
|
||||
pub plan: Option<ArtcraftSubscriptionSlug>,
|
||||
|
||||
pub cadence: Option<PlanBillingCadence>,
|
||||
|
||||
/// Optional: The referral URL the user arrived from when signing up.
|
||||
/// The browser can send `document.referrer` to the backend so we know how people are finding us.
|
||||
/// If the browser doesn't send this parameter, we'll try the `referer` header.
|
||||
pub maybe_referral_url: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema, Debug, Copy, Clone)]
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub const LOG_WEB_REFERRAL_URL_PATH: &str = "/v1/web_referrals/record";
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct LogWebReferralRequest {
|
||||
/// Optional: The referral URL the user arrived from when signing up.
|
||||
/// The browser can send `document.referrer` to the backend so we know how people are finding us.
|
||||
/// If the browser doesn't send this parameter, we'll try the `referer` header.
|
||||
pub maybe_referral_url: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct LogWebReferralResponse {
|
||||
pub success: bool,
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod log_web_referral;
|
||||
+1
@@ -1,2 +1,3 @@
|
||||
pub mod image;
|
||||
pub mod splat;
|
||||
pub mod video;
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use crate::error::storyteller_error::StorytellerError;
|
||||
use crate::utils::api_host::ApiHost;
|
||||
use crate::utils::basic_json_post_request::basic_json_post_request;
|
||||
use artcraft_api_defs::generate::cost_estimate::estimate_splat_cost::{
|
||||
EstimateSplatCostRequest, EstimateSplatCostResponse, ESTIMATE_SPLAT_COST_PATH,
|
||||
};
|
||||
|
||||
pub async fn estimate_splat_cost(
|
||||
api_host: &ApiHost,
|
||||
maybe_creds: Option<&StorytellerCredentialSet>,
|
||||
request: EstimateSplatCostRequest,
|
||||
) -> Result<EstimateSplatCostResponse, StorytellerError> {
|
||||
Ok(basic_json_post_request(
|
||||
api_host,
|
||||
ESTIMATE_SPLAT_COST_PATH,
|
||||
maybe_creds,
|
||||
request,
|
||||
).await?)
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
pub mod estimate_splat_cost;
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use crate::error::storyteller_error::StorytellerError;
|
||||
use crate::utils::api_host::ApiHost;
|
||||
use crate::utils::basic_json_post_request::basic_json_post_request;
|
||||
use artcraft_api_defs::generate::image::angle::flux_2_lora_edit_image_angle::{
|
||||
Flux2LoraEditImageAngleRequest, Flux2LoraEditImageAngleResponse,
|
||||
FLUX_2_LORA_EDIT_IMAGE_ANGLE_PATH,
|
||||
};
|
||||
|
||||
pub async fn flux_2_lora_edit_image_angle(
|
||||
api_host: &ApiHost,
|
||||
maybe_creds: Option<&StorytellerCredentialSet>,
|
||||
request: Flux2LoraEditImageAngleRequest,
|
||||
) -> Result<Flux2LoraEditImageAngleResponse, StorytellerError> {
|
||||
Ok(basic_json_post_request(
|
||||
api_host,
|
||||
FLUX_2_LORA_EDIT_IMAGE_ANGLE_PATH,
|
||||
maybe_creds,
|
||||
request,
|
||||
).await?)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod flux_2_lora_edit_image_angle;
|
||||
pub mod qwen_edit_2511_edit_image_angle;
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use crate::error::storyteller_error::StorytellerError;
|
||||
use crate::utils::api_host::ApiHost;
|
||||
use crate::utils::basic_json_post_request::basic_json_post_request;
|
||||
use artcraft_api_defs::generate::image::angle::qwen_edit_2511_edit_image_angle::{
|
||||
QwenEdit2511EditImageAngleRequest, QwenEdit2511EditImageAngleResponse,
|
||||
QWEN_EDIT_2511_EDIT_IMAGE_ANGLE_PATH,
|
||||
};
|
||||
|
||||
pub async fn qwen_edit_2511_edit_image_angle(
|
||||
api_host: &ApiHost,
|
||||
maybe_creds: Option<&StorytellerCredentialSet>,
|
||||
request: QwenEdit2511EditImageAngleRequest,
|
||||
) -> Result<QwenEdit2511EditImageAngleResponse, StorytellerError> {
|
||||
Ok(basic_json_post_request(
|
||||
api_host,
|
||||
QWEN_EDIT_2511_EDIT_IMAGE_ANGLE_PATH,
|
||||
maybe_creds,
|
||||
request,
|
||||
).await?)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod angle;
|
||||
pub mod bg_removal;
|
||||
pub mod edit;
|
||||
pub mod inpaint;
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use crate::error::storyteller_error::StorytellerError;
|
||||
use crate::utils::api_host::ApiHost;
|
||||
use crate::utils::basic_json_post_request::basic_json_post_request;
|
||||
use artcraft_api_defs::generate::image::multi_function::bytedance_seedream_5_lite_multi_function_image_gen::{BytedanceSeedream5LiteMultiFunctionImageGenRequest, BytedanceSeedream5LiteMultiFunctionImageGenResponse, BYTEDANCE_SEEDREAM_5_LITE_MULTI_FUNCTION_IMAGE_GEN_PATH};
|
||||
|
||||
pub async fn bytedance_seedream_5_lite_multi_function_image_gen(
|
||||
api_host: &ApiHost,
|
||||
maybe_creds: Option<&StorytellerCredentialSet>,
|
||||
request: BytedanceSeedream5LiteMultiFunctionImageGenRequest,
|
||||
) -> Result<BytedanceSeedream5LiteMultiFunctionImageGenResponse, StorytellerError> {
|
||||
Ok(basic_json_post_request(
|
||||
api_host,
|
||||
BYTEDANCE_SEEDREAM_5_LITE_MULTI_FUNCTION_IMAGE_GEN_PATH,
|
||||
maybe_creds,
|
||||
request,
|
||||
).await?)
|
||||
}
|
||||
+2
@@ -1,5 +1,7 @@
|
||||
pub mod bytedance_seedream_v4_multi_function_image_gen_image;
|
||||
pub mod bytedance_seedream_v4p5_multi_function_image_gen_image;
|
||||
pub mod bytedance_seedream_5_lite_multi_function_image_gen_image;
|
||||
pub mod gpt_image_1p5_multi_function_image_gen_image;
|
||||
pub mod nano_banana_2_multi_function_image_gen_image;
|
||||
pub mod nano_banana_multi_function_image_gen_image;
|
||||
pub mod nano_banana_pro_multi_function_image_gen_image;
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use crate::error::storyteller_error::StorytellerError;
|
||||
use crate::utils::api_host::ApiHost;
|
||||
use crate::utils::basic_json_post_request::basic_json_post_request;
|
||||
use artcraft_api_defs::generate::image::multi_function::nano_banana_2_multi_function_image_gen::{NanaBanana2MultiFunctionImageGenRequest, NanaBanana2MultiFunctionImageGenResponse, NANO_BANANA_2_MULTI_FUNCTION_IMAGE_GEN_PATH};
|
||||
|
||||
pub async fn nano_banana_2_multi_function_image_gen(
|
||||
api_host: &ApiHost,
|
||||
maybe_creds: Option<&StorytellerCredentialSet>,
|
||||
request: NanaBanana2MultiFunctionImageGenRequest,
|
||||
) -> Result<NanaBanana2MultiFunctionImageGenResponse, StorytellerError> {
|
||||
Ok(basic_json_post_request(
|
||||
api_host,
|
||||
NANO_BANANA_2_MULTI_FUNCTION_IMAGE_GEN_PATH,
|
||||
maybe_creds,
|
||||
request,
|
||||
).await?)
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod cost_estimate;
|
||||
pub mod image;
|
||||
pub mod object;
|
||||
pub mod splat;
|
||||
pub mod video;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use crate::error::storyteller_error::StorytellerError;
|
||||
use crate::utils::api_host::ApiHost;
|
||||
use crate::utils::basic_json_post_request::basic_json_post_request;
|
||||
use artcraft_api_defs::generate::splat::generate_worldlabs_marble_0p1_mini_splat::{GenerateWorldlabsMarble0p1MiniSplatRequest, GenerateWorldlabsMarble0p1MiniSplatResponse, GENERATE_WORLDLABS_MARBLE_0P1_MINI_SPLAT_URL_PATH};
|
||||
|
||||
pub async fn generate_worldlabs_marble_0p1_mini_splat(
|
||||
api_host: &ApiHost,
|
||||
maybe_creds: Option<&StorytellerCredentialSet>,
|
||||
request: GenerateWorldlabsMarble0p1MiniSplatRequest,
|
||||
) -> Result<GenerateWorldlabsMarble0p1MiniSplatResponse, StorytellerError> {
|
||||
Ok(basic_json_post_request(
|
||||
api_host,
|
||||
GENERATE_WORLDLABS_MARBLE_0P1_MINI_SPLAT_URL_PATH,
|
||||
maybe_creds,
|
||||
request,
|
||||
).await?)
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use crate::error::storyteller_error::StorytellerError;
|
||||
use crate::utils::api_host::ApiHost;
|
||||
use crate::utils::basic_json_post_request::basic_json_post_request;
|
||||
use artcraft_api_defs::generate::splat::generate_worldlabs_marble_0p1_plus_splat::{GenerateWorldlabsMarble0p1PlusSplatRequest, GenerateWorldlabsMarble0p1PlusSplatResponse, GENERATE_WORLDLABS_MARBLE_0P1_PLUS_SPLAT_URL_PATH};
|
||||
|
||||
pub async fn generate_worldlabs_marble_0p1_plus_splat(
|
||||
api_host: &ApiHost,
|
||||
maybe_creds: Option<&StorytellerCredentialSet>,
|
||||
request: GenerateWorldlabsMarble0p1PlusSplatRequest,
|
||||
) -> Result<GenerateWorldlabsMarble0p1PlusSplatResponse, StorytellerError> {
|
||||
Ok(basic_json_post_request(
|
||||
api_host,
|
||||
GENERATE_WORLDLABS_MARBLE_0P1_PLUS_SPLAT_URL_PATH,
|
||||
maybe_creds,
|
||||
request,
|
||||
).await?)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod generate_worldlabs_marble_0p1_mini_splat;
|
||||
pub mod generate_worldlabs_marble_0p1_plus_splat;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use crate::error::storyteller_error::StorytellerError;
|
||||
use crate::utils::api_host::ApiHost;
|
||||
use crate::utils::basic_json_post_request::basic_json_post_request;
|
||||
use artcraft_api_defs::generate::video::multi_function::kling_3p0_pro_multi_function_video_gen::{Kling3p0ProMultiFunctionVideoGenRequest, Kling3p0ProMultiFunctionVideoGenResponse, KLING_3P0_PRO_MULTI_FUNCTION_VIDEO_PATH};
|
||||
|
||||
pub async fn kling_3p0_pro_multi_function_video_gen(
|
||||
api_host: &ApiHost,
|
||||
maybe_creds: Option<&StorytellerCredentialSet>,
|
||||
request: Kling3p0ProMultiFunctionVideoGenRequest,
|
||||
) -> Result<Kling3p0ProMultiFunctionVideoGenResponse, StorytellerError> {
|
||||
Ok(basic_json_post_request(
|
||||
api_host,
|
||||
KLING_3P0_PRO_MULTI_FUNCTION_VIDEO_PATH,
|
||||
maybe_creds,
|
||||
request,
|
||||
).await?)
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use crate::error::storyteller_error::StorytellerError;
|
||||
use crate::utils::api_host::ApiHost;
|
||||
use crate::utils::basic_json_post_request::basic_json_post_request;
|
||||
use artcraft_api_defs::generate::video::multi_function::kling_3p0_standard_multi_function_video_gen::{Kling3p0StandardMultiFunctionVideoGenRequest, Kling3p0StandardMultiFunctionVideoGenResponse, KLING_3P0_STANDARD_MULTI_FUNCTION_VIDEO_PATH};
|
||||
|
||||
pub async fn kling_3p0_standard_multi_function_video_gen(
|
||||
api_host: &ApiHost,
|
||||
maybe_creds: Option<&StorytellerCredentialSet>,
|
||||
request: Kling3p0StandardMultiFunctionVideoGenRequest,
|
||||
) -> Result<Kling3p0StandardMultiFunctionVideoGenResponse, StorytellerError> {
|
||||
Ok(basic_json_post_request(
|
||||
api_host,
|
||||
KLING_3P0_STANDARD_MULTI_FUNCTION_VIDEO_PATH,
|
||||
maybe_creds,
|
||||
request,
|
||||
).await?)
|
||||
}
|
||||
+3
@@ -1,6 +1,9 @@
|
||||
pub mod kling_2p5_turbo_pro_multi_function_video_gen;
|
||||
pub mod seedance_1p5_pro_multi_function_video_gen;
|
||||
pub mod seedance_2p0_multi_function_video_gen;
|
||||
pub mod kling_2p6_pro_multi_function_video_gen;
|
||||
pub mod kling_3p0_pro_multi_function_video_gen;
|
||||
pub mod kling_3p0_standard_multi_function_video_gen;
|
||||
pub mod sora_2_multi_function_video_gen;
|
||||
pub mod sora_2_pro_multi_function_video_gen;
|
||||
pub mod veo_3p1_fast_multi_function_video_gen;
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
use crate::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use crate::error::storyteller_error::StorytellerError;
|
||||
use crate::utils::api_host::ApiHost;
|
||||
use crate::utils::basic_json_post_request::basic_json_post_request;
|
||||
use artcraft_api_defs::generate::video::multi_function::seedance_1p5_pro_multi_function_video_gen::{Seedance1p5ProMultiFunctionVideoGenRequest, Seedance1p5ProMultiFunctionVideoGenResponse, SEEDANCE_1P5_PRO_MULTI_FUNCTION_VIDEO_GEN_PATH};
|
||||
|
||||
pub async fn seedance_1p5_pro_multi_function_video_gen(
|
||||
api_host: &ApiHost,
|
||||
maybe_creds: Option<&StorytellerCredentialSet>,
|
||||
request: Seedance1p5ProMultiFunctionVideoGenRequest,
|
||||
) -> Result<Seedance1p5ProMultiFunctionVideoGenResponse, StorytellerError> {
|
||||
Ok(basic_json_post_request(
|
||||
api_host,
|
||||
SEEDANCE_1P5_PRO_MULTI_FUNCTION_VIDEO_GEN_PATH,
|
||||
maybe_creds,
|
||||
request,
|
||||
).await?)
|
||||
}
|
||||
@@ -17,10 +17,11 @@ workspace-build-acceleration.workspace = true
|
||||
|
||||
# Internal
|
||||
artcraft_api_defs.workspace = true
|
||||
artcraft_client.workspace = true
|
||||
fal_client.workspace = true
|
||||
seedance2pro.workspace = true
|
||||
artcraft_client.workspace = true
|
||||
tokens.workspace = true
|
||||
world_labs_api.workspace = true
|
||||
|
||||
# External
|
||||
anyhow.workspace = true
|
||||
@@ -32,3 +33,5 @@ uuid.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
test_data.workspace = true
|
||||
strum.workspace = true
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
#[cfg(test)]
|
||||
use strum::EnumIter;
|
||||
|
||||
/// This is a comprehensive list of common aspect ratios you can specify when enqueuing a generation.
|
||||
/// Not every model will support every aspect ratio.
|
||||
/// In the case a model doesn't support the aspect ratio, gracefully pick the nearest option.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(test, derive(EnumIter))]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CommonAspectRatio {
|
||||
// Auto (eg. for image editing to use the source; used by Nano Banana Pro edit image, but not text-to-image)
|
||||
|
||||
@@ -5,6 +5,30 @@ use serde_derive::{Deserialize, Serialize};
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CommonImageModel {
|
||||
#[serde(rename = "flux_1_dev")]
|
||||
Flux1Dev,
|
||||
#[serde(rename = "flux_1_schnell")]
|
||||
Flux1Schnell,
|
||||
#[serde(rename = "flux_pro_1p1")]
|
||||
FluxPro11,
|
||||
#[serde(rename = "flux_pro_1p1_ultra")]
|
||||
FluxPro11Ultra,
|
||||
#[serde(rename = "gpt_image_1p5")]
|
||||
GptImage1p5,
|
||||
#[serde(rename = "nano_banana")]
|
||||
NanaBanana,
|
||||
#[serde(rename = "nano_banana_2")]
|
||||
NanaBanana2,
|
||||
#[serde(rename = "nano_banana_pro")]
|
||||
NanaBananaPro,
|
||||
#[serde(rename = "seedream_4")]
|
||||
Seedream4,
|
||||
#[serde(rename = "seedream_4p5")]
|
||||
Seedream4p5,
|
||||
#[serde(rename = "seedream_5_lite")]
|
||||
Seedream5Lite,
|
||||
#[serde(rename = "qwen_edit_2511_angles")]
|
||||
QwenEdit2511Angles,
|
||||
#[serde(rename = "flux_2_lora_angles")]
|
||||
Flux2LoraAngles,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
/// Common splat models supported by the router.
|
||||
/// Not all models are available through all providers.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CommonSplatModel {
|
||||
#[serde(rename = "marble_0p1_mini")]
|
||||
Marble0p1Mini,
|
||||
|
||||
#[serde(rename = "marble_0p1_plus")]
|
||||
Marble0p1Plus,
|
||||
}
|
||||
@@ -23,9 +23,18 @@ pub enum CommonVideoModel {
|
||||
#[serde(rename = "kling_2p6_pro")]
|
||||
Kling2p6Pro,
|
||||
|
||||
#[serde(rename = "kling_3p0_standard")]
|
||||
Kling3p0Standard,
|
||||
|
||||
#[serde(rename = "kling_3p0_pro")]
|
||||
Kling3p0Pro,
|
||||
|
||||
#[serde(rename = "seedance_1p0_lite")]
|
||||
Seedance10Lite,
|
||||
|
||||
#[serde(rename = "seedance_1p5_pro")]
|
||||
Seedance1p5Pro,
|
||||
|
||||
#[serde(rename = "seedance_2p0")]
|
||||
Seedance2p0,
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod common_aspect_ratio;
|
||||
pub mod common_image_model;
|
||||
pub mod common_resolution;
|
||||
pub mod common_splat_model;
|
||||
pub mod common_video_model;
|
||||
pub mod image_list_ref;
|
||||
pub mod image_ref;
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
|
||||
/// Strategy for handling requests where the model only supports text-to-image
|
||||
/// but the request includes image inputs (image editing mode).
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum GenerationModeMismatchStrategy {
|
||||
/// Abort the generation: return an error if image inputs are provided
|
||||
/// for a text-to-image-only model.
|
||||
AbortGeneration,
|
||||
|
||||
/// Proceed anyway, ignoring the image inputs for the generation.
|
||||
GenerateAnyway,
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod generation_mode_mismatch_strategy;
|
||||
pub mod multi_router_client;
|
||||
pub mod multi_router_client_builder;
|
||||
pub mod request_mismatch_mitigation_strategy;
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
use artcraft_api_defs::generate::image::text::generate_flux_1_dev_text_to_image::GenerateFlux1DevTextToImageNumImages;
|
||||
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_flux_1_dev::PlanArtcraftFlux1Dev;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_flux_1_dev(
|
||||
plan: &PlanArtcraftFlux1Dev<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.02/image (2 cents). 1 credit = 1 USD cent.
|
||||
let cost_per_image: u64 = 2;
|
||||
|
||||
let num_images: u64 = match plan.num_images {
|
||||
GenerateFlux1DevTextToImageNumImages::One => 1,
|
||||
GenerateFlux1DevTextToImageNumImages::Two => 2,
|
||||
GenerateFlux1DevTextToImageNumImages::Three => 3,
|
||||
GenerateFlux1DevTextToImageNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
|
||||
fn estimate_usd_cents(image_batch_count: u16) -> u64 {
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::Flux1Dev,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: None,
|
||||
resolution: None,
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs()
|
||||
.cost_in_usd_cents
|
||||
.expect("cost_in_usd_cents should be present")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_usd_cents() {
|
||||
// $0.02/image = 2 cents each
|
||||
assert_eq!(estimate_usd_cents(1), 2);
|
||||
assert_eq!(estimate_usd_cents(2), 4);
|
||||
assert_eq!(estimate_usd_cents(3), 6);
|
||||
assert_eq!(estimate_usd_cents(4), 8);
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_flux_1_schnell::PlanArtcraftFlux1Schnell;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_flux_1_schnell(
|
||||
_plan: &PlanArtcraftFlux1Schnell<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: not available
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: None,
|
||||
cost_in_usd_cents: None,
|
||||
is_free: true,
|
||||
is_unlimited: true,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_is_none() {
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::Flux1Schnell,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: None,
|
||||
resolution: None,
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(1),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
let estimate = request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs();
|
||||
assert!(estimate.cost_in_usd_cents.is_none());
|
||||
assert!(estimate.cost_in_credits.is_none());
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
use artcraft_api_defs::generate::image::angle::flux_2_lora_edit_image_angle::Flux2LoraEditImageAngleNumImages;
|
||||
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_flux_2_lora_angles::PlanArtcraftFlux2LoraAngles;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_flux_2_lora_angles(
|
||||
plan: &PlanArtcraftFlux2LoraAngles<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.04/image (4 cents). 1 credit = 1 USD cent.
|
||||
let cost_per_image: u64 = 4;
|
||||
|
||||
let num_images: u64 = match plan.num_images {
|
||||
Flux2LoraEditImageAngleNumImages::One => 1,
|
||||
Flux2LoraEditImageAngleNumImages::Two => 2,
|
||||
Flux2LoraEditImageAngleNumImages::Three => 3,
|
||||
Flux2LoraEditImageAngleNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::image_list_ref::ImageListRef;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
fn estimate_usd_cents(image_batch_count: u16) -> u64 {
|
||||
let tokens = vec![MediaFileToken::new_from_str("test_token")];
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::Flux2LoraAngles,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: Some(ImageListRef::MediaFileTokens(&tokens)),
|
||||
resolution: None,
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs()
|
||||
.cost_in_usd_cents
|
||||
.expect("cost_in_usd_cents should be present")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_usd_cents() {
|
||||
// $0.04/image = 4 cents each
|
||||
assert_eq!(estimate_usd_cents(1), 4);
|
||||
assert_eq!(estimate_usd_cents(2), 8);
|
||||
assert_eq!(estimate_usd_cents(3), 12);
|
||||
assert_eq!(estimate_usd_cents(4), 16);
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
use artcraft_api_defs::generate::image::text::generate_flux_pro_11_text_to_image::GenerateFluxPro11TextToImageNumImages;
|
||||
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_flux_pro_1p1::PlanArtcraftFluxPro11;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_flux_pro_1p1(
|
||||
plan: &PlanArtcraftFluxPro11<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// NB(bt): Slightly more than 3 cents, weird megapixel maths. We can eat that cost for now.
|
||||
let cost_per_image: u64 = 3;
|
||||
|
||||
let num_images: u64 = match plan.num_images {
|
||||
GenerateFluxPro11TextToImageNumImages::One => 1,
|
||||
GenerateFluxPro11TextToImageNumImages::Two => 2,
|
||||
GenerateFluxPro11TextToImageNumImages::Three => 3,
|
||||
GenerateFluxPro11TextToImageNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
|
||||
fn estimate_usd_cents(image_batch_count: u16) -> u64 {
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::FluxPro11,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: None,
|
||||
resolution: None,
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs()
|
||||
.cost_in_usd_cents
|
||||
.expect("cost_in_usd_cents should be present")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_usd_cents() {
|
||||
// ~$0.03/image = 3 cents each (slightly more than 3¢ actual, rounded up)
|
||||
assert_eq!(estimate_usd_cents(1), 3);
|
||||
assert_eq!(estimate_usd_cents(2), 6);
|
||||
assert_eq!(estimate_usd_cents(3), 9);
|
||||
assert_eq!(estimate_usd_cents(4), 12);
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
use artcraft_api_defs::generate::image::text::generate_flux_pro_11_ultra_text_to_image::GenerateFluxPro11UltraTextToImageNumImages;
|
||||
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_flux_pro_1p1_ultra::PlanArtcraftFluxPro11Ultra;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_flux_pro_1p1_ultra(
|
||||
plan: &PlanArtcraftFluxPro11Ultra<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.06/image (6 cents). 1 credit = 1 USD cent.
|
||||
let cost_per_image: u64 = 6;
|
||||
|
||||
let num_images: u64 = match plan.num_images {
|
||||
GenerateFluxPro11UltraTextToImageNumImages::One => 1,
|
||||
GenerateFluxPro11UltraTextToImageNumImages::Two => 2,
|
||||
GenerateFluxPro11UltraTextToImageNumImages::Three => 3,
|
||||
GenerateFluxPro11UltraTextToImageNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
|
||||
fn estimate_usd_cents(image_batch_count: u16) -> u64 {
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::FluxPro11Ultra,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: None,
|
||||
resolution: None,
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs()
|
||||
.cost_in_usd_cents
|
||||
.expect("cost_in_usd_cents should be present")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_usd_cents() {
|
||||
// $0.06/image = 6 cents each
|
||||
assert_eq!(estimate_usd_cents(1), 6);
|
||||
assert_eq!(estimate_usd_cents(2), 12);
|
||||
assert_eq!(estimate_usd_cents(3), 18);
|
||||
assert_eq!(estimate_usd_cents(4), 24);
|
||||
}
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
use artcraft_api_defs::generate::image::multi_function::gpt_image_1p5_multi_function_image_gen::{
|
||||
GptImage1p5MultiFunctionImageGenNumImages, GptImage1p5MultiFunctionImageGenQuality,
|
||||
GptImage1p5MultiFunctionImageGenSize,
|
||||
};
|
||||
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_gpt_image_1p5::PlanArtcraftGptImage1p5;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_gpt_image_1p5(
|
||||
plan: &PlanArtcraftGptImage1p5<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing varies by quality and image size. 1 credit = 1 USD cent.
|
||||
// Low: $0.01/image (any size)
|
||||
// Medium: $0.03/image (square/unset), $0.05/image (wide or tall)
|
||||
// High: $0.13/image (square/unset), $0.20/image (wide or tall)
|
||||
//
|
||||
// From Fal (text to image) -
|
||||
//
|
||||
// Your request will cost different amounts based on the number of images, quality, and size.
|
||||
//
|
||||
// You will be charged $0.005 per 1,000 input text tokens. One word is roughly 4 tokens.
|
||||
// You will be charged $0.010 per 1,000 output text tokens. The model will consume tokens reasoning about your prompt based on it's complexity.
|
||||
// For low quality, you will be charged $0.009 for 1024x1024 or $0.013 for any other size per image.
|
||||
// For medium quality, you will be charged $0.034 for 1024x1024, $0.051 for 1024x1536 and $0.050 for 1536x1024 per image.
|
||||
// For high quality, you will be charged $0.133 for 1024x1024, $0.200 for 1024x1536 or $0.199 for 1536x1024 per image.
|
||||
//
|
||||
// From Fal (image to image) -
|
||||
//
|
||||
// Your request will cost different amounts based on the number of images, quality, and size.
|
||||
//
|
||||
// You will be charged $0.005 per 1,000 input text tokens. One word is roughly 4 tokens.
|
||||
// You will be charged $0.008 per 1,000 input image tokens. One 1024x1024 image is roughly 135 tokens in low fidelity mode, or 3,050 tokens in high fidelity mode.
|
||||
// You will be charged $0.010 per 1,000 output text tokens. The model will consume tokens reasoning about your prompt based on it's complexity.
|
||||
// For low quality, you will be charged $0.009 for 1024x1024 or $0.013 for any other size per image.
|
||||
// For medium quality, you will be charged $0.034 for 1024x1024, $0.051 for 1024x1536 and $0.050 for 1536x1024 per image.
|
||||
// For high quality, you will be charged $0.133 for 1024x1024, $0.200 for 1024x1536 or $0.199 for 1536x1024 per image.
|
||||
//
|
||||
let cost_per_image: u64 = match plan.quality {
|
||||
GptImage1p5MultiFunctionImageGenQuality::Low => 1,
|
||||
GptImage1p5MultiFunctionImageGenQuality::Medium => match plan.image_size {
|
||||
Some(GptImage1p5MultiFunctionImageGenSize::Square) | None => 3,
|
||||
Some(GptImage1p5MultiFunctionImageGenSize::Wide) | Some(GptImage1p5MultiFunctionImageGenSize::Tall) => 5,
|
||||
},
|
||||
GptImage1p5MultiFunctionImageGenQuality::High => match plan.image_size {
|
||||
Some(GptImage1p5MultiFunctionImageGenSize::Square) | None => 13,
|
||||
Some(GptImage1p5MultiFunctionImageGenSize::Wide) | Some(GptImage1p5MultiFunctionImageGenSize::Tall) => 20,
|
||||
},
|
||||
};
|
||||
|
||||
let num_images: u64 = match plan.num_images {
|
||||
GptImage1p5MultiFunctionImageGenNumImages::One => 1,
|
||||
GptImage1p5MultiFunctionImageGenNumImages::Two => 2,
|
||||
GptImage1p5MultiFunctionImageGenNumImages::Three => 3,
|
||||
GptImage1p5MultiFunctionImageGenNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_aspect_ratio::CommonAspectRatio;
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
|
||||
fn estimate_usd_cents(image_batch_count: u16, aspect_ratio: Option<CommonAspectRatio>) -> u64 {
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::GptImage1p5,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: None,
|
||||
resolution: None,
|
||||
aspect_ratio,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs()
|
||||
.cost_in_usd_cents
|
||||
.expect("cost_in_usd_cents should be present")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_medium_square() {
|
||||
// Default quality (Medium) + square/unset size = 3 cents each
|
||||
assert_eq!(estimate_usd_cents(1, None), 3);
|
||||
assert_eq!(estimate_usd_cents(1, Some(CommonAspectRatio::Square)), 3);
|
||||
assert_eq!(estimate_usd_cents(2, Some(CommonAspectRatio::Square)), 6);
|
||||
assert_eq!(estimate_usd_cents(3, Some(CommonAspectRatio::Square)), 9);
|
||||
assert_eq!(estimate_usd_cents(4, Some(CommonAspectRatio::Square)), 12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_medium_wide() {
|
||||
// Medium + wide = 5 cents each
|
||||
assert_eq!(estimate_usd_cents(1, Some(CommonAspectRatio::WideSixteenByNine)), 5);
|
||||
assert_eq!(estimate_usd_cents(4, Some(CommonAspectRatio::WideSixteenByNine)), 20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_medium_tall() {
|
||||
// Medium + tall = 5 cents each
|
||||
assert_eq!(estimate_usd_cents(1, Some(CommonAspectRatio::TallNineBySixteen)), 5);
|
||||
assert_eq!(estimate_usd_cents(4, Some(CommonAspectRatio::TallNineBySixteen)), 20);
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
use artcraft_api_defs::generate::image::multi_function::nano_banana_multi_function_image_gen::NanoBananaMultiFunctionImageGenNumImages;
|
||||
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_nano_banana::PlanArtcraftNanaBanana;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_nano_banana(
|
||||
plan: &PlanArtcraftNanaBanana<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.04/image (4 cents). 1 credit = 1 USD cent.
|
||||
let cost_per_image: u64 = 4;
|
||||
|
||||
let num_images: u64 = match plan.num_images {
|
||||
NanoBananaMultiFunctionImageGenNumImages::One => 1,
|
||||
NanoBananaMultiFunctionImageGenNumImages::Two => 2,
|
||||
NanoBananaMultiFunctionImageGenNumImages::Three => 3,
|
||||
NanoBananaMultiFunctionImageGenNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
|
||||
fn estimate_usd_cents(image_batch_count: u16) -> u64 {
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::NanaBanana,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: None,
|
||||
resolution: None,
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs()
|
||||
.cost_in_usd_cents
|
||||
.expect("cost_in_usd_cents should be present")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_usd_cents() {
|
||||
// $0.04/image = 4 cents each
|
||||
assert_eq!(estimate_usd_cents(1), 4);
|
||||
assert_eq!(estimate_usd_cents(2), 8);
|
||||
assert_eq!(estimate_usd_cents(3), 12);
|
||||
assert_eq!(estimate_usd_cents(4), 16);
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
use artcraft_api_defs::generate::image::multi_function::nano_banana_2_multi_function_image_gen::{
|
||||
NanaBanana2MultiFunctionImageGenImageResolution, NanaBanana2MultiFunctionImageGenNumImages,
|
||||
};
|
||||
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_nano_banana_2::PlanArtcraftNanaBanana2;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_nano_banana_2(
|
||||
plan: &PlanArtcraftNanaBanana2<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.08/image at 0.5K, $0.15/image at 1K or 2K, $0.30/image at 4K.
|
||||
// (Stored as USD cents.)
|
||||
let cost_per_image: u64 = match plan.resolution {
|
||||
Some(NanaBanana2MultiFunctionImageGenImageResolution::HalfK) => 8,
|
||||
Some(NanaBanana2MultiFunctionImageGenImageResolution::FourK) => 30,
|
||||
_ => 15, // OneK, TwoK, or None (default 1K)
|
||||
};
|
||||
|
||||
let num_images: u64 = match plan.num_images {
|
||||
NanaBanana2MultiFunctionImageGenNumImages::One => 1,
|
||||
NanaBanana2MultiFunctionImageGenNumImages::Two => 2,
|
||||
NanaBanana2MultiFunctionImageGenNumImages::Three => 3,
|
||||
NanaBanana2MultiFunctionImageGenNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::common_resolution::CommonResolution;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
|
||||
fn estimate_usd_cents(resolution: Option<CommonResolution>, image_batch_count: u16) -> u64 {
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::NanaBanana2,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: None,
|
||||
resolution,
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs()
|
||||
.cost_in_usd_cents
|
||||
.expect("cost_in_usd_cents should be present")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_usd_cents() {
|
||||
// 1K/2K: $0.15/image = 15 cents
|
||||
assert_eq!(estimate_usd_cents(None, 1), 15);
|
||||
assert_eq!(estimate_usd_cents(Some(CommonResolution::OneK), 1), 15);
|
||||
assert_eq!(estimate_usd_cents(Some(CommonResolution::TwoK), 1), 15);
|
||||
assert_eq!(estimate_usd_cents(Some(CommonResolution::OneK), 2), 30);
|
||||
assert_eq!(estimate_usd_cents(Some(CommonResolution::OneK), 4), 60);
|
||||
|
||||
// 4K: $0.30/image = 30 cents
|
||||
assert_eq!(estimate_usd_cents(Some(CommonResolution::FourK), 1), 30);
|
||||
assert_eq!(estimate_usd_cents(Some(CommonResolution::FourK), 2), 60);
|
||||
}
|
||||
}
|
||||
+4
@@ -52,7 +52,11 @@ mod tests {
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
use artcraft_api_defs::generate::image::angle::qwen_edit_2511_edit_image_angle::QwenEdit2511EditImageAngleNumImages;
|
||||
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_qwen_edit_2511_angles::PlanArtcraftQwenEdit2511Angles;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_qwen_edit_2511_angles(
|
||||
plan: &PlanArtcraftQwenEdit2511Angles<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.04/image (4 cents). 1 credit = 1 USD cent.
|
||||
let cost_per_image: u64 = 4;
|
||||
|
||||
let num_images: u64 = match plan.num_images {
|
||||
QwenEdit2511EditImageAngleNumImages::One => 1,
|
||||
QwenEdit2511EditImageAngleNumImages::Two => 2,
|
||||
QwenEdit2511EditImageAngleNumImages::Three => 3,
|
||||
QwenEdit2511EditImageAngleNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::image_list_ref::ImageListRef;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
|
||||
fn estimate_usd_cents(image_batch_count: u16) -> u64 {
|
||||
let tokens = vec![MediaFileToken::new_from_str("test_token")];
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::QwenEdit2511Angles,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: Some(ImageListRef::MediaFileTokens(&tokens)),
|
||||
resolution: None,
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs()
|
||||
.cost_in_usd_cents
|
||||
.expect("cost_in_usd_cents should be present")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_usd_cents() {
|
||||
// $0.04/image = 4 cents each
|
||||
assert_eq!(estimate_usd_cents(1), 4);
|
||||
assert_eq!(estimate_usd_cents(2), 8);
|
||||
assert_eq!(estimate_usd_cents(3), 12);
|
||||
assert_eq!(estimate_usd_cents(4), 16);
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
use artcraft_api_defs::generate::image::multi_function::bytedance_seedream_v4_multi_function_image_gen::BytedanceSeedreamV4MultiFunctionImageGenNumImages;
|
||||
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_seedream_4::PlanArtcraftSeedream4;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_seedream_4(
|
||||
plan: &PlanArtcraftSeedream4<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.03/image (3 cents). 1 credit = 1 USD cent.
|
||||
let cost_per_image: u64 = 3;
|
||||
|
||||
let num_images: u64 = match plan.num_images {
|
||||
BytedanceSeedreamV4MultiFunctionImageGenNumImages::One => 1,
|
||||
BytedanceSeedreamV4MultiFunctionImageGenNumImages::Two => 2,
|
||||
BytedanceSeedreamV4MultiFunctionImageGenNumImages::Three => 3,
|
||||
BytedanceSeedreamV4MultiFunctionImageGenNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
|
||||
fn estimate_usd_cents(image_batch_count: u16) -> u64 {
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::Seedream4,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: None,
|
||||
resolution: None,
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs()
|
||||
.cost_in_usd_cents
|
||||
.expect("cost_in_usd_cents should be present")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_usd_cents() {
|
||||
// $0.03/image = 3 cents each
|
||||
assert_eq!(estimate_usd_cents(1), 3);
|
||||
assert_eq!(estimate_usd_cents(2), 6);
|
||||
assert_eq!(estimate_usd_cents(3), 9);
|
||||
assert_eq!(estimate_usd_cents(4), 12);
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
use artcraft_api_defs::generate::image::multi_function::bytedance_seedream_v4p5_multi_function_image_gen::BytedanceSeedreamV4p5MultiFunctionImageGenNumImages;
|
||||
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_seedream_4p5::PlanArtcraftSeedream4p5;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_seedream_4p5(
|
||||
plan: &PlanArtcraftSeedream4p5<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.04/image (4 cents). 1 credit = 1 USD cent.
|
||||
let cost_per_image: u64 = 4;
|
||||
|
||||
let num_images: u64 = match plan.num_images {
|
||||
BytedanceSeedreamV4p5MultiFunctionImageGenNumImages::One => 1,
|
||||
BytedanceSeedreamV4p5MultiFunctionImageGenNumImages::Two => 2,
|
||||
BytedanceSeedreamV4p5MultiFunctionImageGenNumImages::Three => 3,
|
||||
BytedanceSeedreamV4p5MultiFunctionImageGenNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
|
||||
fn estimate_usd_cents(image_batch_count: u16) -> u64 {
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::Seedream4p5,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: None,
|
||||
resolution: None,
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs()
|
||||
.cost_in_usd_cents
|
||||
.expect("cost_in_usd_cents should be present")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_usd_cents() {
|
||||
// $0.04/image = 4 cents each
|
||||
assert_eq!(estimate_usd_cents(1), 4);
|
||||
assert_eq!(estimate_usd_cents(2), 8);
|
||||
assert_eq!(estimate_usd_cents(3), 12);
|
||||
assert_eq!(estimate_usd_cents(4), 16);
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
use artcraft_api_defs::generate::image::multi_function::bytedance_seedream_5_lite_multi_function_image_gen::BytedanceSeedream5LiteMultiFunctionImageGenNumImages;
|
||||
|
||||
use crate::generate::generate_image::image_generation_cost_estimate::ImageGenerationCostEstimate;
|
||||
use crate::generate::generate_image::plan::artcraft::plan_generate_image_artcraft_seedream_5_lite::PlanArtcraftSeedream5Lite;
|
||||
|
||||
pub(crate) fn estimate_image_cost_artcraft_seedream_5_lite(
|
||||
plan: &PlanArtcraftSeedream5Lite<'_>,
|
||||
) -> ImageGenerationCostEstimate {
|
||||
// Pricing: $0.04/image (4 cents). 1 credit = 1 USD cent.
|
||||
let cost_per_image: u64 = 4;
|
||||
|
||||
let num_images: u64 = match plan.num_images {
|
||||
BytedanceSeedream5LiteMultiFunctionImageGenNumImages::One => 1,
|
||||
BytedanceSeedream5LiteMultiFunctionImageGenNumImages::Two => 2,
|
||||
BytedanceSeedream5LiteMultiFunctionImageGenNumImages::Three => 3,
|
||||
BytedanceSeedream5LiteMultiFunctionImageGenNumImages::Four => 4,
|
||||
};
|
||||
|
||||
let cost_in_usd_cents = cost_per_image * num_images;
|
||||
|
||||
ImageGenerationCostEstimate {
|
||||
cost_in_credits: Some(cost_in_usd_cents),
|
||||
cost_in_usd_cents: Some(cost_in_usd_cents),
|
||||
is_free: false,
|
||||
is_unlimited: false,
|
||||
is_rate_limited: false,
|
||||
has_watermark: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::api::common_image_model::CommonImageModel;
|
||||
use crate::api::provider::Provider;
|
||||
use crate::client::request_mismatch_mitigation_strategy::RequestMismatchMitigationStrategy;
|
||||
use crate::generate::generate_image::generate_image_request::GenerateImageRequest;
|
||||
|
||||
fn estimate_usd_cents(image_batch_count: u16) -> u64 {
|
||||
let request = GenerateImageRequest {
|
||||
model: CommonImageModel::Seedream5Lite,
|
||||
provider: Provider::Artcraft,
|
||||
prompt: None,
|
||||
image_inputs: None,
|
||||
resolution: None,
|
||||
aspect_ratio: None,
|
||||
image_batch_count: Some(image_batch_count),
|
||||
request_mismatch_mitigation_strategy: RequestMismatchMitigationStrategy::ErrorOut,
|
||||
generation_mode_mismatch_strategy: None,
|
||||
idempotency_token: None,
|
||||
horizontal_angle: None,
|
||||
vertical_angle: None,
|
||||
zoom: None,
|
||||
};
|
||||
request.build()
|
||||
.expect("build should succeed")
|
||||
.estimate_costs()
|
||||
.cost_in_usd_cents
|
||||
.expect("cost_in_usd_cents should be present")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_estimate_cost_usd_cents() {
|
||||
// $0.04/image = 4 cents each
|
||||
assert_eq!(estimate_usd_cents(1), 4);
|
||||
assert_eq!(estimate_usd_cents(2), 8);
|
||||
assert_eq!(estimate_usd_cents(3), 12);
|
||||
assert_eq!(estimate_usd_cents(4), 16);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user