feat(catalogue): a curated file of providers and models, refreshed daily
The five connections in the database were never configured by anyone — a migration minted one per model from the adapter's own list, so the table held five decisions nobody made. What that list actually is, is a CATALOGUE: what you can choose from, which is not the same kind of thing as what you chose. So it is a file. `sidecar/catalogue/shipped.ts` is the curated baseline, in git, reviewed; `$OFFICER_ROOT/data/atelier/catalogue.json` is what a refresh writes, and it wins where it has something to say. Data dir, not the plugin dir — a plugin directory is a clone an update replaces, which is the rule env.ts already states for images. Refresh runs in the sidecar, daily, and only on boot when the file is actually stale — this process has restarted twenty times in an afternoon and should not hit OpenAI twenty times for it. Two sources, unequal, and the code says so. `GET /v1/models` is authoritative and thin: ids and nothing else, so a model matching /^(gpt-image|dall-e)/ appears the day it ships without a release. Prices come off an HTML page because there is no pricing endpoint for any plan, and that parser is written to give up rather than guess — a guess gets written to disk and then believed. When it gives up it says so in the log; the durable replacement is handing the page to a model for structured output, which Officer can already do locally. Nothing a refresh cannot establish overwrites a curated value: fields merge one by one, not objects wholesale, so an id-only listing cannot wipe the sizes and prices that were written by hand. Retiring is decided by the merge, which can tell a complete listing from a request that failed halfway — and it marks `deprecated` rather than deleting, because the gallery labels 88 historical rows from this list. Per-model sizes, qualities and transparency now travel with each entry, which is what will let the form stop offering dall-e-2 a transparent background it cannot do. The catalogue is advisory throughout: validate.ts still refuses to enforce per-model rules, exactly as before.
This commit is contained in:
@@ -4,6 +4,7 @@ import { API_URL } from '@@/officer-url.mjs';
|
||||
import { buildHonoApp } from './hono';
|
||||
import { waitForDatabase } from './db';
|
||||
import { startQueue } from './generations/queue';
|
||||
import { startCatalogueRefresh } from './catalogue/refresh';
|
||||
|
||||
// The officer-atelier sidecar. Owns the whole image-generation contract: providers, the generation
|
||||
// queue, and the `atelier` Postgres database (kept separate from officer_db — see ../PLUGIN.md).
|
||||
@@ -79,6 +80,10 @@ const connection = createSidecarConnector({
|
||||
void (async () => {
|
||||
if (await waitForDatabase()) await startQueue();
|
||||
else console.error('[atelier:queue] not started: no database');
|
||||
|
||||
// After the database, because a refresh reads any connection's key before falling back to the
|
||||
// environment — and before it, there is nothing to read.
|
||||
await startCatalogueRefresh();
|
||||
})();
|
||||
|
||||
function shutdown(signal: string) {
|
||||
|
||||
Reference in New Issue
Block a user