Add OpenAI (GPT-5.6 Sol) as a second vision provider; gate server settings to a named admin

vision.py now dispatches per-model to _call_anthropic or _call_openai --
same prompt, same schema, same cardimage.py measurements either way, only
the request/response shape differs. Confirmed the existing GRADING_SCHEMA
already satisfies OpenAI's strict-mode requirement (every property listed
in required, additionalProperties:false at every level) with no changes.

Settings gained a second axis: which server key applies now depends on the
selected model's provider, and friends' personal keys are stored per
provider (with a one-time migration from the old single-key localStorage
slot) since a Claude key and an OpenAI key aren't interchangeable.

CARD_GRADER_ADMIN_USER names one username (read from the proxy's forwarded
basic-auth header) who alone may write server settings; everyone else keeps
the same read-only view CARD_GRADER_LOCK used to give everyone, while still
being able to set their own personal key. Deployed here as ninja_hippo.
CARD_GRADER_LOCK remains the fallback when no admin is named.
This commit is contained in:
Barely Removable 2026-08-23 07:39:03 -07:00
parent 9d5c68b093
commit 034761e145
7 changed files with 351 additions and 122 deletions

View file

@ -77,6 +77,7 @@ CREATE INDEX IF NOT EXISTS idx_events_created ON grade_events(created_at DESC);
DEFAULT_SETTINGS = {
"anthropic_api_key": "",
"openai_api_key": "",
"vision_model": "claude-sonnet-5",
"vision_effort": "low",
}