Skip to content

SN-2c: image generation through Gecko Suite behind AI_BACKEND - #216

Merged
davior merged 1 commit into
mainfrom
claude/beautiful-wright-og4xur
Nov 4, 2026
Merged

davior merged 1 commit into
mainfrom
claude/beautiful-wright-og4xur

Conversation

@davior

@davior davior commented Nov 4, 2026

Copy link
Copy Markdown
Owner

Summary

Last piece of SN-2. With AI_BACKEND=suite, generate_image_for_user (used by the image route and the assistant's generate_image action) sends its fal request to the suite's media queue instead of to fal. local is unchanged.

  • Notes still owns the catalogue. The model list, size presets and each endpoint's request fields (build_fal_image_body) stay here, as in GAM. The suite is the fal key, the queue and the bill, so no fal key is needed in Notes in this mode.
  • Flow: submit POST /ai/media/jobs (kind image), poll until it finishes, take the image URL from fal's result, then download and save it into the user's media exactly as before (stable /media/... URL, thumbnail, size cap, SSRF check).
  • Cost is the suite's billed amount from the job, returned as before (cost, currency; null when fal's price is not yet known). Notes writes no usage row; the suite has.
  • A generation that does not finish within the existing 180 s is cancelled (DELETE on the job) rather than left running and billing, and answers 504. fal's own refusal reason is passed through as a 502 fal_error. The suite being down is a 503 suite_unavailable.
  • This completes SN-2 (search SN-2a: web search through Gecko Suite behind AI_BACKEND #214, speech SN-2b: speech through Gecko Suite behind AI_BACKEND #215, images here).

Not changed: Settings → Images' fal usage and balance readouts (/images/usage, /images/pricing) still use Notes' own fal admin/billing keys; they report Notes' own history, not the suite's.

Test plan

  • pytest -q in backend/: 1379 passed, 1 skipped (Python 3.13 locally; CI is 3.11). 5 new tests in tests/test_suite_proxy.py through the real image route with a fake suite and a fake fal download: queued → running → completed, file saved in Notes' media, cost from the job, the endpoint body Notes built, no usage row and no fal key needed; a failed job keeping fal's reason; a never-finishing job cancelled with a 504; a model outside Notes' list refused without calling the suite; the suite down.
  • Not run against the real suite or fal.

Deployment

Nothing changes unless AI_BACKEND=suite is set (from #213).

  • Before enabling: the person needs a fal.ai provider in the suite (their own, or a shared one), which the suite's importer brings across from Notes' fal key.
  • Configuration: none new. Services rebuilt: backend only. Migrations, Caddy: none.
  • Verify: in suite mode generate an image from the editor (it appears in the note) and from the assistant; the suite's Usage view shows an image event under app notes with a cost.
  • Roll back: AI_BACKEND=local, docker compose up -d.

Generated by Claude Code

In suite mode generate_image_for_user keeps Notes' model list, size presets and per-endpoint
request builder, and sends the body to the suite's fal queue instead of fal. The suite holds
the key and records the billed cost; Notes polls the job, downloads the result into the
user's media as before, and writes no usage. A generation that does not finish in time is
cancelled so it is not billed for nobody.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1geD2ELWgL2sDpxYbx3Aw
@davior
davior marked this pull request as ready for review November 4, 2026 09:36
@davior
davior merged commit 423793f into main Nov 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants