Compare commits

..
Author SHA1 Message Date
Brandon Thomas 4c692d863e generation count update 2026-01-02 03:14:33 -05:00
Brandon Thomas 4b53badf3b generation count behavior 2026-01-02 02:46:41 -05:00
Brandon Thomas 586e6f10d0 generation count options 2026-01-02 02:27:37 -05:00
Brandon Thomas 7a04b131f7 rename nx module editor3d -> artcraft (#951) 2026-01-02 00:45:22 -05:00
Brandon Thomas 427269feec sort model selectors, default models (#950) 2026-01-01 22:48:44 -05:00
Brandon Thomas 2e2c433ffe flux and seedance aspect ratio options (#949) 2026-01-01 20:29:49 -05:00
Brandon Thomas c8228c5073 more model controls (#948)
still need to roll this out to everything, but this lands standardized
aspect ratio for several models
2025-12-31 07:03:34 -05:00
Brandon Thomas f89ce374cd animated discord icon 2025-12-31 03:31:08 -05:00
Brandon Thomas affcbac10f artcraft spin animation for discord 2025-12-31 03:26:08 -05:00
Brandon Thomas cbf91709dc nano banana frontend options, unified nano banana endpoint, new aspect ratio controls (#947) 2025-12-31 03:21:25 -05:00
BFlat eea31d3f94 billing blocker modal update (#946)
billing blocker update
2025-12-30 11:29:21 +07:00
Brandon Thomas f8f3434d70 random discord app icon 2025-12-29 22:06:02 -05:00
Brandon Thomas c6f3fd13b8 add assets for discord that will be deployed with website 2025-12-29 21:41:05 -05:00
Brandon Thomas fd8f9d037f fix stupid bug 2025-12-29 14:33:05 -05:00
bflatastic 9fa4080851 reverse capability for pre-ES2023 2025-12-29 23:25:23 +07:00
Brandon Thomas 73b16274f8 remove spurious billing tests 2025-12-29 03:49:29 -05:00
Brandon Thomas 835c9ef6b0 begin charging for video generations (#945) 2025-12-29 03:39:10 -05:00
Brandon Thomas 11bf5949fe select provider in frontend (#944) 2025-12-28 09:30:41 -05:00
Brandon Thomas 5415109a35 tauri command cleanup (#943)
this will aid in adding providers
2025-12-28 05:20:25 -05:00
bflatastic cb8c3b426f model selector to show provider submenu only when there's more than one, and commented out provider priority from settings modal 2025-12-28 11:31:10 +07:00
bflatastic 25ac4213af task queue buttons 2025-12-24 23:12:07 +07:00
bflatastic 2a316f6cc7 grid fixes, toast z-index on 3d world page, smaller onboarding helper and moved to above promptbox 2025-12-24 22:54:11 +07:00
bflatastic 2a1ae24917 spz file flip in editor, 3d viewer above grid and no event clickthrough 2025-12-23 00:37:33 +07:00
BFlat 68ff2b484b scrolling model list update (#942) 2025-12-22 16:59:53 +07:00
Brandon Thomas 19258c257c kling 2.5/2.6, veo3.1, sora2 in tauri + javascript (#941) 2025-12-22 04:46:56 -05:00
Brandon Thomas 4cd3bd8095 more video models (fal, server, client) - kling2.6/2.6, veo3.1, sora2 (#940) 2025-12-22 00:36:31 -05:00
Brandon Thomas e7dc0abb36 fix required rust never type behavior (#939) 2025-12-21 20:09:59 -05:00
bflatastic a36fe72832 lightbox 3d world button, nano banana name mappings with icon and fixed column width 2025-12-21 19:26:40 +07:00
bflatastic 4eeb915bef duplicated topbar on miniapps index page fix 2025-12-21 18:51:09 +07:00
bflatastic 19079ab7ec worldlabs icon and mapping 2025-12-21 18:38:34 +07:00
BFlat 9ffcfe83c2 bug fix: ImageTo3DWorldStore to use GaussianGenerationEvent (#938) 2025-12-21 18:28:16 +07:00
Brandon Thomas 3404935720 tauri hooks for gpt-image-1.5 and seedream4/4.5 (#937) 2025-12-20 16:06:25 -05:00
Brandon Thomas b490b92833 more models (again) - partial impl of gpt-image-1.5, seedream4/.5 (#936) 2025-12-20 14:12:24 -05:00
Brandon Thomas f151837c2b website links 2025-12-19 17:07:20 -05:00
Brandon Thomas 86a6d16441 refresh access token (#935) 2025-12-19 06:47:22 -05:00
Brandon Thomas b9397fb809 worldlabs improvements - login modal, refresh, etc. (#934) 2025-12-19 06:41:24 -05:00
Brandon Thomas 5688d8cef7 worldlabs tauri (#933)
not finished: need refresh tokens and thumbnails
2025-12-18 22:50:36 -05:00
BFlat 6815040cb1 3d world page and separate store (#932) 2025-12-18 00:29:25 +07:00
Brandon Thomas 754a4da019 worldlabs client library (#931) 2025-12-17 00:21:56 -05:00
bflatastic 3a600fcb9f remove background ui styling center update 2025-12-16 23:15:27 +07:00
Tanish Manku 510589b758 Splat persistence and preview support (#930)
Branch name is misleading as it was originally meant to upload splats to
the endpoint. It results in HTTP400 as of now.
2025-12-15 23:46:48 -08:00
BFlat 7ee5a6aa9a Feature/remove bg mini app (#929)
- remove background mini app
- button in lightbox to remove background leads to mini app as well
2025-12-16 05:45:35 +07:00
Tanish Manku f5cd65be9c Temporarily give splats meshes a name (#928) 2025-12-10 22:29:01 -08:00
Tanish Manku fba1a65e95 Fix bone controls not appearing since 3JS update (#927) 2025-12-10 22:14:26 -08:00
BFlat a1d08460db nano banana pro updates and fixes (#926)
- working red marker
- aspect ratio and resolution buttons
- styling fixes, canvas centering/padding
- nano banana not stuck at 1 image per generation anymore
- context images working for image edit
2025-12-11 01:14:04 +07:00
Brandon Thomas ba538142e4 store more metadata on spz uploads (#925) 2025-12-09 02:15:40 -05:00
Brandon Thomas 99fd390bc5 spz file uploads (#924) 2025-12-09 00:33:14 -05:00
bflatastic cd283bf8de vite config settings modal 2025-12-08 13:17:19 +07:00
Brandon Thomas 0c6021e95c nano banana pro in tauri (#923) 2025-12-06 04:50:30 -05:00
Brandon Thomas 859d295014 tailscale dev change, remove billing test on flux dev 2025-12-06 00:43:54 -05:00
Brandon Thomas e116df736f nano banana pro (#922) 2025-12-05 21:18:59 -05:00
Brandon Thomas 9bb4a78111 CSP fixes + nix per-frame logging 2025-12-05 11:22:32 -05:00
Brandon Thomas edb0330cec rebuild package-lock.json from scratch (#921) 2025-12-05 03:05:26 -05:00
Brandon Thomas 146f152732 fix js build files 2025-12-05 01:57:23 -05:00
Brandon Thomas 32b939a67e fix rust/grok bug, package.lock change 2025-12-04 23:19:33 -05:00
Tanish Manku 866a409ff1 Add basic local 3D splat support (SPZ only) (#920)
- Disabled Outline Pass
- Disabled SAO Pass
- Disabled Bloom Pass
- Disabled SMAA Pass

SAO and Outline passes are necessary to disable for adequate
performance. No idea why.
2025-12-04 16:05:54 -08:00
Brandon Thomas 92731d87ef Fal: more models (plumbing not yet done) (#919) 2025-12-04 16:21:55 -05:00
bflatastic f574d66897 remove midjourney text 2025-12-04 12:20:09 +07:00
Brandon Thomas 21a30bde2d update website installer links 2025-12-02 13:38:34 -05:00
BFlat 6a1eeaffb4 brush edit for nano banana and other refactor + bug fixes (#918)
edit product ui refactor:
- nano banana model now has marker and eraser
- marker color can be changed, all brush, marker and eraser can be size
adjusted separately
- flux ones have edit region and eraser (removed select since i dont
think thats neccessary)
- smooth fade between history image switches
2025-12-02 22:36:59 +07:00
Brandon Thomas 00065f120e More grok fixes for the xsid script, more semantic error messages (#917) 2025-12-01 17:43:50 -05:00
Brandon Thomas e30dc03466 grok retry (#916) 2025-12-01 12:58:58 -05:00
Brandon Thomas 029789ac78 grok aspect ratios (#915) 2025-12-01 00:15:24 -05:00
BFlat 7b5550c546 3d object generator page with interactive three js result view (#906)
- reusable 3d viewer component
2025-11-28 20:56:01 +07:00
Brandon Thomas 0f0bd4c907 repair grok (#914) 2025-11-27 02:20:51 -05:00
Brandon Thomas 63f77a4b11 preserve the URL of broken thumbnails in a data- attribute for debugging (#913) 2025-11-26 23:59:29 -05:00
Brandon Thomas 5ba6a3e226 rename field 2025-11-26 22:56:54 -05:00
bflatastic 7683fe34b7 default to only artcraft provider and add sora/chatgpt provider selection for GPT image 1 2025-11-27 00:39:30 +07:00
Brandon Thomas 1d41fa8174 turn on decorations on linux 2025-11-26 07:28:53 -05:00
Brandon Thomas 8fe15839b0 notify frontend of video and object events (#912) 2025-11-26 06:23:00 -05:00
Brandon Thomas 1eada337f9 plumb through "generate audio" (only veo supports this??) (#911) 2025-11-25 04:54:34 -05:00
Brandon Thomas 016f5107e0 frontend subscriber id on image-to-video (#910) 2025-11-25 03:42:51 -05:00
Brandon Thomas 224ce3f80b add "frontend_subscriber_id" to image-to-object (#909) 2025-11-24 23:33:49 -05:00
BFlat 73a6d0494b show sound toggle for kling models (#908) 2025-11-21 22:42:49 +07:00
Brandon Thomas 0a5f220a7d remove openssl / native-tls in favor of rustls -- this lets Artcraft run on Linux! (#907) 2025-11-20 22:46:05 -05:00
Brandon Thomas d852d24226 Script to build modules - see note about warning
Note: this should not be necessary. Nx/Vite should build all of this for
us. Something in our build configuration fails to do this, which causes
us to need to build these packages.
2025-11-20 16:59:42 -05:00
BFlat e7da946e2d 3d tool pages + double gallery stack bug fix for extractor page (#904)
new pages disabled for now and coming soon tag
2025-11-19 01:59:19 +07:00
BFlat ea80dab67b watermark removal tools ui (#902) 2025-11-17 23:41:34 +07:00
bflatastic 957bb7ff2f dont load videos as blobs 2025-11-13 13:26:27 +07:00
BFlat 2f41f345a2 video frame extractor app (#901)
- extract frames from video
- save frame
- turn into frame
2025-11-13 04:09:21 +07:00
BFlat 53225932fb apps index page (#900)
- top menu selector last icon hover
- standalone index page
2025-11-13 00:15:15 +07:00
BFlat 0c353f2a8c artcraft website media page cleanup/refactor and video fixed (#899)
- fixed the video not loading issue
- refactored the media page file so that it's cleaner
- added Grok icon
2025-11-05 20:12:13 +07:00
BFlat 6036be1e01 modal now goes to previous position or centers when restored from max… (#898)
…imization
2025-11-03 14:39:10 +07:00
BFlat 197e91d4c6 bug fix: turn into video button now only sets the video promptbox reference (#897) 2025-11-03 14:34:36 +07:00
BFlat 5ddd23a8ff gallery fixes for grok, video and provider icons (#896) 2025-11-03 14:15:50 +07:00
BFlat 31eb00cfa7 change text to image background (#895) 2025-11-03 13:51:02 +07:00
BFlat 7d6f262ffe provider icons in settings to invert color properly to current theme (#894) 2025-11-03 13:35:15 +07:00
Brandon Thomas 33162e4337 update web cors for artcraft website 2025-10-31 22:34:59 -04:00
Brandon Thomas 5afb1db285 fix legacy grok metadata 2025-10-31 22:26:34 -04:00
Brandon Thomas a511e0e0a4 grok images (#893) 2025-10-31 21:55:45 -04:00
Brandon Thomas 0598aadaa1 grok logout, settings panel info 2025-10-31 05:26:44 -04:00
Brandon Thomas 06c6ff4b36 persist user details to disk 2025-10-31 05:09:08 -04:00
Brandon Thomas 5bc759e511 notify frontend of Grok 429 2025-10-31 04:52:58 -04:00
Brandon Thomas 02eafa96cc error categorization 2025-10-31 04:19:41 -04:00
Brandon Thomas 706bdb8d83 grok video enums 2025-10-31 03:36:07 -04:00
Brandon Thomas 57534c7a77 artcraft grok video integration (#892) 2025-10-31 02:59:10 -04:00
bflatastic 2228a01466 added grok icon 2025-10-31 11:57:46 +07:00
Brandon Thomas 262d931c3d grok client (not yet integrated) (#891)
- image gen works
- video gen works
- login flow works
2025-10-30 17:11:32 -04:00
BFlat a7826f8be3 ui model selector update with provider selection (#890)
sub menu inside model selector

<img width="646" height="705" alt="image"
src="https://github.com/user-attachments/assets/f946c8ea-d48d-4d0f-8dd6-95772b0161c1"
/>
2025-10-29 15:33:47 +07:00
BFlat dc0e59b8ce Link sharing from lightbox modal + website media page view (#889) 2025-10-27 11:12:06 +07:00
BFlat e1f3458c54 text to image results now pass lightbox media id and modal resize bug fix (#888)
- clicking from text to image page results now shows action buttons in
lightbox
- resizing modal from sides or corners that are not bottom or right now
doesn't move the modal once it reaches min size
- limited the min size of the lightbox modal so that the layout doesnt
break
2025-10-22 07:36:48 +07:00
BFlat e385b3c6c3 bug fixed: can't name a scene with "B" in the name because it brings … (#887)
…up the asset modal
2025-10-21 21:34:53 +07:00
BFlat dbedb25930 handle thumbnails error (#883) 2025-10-20 14:00:29 +07:00
BFlat 952d1e936c lightbox carousel for batch images (#882)
- task queue item opens in batch images carousel if there;s batch token
returned
2025-10-20 11:54:22 +07:00
Tanish Manku 88799a482d Refresh outliner items on scene load (#881) 2025-10-19 17:21:12 -07:00
Brandon Thomas 851aba7e06 midjourney task completion data 2025-10-16 20:29:09 -04:00
Brandon Thomas 8ff9323ae6 add metadata to sora uploads 2025-10-16 20:14:16 -04:00
Brandon Thomas 50b085d450 minor cleanup 2025-10-16 19:17:04 -04:00
Brandon Thomas 1b70ee7394 fixup sora sentinel tokens (#879) 2025-10-16 19:09:52 -04:00
Brandon Thomas 1c3a176705 fix docs compile errors 2025-10-15 21:18:46 -04:00
bflatastic 70c305f78d promptbox clickthrough fix 3d 2025-10-15 22:49:47 +07:00
Brandon Thomas 1c3178d073 task queue api - thumbnails, tokens, etc. (#878) 2025-10-15 02:51:08 -04:00
Tanish Manku 1243e755fe Add reset ability to 2D (#874) 2025-10-14 15:57:03 -07:00
BFlat d551e48a23 sound toggle for veo models (#877)
- veo models if selected now has a sound toggle button which defaults to
ON/true (still needs backend link)
2025-10-14 23:30:26 +07:00
BFlat 5cb608fad6 lightbox updates (#876)
- colors will match selected theme now
- buttons relayout and added "turn into video" button for images that
will take you to the Image to Video page
- reference image matches imapge prompt row component now - opens full
preview in a separate resizable modal
2025-10-14 23:15:32 +07:00
BFlat d5ae28ca4c task queue dropdown and modal (#852)
task queue implementation
2025-10-14 00:11:40 +07:00
Brandon Thomas 8313558795 debugging for inference-job loop 2025-10-13 11:03:50 -04:00
Brandon Thomas 95173e032f Remove FAL from desktop app (for now) - build speed issue (#875)
Fal is causing really inflated build slowdowns on account of the library
using so much Serde/proc macros. We really need to rethink FAL client
workings before adding it.
2025-10-10 19:31:44 -04:00
Brandon Thomas b0f6551623 fix job builds (#873) 2025-10-10 19:00:22 -04:00
Brandon Thomas 8f2a03e21e nx fix vite build (#872) 2025-10-09 23:53:34 -04:00
Brandon Thomas 5c3760f9ec config+script to debug production builds (#871) 2025-10-09 05:07:27 -04:00
Brandon Thomas d6c1eaae5d fix inpainting thumbnails (#870) 2025-10-09 04:21:03 -04:00
Brandon Thomas d6abe9fb88 rename Nano Banana, change metadata, change predicates 2025-10-08 23:00:09 -04:00
Brandon Thomas 1e758b1b6c rename model to "Nano Banana" 2025-10-08 22:44:11 -04:00
Brandon Thomas cd40edb5f9 forgot to commit these changes 2025-10-08 21:15:31 -04:00
Brandon Thomas 3838cc3f21 artcraft task queue 2 (#869) 2025-10-08 21:14:16 -04:00
bflatastic 0fec772d9a page title for landing 2025-10-06 21:43:03 +07:00
bflatastic 1afe2ac26f footer link fixes 2025-10-06 15:30:59 +07:00
bflatastic 5eef6c0161 navbar, faq, tutorial page link fixes 2025-10-06 15:23:03 +07:00
bflatastic 6c6f7f054d update 2 faq 3d 2025-10-06 15:06:14 +07:00
bflatastic ba3d46607b 3d editor faq post update 2025-10-06 15:04:15 +07:00
BFlat 12bf504d6f faq and tutorials update to use markdown, footer updates, landing vid… (#868)
…eo layout shift fix
2025-10-06 14:57:33 +07:00
Brandon Thomas 026c2bf827 update version on website 2025-10-04 18:39:37 -04:00
Brandon Thomas d20854f75d remove service selector (#867) 2025-10-04 16:28:48 -04:00
Brandon Thomas 7c9396aa65 fix broken builds 2025-10-04 15:58:37 -04:00
Brandon Thomas 90810231da fix release script 2025-10-04 12:50:14 -04:00
Brandon Thomas e9613c6b4a boringssl got into web which conflicts with openssl on linux :( (#866) 2025-10-04 12:45:36 -04:00
Brandon Thomas cb2eb39183 bump toolchain 2025-10-04 02:13:44 -04:00
Brandon Thomas 7a100bd461 sora implementation (#865) 2025-10-04 01:58:31 -04:00
bflatastic 10c35381fa landing page text change 2025-10-02 22:53:18 +07:00
bflatastic 24c8353482 popover hover bug fix to prevent “first stays stuck open” when moving to the next 2025-10-02 14:10:23 +07:00
bflatastic eb0db3d67d first class provider selector next to model selector 2025-10-02 14:06:42 +07:00
Brandon Thomas 2d44b92bfc cleanup sora client (#863) 2025-10-02 00:27:16 -04:00
Brandon Thomas 8c36a7f98a refactor client package organization 2025-10-01 17:56:04 -04:00
Brandon Thomas a174730bf0 fix delete by calling tauri instead (#861) 2025-09-30 04:00:57 -04:00
Brandon Thomas 96ffeadbe0 github link (#860) 2025-09-29 23:10:00 -04:00
bflatastic bd93cd4f1f plan text update 2 2025-09-29 23:09:52 +07:00
bflatastic 39ad16e856 plans text change 2025-09-29 23:05:58 +07:00
bflatastic 64d589521a netlify redirects for tutorial page 2025-09-29 22:53:29 +07:00
BFlat 8c0529be0b tutorial modal for app and tutorial page for website (#859)
shared component for tutorials

app:
- tutorial modal accessible from any page on the app on the bottom right
- plays right in the modal through youtube embed
- it remembers the play progress and saves it in the zustand state so in
that current session if modal is opened again, it will continue where
the user left off

website:
- navbar updates (home and tutorials link)
- tutorial page with category buttons to filter by product or show all
- plays through youtube embed on website page
2025-09-29 16:19:59 +07:00
Brandon Thomas f198d5e90c bump version of binaries on website 2025-09-28 02:01:26 -04:00
BFlat a7f4a6eda4 dots dropdown on gallery item to edit image or delete (#858)
- each gallery item now has the three dots button on hover, clicking
shows a dropdown to edit image or delete
- reduced page size to 100 due to lag
2025-09-28 09:10:37 +07:00
Brandon Thomas 450c73a29d remove gpu loading error (#857) 2025-09-27 18:28:02 -04:00
2271 changed files with 72750 additions and 15708 deletions
+1
View File
@@ -1,6 +1,7 @@
SERVER_ENVIRONMENT=development
DATABASE_URL=mysql://storyteller:password@localhost/storyteller
#DATABASE_URL=sqlite:/tmp/tasks.sqlite
#DATABASE_URL=mysql://root:root@localhost/storyteller
#DATABASE_URL=mysql://root@localhost/storyteller
+2 -2
View File
@@ -200,10 +200,10 @@ jobs:
# Use npx to ensure we use the local nx version
echo "Building with npx nx..."
npx nx run editor3d:build
npx nx run artcraft:build
echo "Checking build output..."
ls -la apps/editor3d/dist/ | head -10
ls -la apps/artcraft/dist/ | head -10
# Update Tauri config to skip the build (since we already built)
cd ${{ github.workspace }}/crates/desktop/artcraft
@@ -75,10 +75,10 @@ jobs:
# Use npx to ensure we use the local nx version
echo "Building with npx nx..."
npx nx run editor3d:build
npx nx run artcraft:build
echo "Checking build output..."
dir apps/editor3d/dist/ | Select-Object -First 10
dir apps/artcraft/dist/ | Select-Object -First 10
# Update Tauri config to skip the build (since we already built)
cd ${{ github.workspace }}/crates/desktop/artcraft
@@ -104,4 +104,4 @@ jobs:
releaseBody: "Windows build - See the assets to download this version and install."
releaseDraft: true
prerelease: false
args: ${{ matrix.args }}
args: ${{ matrix.args }}
+3
View File
@@ -45,6 +45,9 @@ crates/lib/sqlite_queries/target/
# Javascript build directories
node_modules/
# Frontend build outputs
frontend/apps/artcraft/bundle-report.html
# Vim noise
*.swo
*.swp
@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "\n UPDATE tasks\n SET is_dismissed_by_user = 1\n WHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "13d435d8f681b73e4080748dcef0579e246e41049af67e1bd79ffc06aa6ba974"
}
@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "\n UPDATE tasks\n SET\n task_status = ?,\n on_complete_batch_token = ?,\n on_complete_primary_media_file_token = ?,\n on_complete_primary_media_file_class = ?,\n on_complete_primary_media_file_cdn_url = ?,\n on_complete_primary_media_file_thumbnail_url_template = ?\n WHERE\n provider = ?\n AND provider_job_id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 8
},
"nullable": []
},
"hash": "1e3758851fc8451670f86a9432009b73bdb81de4a08dcaa96a86afb5f9be7a68"
}
@@ -0,0 +1,68 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id,\n task_status,\n task_type,\n model_type,\n provider,\n provider_job_id,\n frontend_caller,\n frontend_subscriber_id,\n frontend_subscriber_payload\n FROM tasks\n WHERE\n provider = ?\n AND provider_job_id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "task_status",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "task_type",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "model_type",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "provider",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "provider_job_id",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "frontend_caller",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "frontend_subscriber_id",
"ordinal": 7,
"type_info": "Text"
},
{
"name": "frontend_subscriber_payload",
"ordinal": 8,
"type_info": "Text"
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
false,
false,
true,
true,
true,
true,
true,
true
]
},
"hash": "38ff2df237b16f077865711dd81261de1b5fa05a9787679ce9ccd4ac576b1069"
}
@@ -0,0 +1,116 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id,\n task_status,\n task_type,\n model_type,\n provider,\n provider_job_id,\n frontend_caller,\n frontend_subscriber_id,\n frontend_subscriber_payload,\n on_complete_primary_media_file_token,\n on_complete_primary_media_file_class,\n on_complete_batch_token,\n on_complete_primary_media_file_cdn_url,\n on_complete_primary_media_file_thumbnail_url_template,\n created_at as \"created_at: DateTime<Utc>\",\n updated_at as \"updated_at: DateTime<Utc>\",\n completed_at as \"completed_at: DateTime<Utc>\"\n FROM tasks\n WHERE is_dismissed_by_user == 0\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "task_status",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "task_type",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "model_type",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "provider",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "provider_job_id",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "frontend_caller",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "frontend_subscriber_id",
"ordinal": 7,
"type_info": "Text"
},
{
"name": "frontend_subscriber_payload",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "on_complete_primary_media_file_token",
"ordinal": 9,
"type_info": "Text"
},
{
"name": "on_complete_primary_media_file_class",
"ordinal": 10,
"type_info": "Text"
},
{
"name": "on_complete_batch_token",
"ordinal": 11,
"type_info": "Text"
},
{
"name": "on_complete_primary_media_file_cdn_url",
"ordinal": 12,
"type_info": "Text"
},
{
"name": "on_complete_primary_media_file_thumbnail_url_template",
"ordinal": 13,
"type_info": "Text"
},
{
"name": "created_at: DateTime<Utc>",
"ordinal": 14,
"type_info": "Int64"
},
{
"name": "updated_at: DateTime<Utc>",
"ordinal": 15,
"type_info": "Int64"
},
{
"name": "completed_at: DateTime<Utc>",
"ordinal": 16,
"type_info": "Int64"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
false,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
false,
false,
true
]
},
"hash": "47f94c127abc20683b25c257aed3c2190b9bd29eb829d61392f08e10fd986767"
}
@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "\n UPDATE tasks\n SET\n task_status = ?,\n on_complete_batch_token = ?,\n on_complete_primary_media_file_token = ?,\n on_complete_primary_media_file_class = ?,\n on_complete_primary_media_file_cdn_url = ?,\n on_complete_primary_media_file_thumbnail_url_template = ?\n WHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 7
},
"nullable": []
},
"hash": "50a2449b87abed7df3302a74ecd0e8ab87940077a247636680cb09b2fe488321"
}
Generated
+803 -411
View File
File diff suppressed because it is too large Load Diff
+34 -6
View File
@@ -6,17 +6,19 @@ resolver = "2"
members = [
# API clients for external services
# These might be custom implementations or wrappers over other client libraries.
"crates/api_clients/artcraft_api_defs", # TODO: api_clients/{artcraft}/{api_defs,client}
"crates/api_clients/artcraft/artcraft_api_defs", # TODO: api_clients/{artcraft}/{api_defs,client}
"crates/api_clients/artcraft/storyteller_client",
"crates/api_clients/cloud_storage",
"crates/api_clients/fal_client",
"crates/api_clients/google_drive_common",
"crates/api_clients/google_sign_in",
"crates/api_clients/grok_client",
"crates/api_clients/midjourney_client",
"crates/api_clients/openai_sora_client",
"crates/api_clients/openart_client",
"crates/api_clients/runwayml_client",
"crates/api_clients/storyteller_client",
"crates/api_clients/thumbnail_generator",
"crates/api_clients/world_labs_client",
# CLI tools for operations, etc.
"crates/cli/devenv/dev-database-seed",
@@ -43,6 +45,7 @@ members = [
"crates/lib/caching/memory_store",
"crates/lib/caching/redis_caching",
"crates/lib/cloudflare_errors",
"crates/lib/cloudflare_mitigation",
"crates/lib/concurrency",
"crates/lib/cookie_store",
"crates/lib/cookies",
@@ -65,6 +68,7 @@ members = [
"crates/lib/files/media",
"crates/lib/files/mimetypes",
"crates/lib/files/videos",
"crates/lib/http_headers",
"crates/lib/idempotency",
"crates/lib/image_algorithms",
"crates/lib/jobs_common",
@@ -84,6 +88,7 @@ members = [
"crates/lib/testing",
"crates/lib/tts_common",
"crates/lib/url_config",
"crates/lib/url_utils",
"crates/lib/user_input_common",
"crates/lib/web_scrapers",
#"crates/lib/api_clients/fakeyou_client",
@@ -181,10 +186,11 @@ workspace-build-acceleration = { path = "crates/workspace-build-acceleration" }
# Internal libs
# Setting paths here ensures we don't need to do so in every crate's Cargo.toml
# It makes refactoring much easier.
artcraft_api_defs = { path = "crates/api_clients/artcraft_api_defs" }
artcraft_api_defs = { path = "crates/api_clients/artcraft/artcraft_api_defs" }
build_metadata = { path = "crates/lib/build_metadata" }
cloud_storage = { path = "crates/api_clients/cloud_storage" }
cloudflare_errors = { path = "crates/lib/cloudflare_errors" }
cloudflare_mitigation = { path = "crates/lib/cloudflare_mitigation" }
component_traits = { path = "crates/service/plugins/component_traits" }
cookie_store = { path = "crates/lib/cookie_store" }
crockford = { path = "crates/lib/data/crockford" }
@@ -194,6 +200,8 @@ errors = { path = "crates/lib/errors" }
fal_client = { path = "crates/api_clients/fal_client" }
file_to_base64_url = { path = "crates/lib/files/file_to_base64_url" }
filesys = { path = "crates/lib/files/filesys" }
grok_client = { path = "crates/api_clients/grok_client" }
http_headers = { path = "crates/lib/http_headers" }
idempotency = { path = "crates/lib/idempotency" }
images = { path = "crates/lib/files/images" }
jwt_light = { path = "crates/lib/jwt_light" }
@@ -205,12 +213,14 @@ openai_sora_client = { path = "crates/api_clients/openai_sora_client" }
primitives = { path = "crates/lib/data/primitives" }
shared_service_components = { path = "crates/lib/shared_service_components" }
sqlite_tasks = { path = "crates/schema/database/sqlite_tasks" }
storyteller_client = { path = "crates/api_clients/storyteller_client" }
storyteller_client = { path = "crates/api_clients/artcraft/storyteller_client" }
subprocess_common = { path = "crates/lib/subprocess_common" }
test_data = { path = "crates/lib/test_data" }
testing = { path = "crates/lib/testing" }
tokens = { path = "crates/schema/public/tokens" }
url_utils = { path = "crates/lib/url_utils" }
web_base64 = { path = "crates/lib/data/web_base64" }
world_labs_client = { path = "crates/api_clients/world_labs_client" }
# External libs
# Centrally pinned versions so that we can uniformly upgrade/downgrade versions across the workspace
@@ -227,22 +237,26 @@ actix-web-actors = "4.3.1+deprecated"
actix-web-lab = "0.20.2"
anyhow = "1.0.98"
base64 = "0.22.1"
bstr = "1.12.1"
bytes = "1.10.1"
chrono = { version = "0.4.41", features = ["serde"] }
cookie = "0.18.1"
env = "1.0.1"
env_logger = "0.11.8"
futures = { version = "0.3.31" }
hex-literal = "1.0.0"
indexmap = "2.9.0"
log = "0.4.27"
once_cell = "1.21.3"
rand = "0.9.1"
regex = "1.11.1"
reqwest = { version = "0.12.22", features = ["json", "cookies"] }
regex = "1.12.2"
reqwest = { version = "0.12.23", default-features = false, features = [ "charset", "http2", "system-proxy", "json", "cookies", "rustls-tls" ] }
reqwest-websocket = { version = "0.5.0" }
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"
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"
@@ -255,3 +269,17 @@ thiserror = "2.0.12"
tokio = { version = "1.45.1", features = ["macros"] }
toml = "0.8.22"
url = { version = "2.5.4", features = ["serde"] }
uuid = "1.18.1"
# NB: wreq gets past fingerprinting, but we have to deal with platform-specific build issues.
#
# Mac:
# brew install --formula cmake pkg-config llvm
# Windows:
# choco install cmake -y
# choco install strawberryperl -y
# choco install pkgconfiglite -y
# choco install llvm -y
# choco install nasm -y
wreq = { version = "6.0.0-rc.20", features = ["json", "multipart", "cookies", "ws", "stream"] }
wreq-util = "3.0.0-rc.6"
@@ -0,0 +1,20 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
-- noinspection SqlResolveForFile
select
u.display_name,
count(*) as sessions,
a.session_duration_seconds / 60 / 60 as hours,
a.measurement_count,
u.email_address,
a.os_platform,
a.os_version,
u.created_at,
u.maybe_source,
a.last_active_at
from analytics_app_sessions as a
left outer join users as u
on a.user_token = u.token
group by a.user_token
order by hours desc;
@@ -9,6 +9,14 @@
-- tasks_v1.sqlite - initial version
-- tasks_v2.sqlite - added model_type (nullable)
-- tasks_v3.sqlite - added frontend_caller, comments
-- tasks_v4.sqlite - added is_dismissed_by_user
-- tasks_v5.sqlite - added five fields:
-- on_complete_batch_token,
-- on_complete_primary_media_file_token,
-- on_complete_primary_media_file_class,
-- on_complete_primary_media_file_cdn_url,
-- on_complete_primary_media_file_thumbnail_url_template,
--
CREATE TABLE tasks (
-- Task auto-incrementing primary key.
@@ -50,6 +58,32 @@ CREATE TABLE tasks (
-- will be re-emitted back to the frontend.
frontend_subscriber_payload TEXT,
-- Whether the user has dismissed the task from view.
is_dismissed_by_user INTEGER NOT NULL DEFAULT 0,
-- OPTIONAL.
-- When the generation completes, the batch token (if any).
-- This will point to a collection of multiple files.
on_complete_batch_token TEXT,
-- OPTIONAL.
-- When the generation completes, the media token of the "primary" media file.
-- We'll probably always generate homogenous types, but just in case this is the first or primary item in a batch.
on_complete_primary_media_file_token TEXT,
-- OPTIONAL.
-- When the generation completes, the file type of the primary media file.
-- We'll probably always generate homogenous types, but just in case this is the first or primary item in a batch.
on_complete_primary_media_file_class TEXT,
-- OPTIONAL.
-- The URL to the media file.
on_complete_primary_media_file_cdn_url TEXT,
-- OPTIONAL.
-- The URL template for the thumbnail of the primary media file.
on_complete_primary_media_file_thumbnail_url_template TEXT,
created_at INTEGER NOT NULL DEFAULT (unixepoch('now')),
updated_at INTEGER NOT NULL DEFAULT (unixepoch('now')),
completed_at INTEGER DEFAULT NULL
+1
View File
@@ -152,6 +152,7 @@ CREATE TABLE media_files (
-- * `vmd`
-- * `pmx`
-- * `csv`
-- * `spz` Gaussian splats
media_type VARCHAR(16) NOT NULL,
-- Broad class of media:
@@ -3,4 +3,5 @@ pub mod job_details;
pub mod media_file_cover_image_details;
pub mod media_links;
pub mod simple_entity_stats;
pub mod simple_generic_json_success;
pub mod user_details_light;
@@ -0,0 +1,7 @@
use serde_derive::{Deserialize, Serialize};
use utoipa::ToSchema;
#[derive(Serialize, Deserialize, ToSchema)]
pub struct SimpleGenericJsonSuccess {
pub success: bool,
}
@@ -0,0 +1 @@
pub mod remove_image_background;
@@ -1,6 +1,6 @@
pub mod flux_pro_kontext_max_edit_image;
pub mod gpt_image_1_edit_image;
pub mod gemini_25_flash_edit_image;
pub mod gpt_image_1_edit_image;
pub mod qwen_edit_image;
pub mod seededit_3_edit_image;
@@ -0,0 +1,5 @@
pub mod bg_removal;
pub mod edit;
pub mod inpaint;
pub mod multi_function;
pub mod text;
@@ -0,0 +1,69 @@
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_V4_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/bytedance_seedream_4";
#[derive(Serialize, Deserialize, ToSchema)]
pub struct BytedanceSeedreamV4MultiFunctionImageGenRequest {
/// 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<BytedanceSeedreamV4MultiFunctionImageGenNumImages>,
pub max_images: Option<BytedanceSeedreamV4MultiFunctionImageGenMaxImages>,
pub image_size: Option<BytedanceSeedreamV4MultiFunctionImageGenImageSize>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum BytedanceSeedreamV4MultiFunctionImageGenNumImages {
One, // Default
Two,
Three,
Four,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum BytedanceSeedreamV4MultiFunctionImageGenMaxImages {
One, // Default
Two,
Three,
Four,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum BytedanceSeedreamV4MultiFunctionImageGenImageSize {
// Square
Square,
SquareHd,
// Tall
PortraitFourThree,
PortraitSixteenNine,
// Wide
LandscapeFourThree,
LandscapeSixteenNine,
// Auto
Auto,
Auto2k,
Auto4k,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct BytedanceSeedreamV4MultiFunctionImageGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -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_V4P5_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/bytedance_seedream_4p5";
#[derive(Serialize, Deserialize, ToSchema)]
pub struct BytedanceSeedreamV4p5MultiFunctionImageGenRequest {
/// 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<BytedanceSeedreamV4p5MultiFunctionImageGenNumImages>,
pub max_images: Option<BytedanceSeedreamV4p5MultiFunctionImageGenMaxImages>,
pub image_size: Option<BytedanceSeedreamV4p5MultiFunctionImageGenImageSize>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum BytedanceSeedreamV4p5MultiFunctionImageGenNumImages {
One, // Default
Two,
Three,
Four,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum BytedanceSeedreamV4p5MultiFunctionImageGenMaxImages {
One, // Default
Two,
Three,
Four,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum BytedanceSeedreamV4p5MultiFunctionImageGenImageSize {
// Square
Square,
SquareHd,
// Tall
PortraitFourThree,
PortraitSixteenNine,
// Wide
LandscapeFourThree,
LandscapeSixteenNine,
// Auto
Auto2k,
Auto4k,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct BytedanceSeedreamV4p5MultiFunctionImageGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -0,0 +1,95 @@
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
pub const GPT_IMAGE_1P5_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/gpt_image_1p5";
#[derive(Serialize, Deserialize, ToSchema)]
pub struct GptImage1p5MultiFunctionImageGenRequest {
/// 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 (**OR INPAINTING CONTEXT!**).
/// If present, we're doing image editing (image-to-image / image-editing / image-inpainting)
/// If absent, we're doing image generation (text-to-image)
pub image_media_tokens: Option<Vec<MediaFileToken>>,
/// Only for image editing, which turns this into an inpainting task.
/// Text to image should not set this.
pub mask_image_token: Option<MediaFileToken>,
/// Number of images to generate. Default is one.
pub num_images: Option<GptImage1p5MultiFunctionImageGenNumImages>,
pub image_size: Option<GptImage1p5MultiFunctionImageGenSize>,
pub background: Option<GptImage1p5MultiFunctionImageGenBackground>,
pub quality: Option<GptImage1p5MultiFunctionImageGenQuality>,
/// Only for image editing.
pub input_fidelity: Option<GptImage1p5MultiFunctionImageGenInputFidelity>,
pub output_format: Option<GptImage1p5MultiFunctionImageGenOutputFormat>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum GptImage1p5MultiFunctionImageGenNumImages {
One, // Default
Two,
Three,
Four,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum GptImage1p5MultiFunctionImageGenSize {
/// 1024x1024
Square,
/// 1536x1024
Wide,
/// 1024x1536
Tall,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum GptImage1p5MultiFunctionImageGenBackground {
Auto,
Transparent,
Opaque,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum GptImage1p5MultiFunctionImageGenQuality {
Low,
Medium,
High,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum GptImage1p5MultiFunctionImageGenInputFidelity {
Low,
High,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum GptImage1p5MultiFunctionImageGenOutputFormat {
Jpeg,
Png,
Webp,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct GptImage1p5MultiFunctionImageGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -0,0 +1,5 @@
pub mod bytedance_seedream_v4_multi_function_image_gen;
pub mod bytedance_seedream_v4p5_multi_function_image_gen;
pub mod gpt_image_1p5_multi_function_image_gen;
pub mod nano_banana_multi_function_image_gen;
pub mod nano_banana_pro_multi_function_image_gen;
@@ -0,0 +1,62 @@
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_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/nano_banana";
#[derive(Serialize, Deserialize, ToSchema, Debug)]
pub struct NanoBananaMultiFunctionImageGenRequest {
/// 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<NanoBananaMultiFunctionImageGenNumImages>,
/// Aspect ratio of the images to generate. Default is "1:1"
pub aspect_ratio: Option<NanoBananaMultiFunctionImageGenAspectRatio>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum NanoBananaMultiFunctionImageGenNumImages {
One, // Default
Two,
Three,
Four,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum NanoBananaMultiFunctionImageGenAspectRatio {
// 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, // NB: No NineByTwentyOne ?
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct NanoBananaMultiFunctionImageGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -0,0 +1,73 @@
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_PRO_MULTI_FUNCTION_IMAGE_GEN_PATH: &str = "/v1/generate/image/multi_function/nano_banana_pro";
#[derive(Serialize, Deserialize, ToSchema, Debug)]
pub struct NanoBananaProMultiFunctionImageGenRequest {
/// 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<NanoBananaProMultiFunctionImageGenNumImages>,
/// Resolution of the image to generate. Default is OneK (1K).
pub resolution: Option<NanoBananaProMultiFunctionImageGenImageResolution>,
/// Aspect ratio of the images to generate. Default is "1:1"
pub aspect_ratio: Option<NanoBananaProMultiFunctionImageGenAspectRatio>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum NanoBananaProMultiFunctionImageGenNumImages {
One, // Default
Two,
Three,
Four,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum NanoBananaProMultiFunctionImageGenImageResolution {
OneK,
TwoK,
FourK,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum NanoBananaProMultiFunctionImageGenAspectRatio {
// 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, // NB: No NineByTwentyOne ?
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct NanoBananaProMultiFunctionImageGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -0,0 +1,50 @@
use serde_derive::{Deserialize, Serialize};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
pub const GEMINI_25_FLASH_EDIT_IMAGE_PATH: &str = "/v1/generate/image/gemini_25_flash";
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Gemini25FlashTextToImageImageRequest {
/// Idempotency token to prevent duplicate requests.
pub uuid_idempotency_token: String,
/// Text prompt to generate the image from.
pub prompt: Option<String>,
// TODO: OneOf for image_urls or image_media_tokens
/// Image media tokens to include in the editing context.
pub image_media_tokens: Option<Vec<MediaFileToken>>,
/// Number of images to generate. Default is one.
pub num_images: Option<Gemini25FlashTextToImageImageNumImages>,
/// Quality of the image to generate. Default is High.
pub image_quality: Option<Gemini25FlashTextToImageImageImageQuality>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Gemini25FlashTextToImageImageNumImages {
One, // Default
Two,
Three,
Four,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Gemini25FlashTextToImageImageImageQuality {
Auto,
Low,
Medium,
High, // Default
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Gemini25FlashTextToImageImageResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -19,6 +19,7 @@ pub struct GenerateFluxPro11TextToImageRequest {
pub num_images: Option<GenerateFluxPro11TextToImageNumImages>,
}
// TODO(btw,2026-01-01): Fal.ai and Fal.rs client libraries seem to disagree about the options.
#[derive(Copy, Clone, Debug, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum GenerateFluxPro11TextToImageAspectRatio {
@@ -23,10 +23,14 @@ pub struct GenerateFluxPro11UltraTextToImageRequest {
#[serde(rename_all = "snake_case")]
pub enum GenerateFluxPro11UltraTextToImageAspectRatio {
Square, // 1:1
LandscapeThreeByTwo, // 3:2
LandscapeFourByThree, // 4:3
LandscapeSixteenByNine, // 16:9
LandscapeTwentyOneByNine, // 21:9
PortraitTwoByThree, // 2:3
PortraitThreeByFour, // 3:4
PortraitNineBySixteen, // 9:16
PortraitNineByTwentyOne, // 9:21
//Custom { width: u32, height: u32 }, // TODO
}
@@ -1,8 +1,6 @@
pub mod edit;
pub mod gemini_25_flash_text_to_image;
pub mod generate_flux_1_dev_text_to_image;
pub mod generate_flux_1_schnell_text_to_image;
pub mod generate_flux_pro_11_text_to_image;
pub mod generate_flux_pro_11_ultra_text_to_image;
pub mod generate_gpt_image_1_text_to_image;
pub mod inpaint;
pub mod remove_image_background;
@@ -21,11 +21,14 @@ pub struct GenerateSeedance10LiteImageToVideoRequest {
/// Optional text prompt.
pub prompt: Option<String>,
/// Optional: aspect ratio of the generated video.
/// Optional: resolution of the generated video.
pub resolution: Option<GenerateSeedance10LiteResolution>,
/// Optional: aspect ratio of the generated video.
/// Optional: duration of the generated video.
pub duration: Option<GenerateSeedance10LiteDuration>,
/// Optional: aspect ratio of the generated video.
pub aspect_ratio: Option<GenerateSeedance10LiteAspectRatio>,
}
#[derive(Serialize, Deserialize, ToSchema)]
@@ -42,6 +45,19 @@ pub enum GenerateSeedance10LiteDuration {
TenSeconds,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum GenerateSeedance10LiteAspectRatio {
Auto,
TwentyOneByNine,
SixteenByNine,
FourByThree,
Square,
ThreeByFour,
NineBySixteen,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct GenerateSeedance10LiteImageToVideoResponse {
pub success: bool,
@@ -5,4 +5,5 @@ pub mod generate_seedance_1_0_lite_image_to_video;
pub mod generate_seedance_1_0_pro_image_to_video;
pub mod generate_veo_2_image_to_video;
pub mod generate_veo_3_fast_image_to_video;
pub mod generate_veo_3_image_to_video;
pub mod generate_veo_3_image_to_video;
pub mod multi_function;
@@ -0,0 +1,64 @@
use serde::{Deserialize, Serialize};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
pub const KLING_2P5_TURBO_PRO_MULTI_FUNCTION_VIDEO_VIDEO_PATH: &str = "/v1/generate/video/multi_function/kling_2p5_turbo_pro";
/// Both text-to-video and image-to-video in one request.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Kling2p5TurboProMultiFunctionVideoGenRequest {
/// 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 text-to-video.
pub negative_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 (if desired)
pub end_frame_image_media_token: Option<MediaFileToken>,
/// Optional
/// Duration of the video
pub duration: Option<Kling2p5TurboProMultiFunctionVideoGenDuration>,
/// Optional.
/// Only for text-to-video
pub aspect_ratio: Option<Kling2p5TurboProMultiFunctionVideoGenAspectRatio>,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Kling2p5TurboProMultiFunctionVideoGenDuration {
FiveSeconds,
TenSeconds,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Kling2p5TurboProMultiFunctionVideoGenAspectRatio {
Square,
SixteenByNine,
NineBySixteen,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Kling2p5TurboProMultiFunctionVideoGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -0,0 +1,68 @@
use serde::{Deserialize, Serialize};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
pub const KLING_2P6_PRO_MULTI_FUNCTION_VIDEO_VIDEO_PATH: &str = "/v1/generate/video/multi_function/kling_2p6_pro";
/// Both text-to-video and image-to-video in one request.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Kling2p6ProMultiFunctionVideoGenRequest {
/// 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 text-to-video.
pub negative_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 (if desired)
// pub end_frame_image_media_token: Option<MediaFileToken>,
/// Optional
/// Duration of the video
pub duration: Option<Kling2p6ProMultiFunctionVideoGenDuration>,
/// Optional
/// Whether to generate audio.
pub generate_audio: Option<bool>,
/// Optional.
/// Only for text-to-video
pub aspect_ratio: Option<Kling2p6ProMultiFunctionVideoGenAspectRatio>,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Kling2p6ProMultiFunctionVideoGenDuration {
FiveSeconds,
TenSeconds,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Kling2p6ProMultiFunctionVideoGenAspectRatio {
Square,
SixteenByNine,
NineBySixteen,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Kling2p6ProMultiFunctionVideoGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -0,0 +1,6 @@
pub mod kling_2_5_turbo_multi_function_video_gen;
pub mod kling_2_6_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;
pub mod veo_3p1_multi_function_video_gen;
@@ -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 SORA_2_MULTI_FUNCTION_VIDEO_VIDEO_PATH: &str = "/v1/generate/video/multi_function/sora_2";
/// Both text-to-video and image-to-video in one request.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Sora2MultiFunctionVideoGenRequest {
/// 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 image_media_token: Option<MediaFileToken>,
/// Optional.
pub resolution: Option<Sora2MultiFunctionVideoGenResolution>,
/// Optional
/// Duration of the video
/// (this is uniform against all modes)
pub duration: Option<Sora2MultiFunctionVideoGenDuration>,
/// Optional.
pub aspect_ratio: Option<Sora2MultiFunctionVideoGenAspectRatio>,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Sora2MultiFunctionVideoGenResolution {
Auto,
SevenTwentyP,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Sora2MultiFunctionVideoGenDuration {
FourSeconds,
EightSeconds,
TwelveSeconds,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Sora2MultiFunctionVideoGenAspectRatio {
Auto,
NineBySixteen,
SixteenByNine,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Sora2MultiFunctionVideoGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -0,0 +1,67 @@
use serde::{Deserialize, Serialize};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
pub const SORA_2_PRO_MULTI_FUNCTION_VIDEO_VIDEO_PATH: &str = "/v1/generate/video/multi_function/sora_2_pro";
/// Both text-to-video and image-to-video in one request.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Sora2ProMultiFunctionVideoGenRequest {
/// 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 image_media_token: Option<MediaFileToken>,
/// Optional.
pub resolution: Option<Sora2ProMultiFunctionVideoGenResolution>,
/// Optional
/// Duration of the video
/// (this is uniform against all modes)
pub duration: Option<Sora2ProMultiFunctionVideoGenDuration>,
/// Optional.
pub aspect_ratio: Option<Sora2ProMultiFunctionVideoGenAspectRatio>,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Sora2ProMultiFunctionVideoGenResolution {
Auto,
SevenTwentyP,
TenEightyP,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Sora2ProMultiFunctionVideoGenDuration {
FourSeconds,
EightSeconds,
TwelveSeconds,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Sora2ProMultiFunctionVideoGenAspectRatio {
Auto,
NineBySixteen,
SixteenByNine,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Sora2ProMultiFunctionVideoGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -0,0 +1,90 @@
use serde::{Deserialize, Serialize};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
pub const VEO_3P1_FAST_MULTI_FUNCTION_VIDEO_VIDEO_PATH: &str = "/v1/generate/video/multi_function/veo_3p1_fast";
/// Both text-to-video and image-to-video in one request.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Veo3p1FastMultiFunctionVideoGenRequest {
/// 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 text-to-video.
pub negative_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 (if desired)
pub end_frame_image_media_token: Option<MediaFileToken>,
/// Optional
/// Duration of the video
/// (this is uniform against all modes)
pub duration: Option<Veo3p1FastMultiFunctionVideoGenDuration>,
/// Optional.
pub aspect_ratio: Option<Veo3p1FastMultiFunctionVideoGenAspectRatio>,
/// Optional.
pub resolution: Option<Veo3p1FastMultiFunctionVideoGenResolution>,
/// Optional
/// Whether to generate audio.
pub generate_audio: Option<bool>,
/// Optional
/// Only for text-to-video
pub enhance_prompt: Option<bool>,
/// Optional
/// Only for text-to-video
pub seed: Option<i64>,
/// Optional
/// Only for text-to-video
pub auto_fix: Option<bool>,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Veo3p1FastMultiFunctionVideoGenDuration {
FourSeconds,
SixSeconds,
EightSeconds,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Veo3p1FastMultiFunctionVideoGenAspectRatio {
Auto,
SixteenByNine,
NineBySixteen,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Veo3p1FastMultiFunctionVideoGenResolution {
SevenTwentyP,
TenEightyP,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Veo3p1FastMultiFunctionVideoGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -0,0 +1,90 @@
use serde::{Deserialize, Serialize};
use tokens::tokens::generic_inference_jobs::InferenceJobToken;
use tokens::tokens::media_files::MediaFileToken;
use utoipa::ToSchema;
pub const VEO_3P1_MULTI_FUNCTION_VIDEO_VIDEO_PATH: &str = "/v1/generate/video/multi_function/veo_3p1";
/// Both text-to-video and image-to-video in one request.
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Veo3p1MultiFunctionVideoGenRequest {
/// 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 text-to-video.
pub negative_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 (if desired)
pub end_frame_image_media_token: Option<MediaFileToken>,
/// Optional
/// Duration of the video
/// (this is uniform against all modes)
pub duration: Option<Veo3p1MultiFunctionVideoGenDuration>,
/// Optional.
pub aspect_ratio: Option<Veo3p1MultiFunctionVideoGenAspectRatio>,
/// Optional.
pub resolution: Option<Veo3p1MultiFunctionVideoGenResolution>,
/// Optional
/// Whether to generate audio.
pub generate_audio: Option<bool>,
/// Optional
/// Only for text-to-video
pub enhance_prompt: Option<bool>,
/// Optional
/// Only for text-to-video
pub seed: Option<i64>,
/// Optional
/// Only for text-to-video
pub auto_fix: Option<bool>,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Veo3p1MultiFunctionVideoGenDuration {
FourSeconds,
SixSeconds,
EightSeconds,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Veo3p1MultiFunctionVideoGenAspectRatio {
Auto,
SixteenByNine,
NineBySixteen,
}
#[derive(Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum Veo3p1MultiFunctionVideoGenResolution {
SevenTwentyP,
TenEightyP,
}
#[derive(Serialize, Deserialize, ToSchema)]
pub struct Veo3p1MultiFunctionVideoGenResponse {
pub success: bool,
pub inference_job_token: InferenceJobToken,
}
@@ -6,4 +6,5 @@ pub mod jobs;
pub mod media_file;
pub mod prompts;
pub mod stripe_artcraft;
pub mod subscriptions;
pub mod subscriptions;
pub mod utils;
@@ -0,0 +1,19 @@
use serde_derive::{Deserialize, Serialize};
use utoipa::ToSchema;
use tokens::tokens::media_files::MediaFileToken;
#[derive(Serialize, Deserialize, ToSchema)]
pub struct DeleteMediaFileRequest {
pub set_delete: bool,
/// NB: this is only to disambiguate when a user is both a mod and an author.
pub as_mod: Option<bool>,
}
/// For the URL PathInfo
#[derive(Serialize, Deserialize, ToSchema)]
pub struct DeleteMediaFilePathInfo {
pub token: MediaFileToken,
}
@@ -1 +1,2 @@
pub mod delete_media_file;
pub mod list_batch_generated_media_files;
@@ -0,0 +1,12 @@
use crate::common::responses::media_links::MediaLinks;
/// Get the thumbnail template for either images or videos.
pub fn media_links_to_thumbnail_template(links: &MediaLinks) -> Option<&str> {
// NB: We only populate video previews for video tasks.
if let Some(video) = links.maybe_video_previews.as_ref() {
return Some(&video.animated_thumbnail_template);
}
// Image case - use the image thumbnail template if it exists.
links.maybe_thumbnail_template.as_deref()
}
@@ -0,0 +1 @@
pub mod media_links_to_thumbnail_template;

Some files were not shown because too many files have changed in this diff Show More