import { CATALOGUE_REVISION, type Catalogue } from './types'; /** * The catalogue as it ships with the plugin — the floor a refresh builds on, and the whole of it when * no refresh has ever run or every refresh has failed. * * Written by hand and reviewed in git, because none of it is fetchable: `GET /v1/models` returns ids, * an owner and a timestamp, and says nothing about price, sizes, transparency, or whether a model is * one you would still choose. That is the entire reason this file exists rather than a nightly fetch. * * The prices are USD per million tokens, from OpenAI's published pricing, and three of the five models * have none — deliberately. `PRICING` in providers/openai.ts had the same gap and the same reason: a * guessed price produces a number that looks authoritative and sums into a wrong total. */ export const SHIPPED_CATALOGUE: Catalogue = { revision: CATALOGUE_REVISION, providers: [ { name: 'openai', label: 'OpenAI', envVar: 'OPENAI_API_KEY', defaultModel: 'gpt-image-1', models: [ { id: 'gpt-image-1.5', label: 'GPT Image 1.5', kind: 'image', sizes: ['auto', '1024x1024', '1536x1024', '1024x1536'], qualities: ['auto', 'low', 'medium', 'high'], transparency: true, edit: true, pricing: { unit: 'token', textInput: 5, imageInput: 8, imageOutput: 32 }, status: 'current', source: 'shipped', }, { id: 'gpt-image-1', label: 'GPT Image 1', kind: 'image', sizes: ['auto', '1024x1024', '1536x1024', '1024x1536'], qualities: ['auto', 'low', 'medium', 'high'], transparency: true, edit: true, pricing: { unit: 'token', textInput: 5, imageInput: 10, imageOutput: 40 }, status: 'current', source: 'shipped', }, { id: 'gpt-image-1-mini', label: 'GPT Image 1 mini', kind: 'image', sizes: ['auto', '1024x1024', '1536x1024', '1024x1536'], qualities: ['auto', 'low', 'medium', 'high'], transparency: true, edit: true, pricing: { unit: 'token', textInput: 2, imageInput: 2.5, imageOutput: 8 }, status: 'current', source: 'shipped', }, { // No transparency and a different size set — which is exactly what the form was getting // wrong by offering one hard-coded list of sizes and qualities for every model. id: 'dall-e-3', label: 'DALL·E 3', kind: 'image', sizes: ['1024x1024', '1792x1024', '1024x1792'], qualities: ['standard', 'hd'], transparency: false, edit: false, status: 'current', source: 'shipped', }, { id: 'dall-e-2', label: 'DALL·E 2', kind: 'image', sizes: ['256x256', '512x512', '1024x1024'], qualities: ['standard'], transparency: false, edit: true, status: 'current', source: 'shipped', }, ], }, { /** * The first LOCAL provider: sd-server on this machine's GPU, not a vendor. * * No `envVar`, because there is no key and never will be — see `keyless` on the adapter. It is * `configured` by existing. * * The id is `sd-cpp-local` and not `qwen-image-2.1` because that is what `GET /v1/models` * returns, hardcoded in sd-server with no override. The catalogue is the only side that can * move, so it moves: the id agrees with the server, and the LABEL carries what the thing * actually is. */ name: 'qwen-local', label: 'Qwen-Image (local)', defaultModel: 'sd-cpp-local', models: [ { id: 'sd-cpp-local', /** * The timings are in the label because there is nowhere else for them, and a user choosing * 1024 should know before they wait rather than after. Measured from the server's own log on * this machine: 512 completes in ~185s; 1024 samples at ~41.4s/step over 20 steps. * * A `note` field on CatalogueModel would be the cleaner home for this. Not added on a guess — * it needs the UI to render it, and a field nothing displays is worse than a long label. */ label: 'Qwen-Image 2.1 (local) — 512 takes ~3 min, 1024 ~14 min', kind: 'image', /** * 512 first, and the adapter substitutes it for `auto` or for nothing. 1024 is offered * because it is genuinely better and sometimes worth the wait — but a default nobody chose * should not spend a quarter of an hour of the only GPU there is. */ sizes: ['512x512', '768x768', '1024x1024'], transparency: false, /** No `edit()` in this version — same GPU, same queue, and the generate path is unproven. */ edit: false, /** Zero is the true answer, not a missing one: it runs on hardware we already own. */ pricing: { unit: 'image', perImage: 0 }, status: 'current', source: 'shipped', }, ], }, ], };