diff --git a/.gitignore b/.gitignore index e98ece7..a0586fa 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ __pycache__/ .venv/ .DS_Store frontend/dist/ +.env diff --git a/README.md b/README.md index 260aa3d..e5b0539 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ fully offline and local; the only optional cloud piece is moment classification. | **ffmpeg** / **ffprobe** on `PATH` | yes | audio extraction, frame sampling, clip cutting | | **Node 18+** | yes | frontend (Vite + Three.js) | | **COLMAP** on `PATH` | optional | 3D reconstruction. Without it the app still runs — you get synced videos + timeline, just no 3D scene. `brew install colmap` on macOS. | -| A classifier API key | optional | AI moment labels. Default **Gemini 2.5 Flash** (`GEMINI_API_KEY`); also Claude or any OpenAI-compatible/local/OpenRouter endpoint via `FESTIVAL4D_CLASSIFIER`. Without a key you still get audio-detected candidate moments, just unlabeled. | +| A classifier API key | optional | AI moment labels. Default **Gemini flash** (`GEMINI_API_KEY`; model `gemini-3.1-flash-lite`, override with `FESTIVAL4D_GEMINI_MODEL`); also Claude or any OpenAI-compatible/local/OpenRouter endpoint via `FESTIVAL4D_CLASSIFIER`. Without a key you still get audio-detected candidate moments, just unlabeled. | --- @@ -92,7 +92,7 @@ corrupts existing data. To enable AI moment labels, set a key before `events`: ```bash -export GEMINI_API_KEY=... # default provider (Gemini 2.5 Flash, native video) +export GEMINI_API_KEY=... # default provider (Gemini flash, native video) # or: export FESTIVAL4D_CLASSIFIER=claude ANTHROPIC_API_KEY=... # or: export FESTIVAL4D_CLASSIFIER=local FESTIVAL4D_OPENAI_BASE_URL=... FESTIVAL4D_OPENAI_MODEL=... ``` diff --git a/backend/festival4d/events_ai.py b/backend/festival4d/events_ai.py index 57b6b84..f8bbf80 100644 --- a/backend/festival4d/events_ai.py +++ b/backend/festival4d/events_ai.py @@ -102,13 +102,18 @@ _CLASSIFY_PROMPT = ( # only pydantic present; construction reads the key/endpoint from the environment. # --------------------------------------------------------------------------- class GeminiClassifier: - """Default provider — Gemini 2.5 Flash, native video input (``GEMINI_API_KEY``).""" + """Default provider — Gemini flash tier, native video input (``GEMINI_API_KEY``). - model = "gemini-2.5-flash" + Model is overridable via ``FESTIVAL4D_GEMINI_MODEL``. Default was ``gemini-2.5-flash`` + until Google retired it for new API keys (404 "no longer available to new users", + field-found 2026-07-16); ``gemini-3.1-flash-lite`` is the cheapest current model verified + to accept inline video + JSON-schema structured output. + """ def __init__(self) -> None: from google import genai + self.model = os.environ.get("FESTIVAL4D_GEMINI_MODEL", "gemini-3.1-flash-lite") self._genai = genai self._client = genai.Client() # reads GEMINI_API_KEY from the environment diff --git a/plan/DIRECTIVES.md b/plan/DIRECTIVES.md index 05498d3..59089cc 100644 --- a/plan/DIRECTIVES.md +++ b/plan/DIRECTIVES.md @@ -46,8 +46,23 @@ Content verified accurate — ratified as written. Rule stands for future rounds **For the human (unchanged + one new):** (a) open the app in a normal focused browser window once and confirm the sync panel stays green during continuous playback; (b) shoot or collect -2–4 overlapping clips of the same performance for the field test; (c) optionally set -`GEMINI_API_KEY` before `events` to see real moment labels. +2–4 overlapping clips of the same performance for the field test; (c) ~~optionally set +`GEMINI_API_KEY`~~ done — see addendum. + +**Round 3 addendum (coordinator, same day) — real API keys wired + first field finding:** +- A local **`.env`** now exists at the repo root (gitignored, chmod 600, **never commit**) with + `GEMINI_API_KEY` (default provider) and OpenRouter creds mapped to the `local` provider + (`FESTIVAL4D_OPENAI_*`, model `google/gemini-2.5-flash`). Load with + `set -a; . ./.env; set +a` before `python -m festival4d events`. Phase-4 agent: the file is + machine-local — if it's missing in your worktree, ask the coordinator, don't recreate keys. +- **Field finding #1 (fixed by coordinator hotfix):** Google retired `gemini-2.5-flash` for new + API keys (404 "no longer available to new users"). The Gemini model is now env-overridable + (`FESTIVAL4D_GEMINI_MODEL`) with default `gemini-3.1-flash-lite` — verified live: inline + video + JSON-schema structured output OK; **3/3 synthetic candidates classified correctly** + (`light_show`/`bass_drop`, coherent descriptions). Suite still 101 passed. The degradation + path also behaved exactly as designed during the failure — good lane D work. +- Phase-4 agent: consider a `plan/ISSUES.md` entry template seeded from this finding's shape + (symptom → root cause → fix → evidence). ## Round 2 — 2026-07-16 — Integration complete; v0.1.0 shipped