feat: move base URL, API key, and model to server .env
- BASE_URL, API_KEY, MODEL now read from process.env (Bun auto-loads .env)
- requireEnv() fails fast at startup if any is missing
- request body simplifies to { prompt, size, referenceImages? }
- client drops the three fields from form and localStorage
- add .env.example as the variable-name source of truth
- AGENTS.md notes the 0.0.0.0 bind now exposes the upstream quota to
anyone reachable on the network
This commit is contained in:
@@ -12,6 +12,26 @@ proxy-read timeout.
|
||||
`dotenv` — Bun loads `.env` automatically.
|
||||
- Bun version baseline: `1.3.13` (per `README.md`).
|
||||
|
||||
## Config
|
||||
|
||||
Required env vars (validated at startup via `requireEnv`; the process exits
|
||||
if any is missing):
|
||||
|
||||
| Var | Example | Purpose |
|
||||
|---|---|---|
|
||||
| `BASE_URL` | `https://api.openai.com/v1` | OpenAI-compatible base URL |
|
||||
| `API_KEY` | `sk-…` | Bearer token sent to upstream |
|
||||
| `MODEL` | `gpt-image-2` | Model name forwarded to upstream |
|
||||
|
||||
`.env.example` is the source of truth for variable names. The real `.env`
|
||||
is gitignored. Restart the server after changing env vars — they are read
|
||||
once at module load.
|
||||
|
||||
These secrets stay **server-side**. The browser only sends `prompt`,
|
||||
`size`, and `referenceImages`. Combined with the `0.0.0.0` bind, this
|
||||
means anyone reachable on the network can spend your upstream quota —
|
||||
bind to `127.0.0.1` or put auth in front if that matters.
|
||||
|
||||
## Commands
|
||||
|
||||
- Install: `bun install`
|
||||
@@ -41,7 +61,9 @@ Three files do everything:
|
||||
connections before the first keepalive can fire. The symptom is an
|
||||
empty EventStream in DevTools and `request timed out after 10 seconds`
|
||||
in the log.
|
||||
- `POST /api/generate` uses `streamSSE` from `hono/streaming`. Emits:
|
||||
- `POST /api/generate` uses `streamSSE` from `hono/streaming`. Accepts
|
||||
`{ prompt, size, referenceImages? }` — `BASE_URL`, `API_KEY`, and
|
||||
`MODEL` come from env, not the request. Emits:
|
||||
- `event: partial` — `{ image: dataUrl, index }` for each
|
||||
`image_generation.partial_image` / `image_edit.partial_image`.
|
||||
- `event: final` — `{ image: dataUrl }` for `*.completed`.
|
||||
@@ -80,9 +102,8 @@ Three files do everything:
|
||||
`signal`, and the `onopen` / `onmessage` / `onerror` callbacks.
|
||||
- On `done`, the client calls `abort.abort()` to terminate the
|
||||
`fetchEventSource` loop cleanly — otherwise it would retry forever.
|
||||
- Text fields (`baseURL`, `apiKey`, `model`, `size`, `prompt`) persist
|
||||
in `localStorage` under the `aip:<field>` prefix. Reference images
|
||||
stay in-memory only.
|
||||
- Text fields (`size`, `prompt`) persist in `localStorage` under the
|
||||
`aip:<field>` prefix. Reference images stay in-memory only.
|
||||
- `index.html` — markup + inline CSS only. No JS lives here.
|
||||
|
||||
No router, no DB, no auth, no AI SDK. API key is supplied per-request by the
|
||||
|
||||
Reference in New Issue
Block a user