Gemini-only β remove OpenAI (audit + handoff) β
Historical 2026-06-08 handoff. Hermes and every Edge Function referenced below are now canonically owned in this repository under
services/hermes-server/andsupabase/functions/.
Date: 2026-06-08 Goal: No OpenAI anywhere. The AI system is Hermes (agent/gateway) with Gemini internally.
The Flutter client has no OpenAI provider; OpenAI-compatible naming describes only the wire format. Provider implementation is owned here by Hermes and the shared Edge Function client.
Audit (read-only, 2026-06-08) β OpenAI is dormant β
Against Supabase project jrsgosnnyjonxaesqtln:
hermes_configis 100% Gemini β nogpt-*pin:key value model.chatgoogle/gemini-3-flash-previewmodel.chat.targetgoogle/gemini-3.5-flashmodel.reasoninggoogle/gemini-3-pro-previewmodel.reasoning.targetgoogle/gemini-3.1-pro- Every AI edge function passes Gemini model IDs in its own logic (
gemini-2.5-flash,gemini-2.5-pro, alsosonar-pro). Nothing passes agpt-*model, so the OpenAI branch is never executed. - The OpenAI code is not function-specific. It lives in the shared
_shared/aiClient.ts(bundled into ~28 AI functions): agpt-branch ingetProviderConfig, theOPENAI_APIconstant, theOPENAI_API_KEYenv read, andgpt-4o*rows in the cost table. generate-property-imageand the ~88 non-AI functions: no OpenAI markers.
Conclusion: OpenAI is present but inert β dead code in one shared helper + an unused secret. Removing it is low-risk (zero functional impact, since nothing uses gpt-*).
Action 1 (kill-switch) β β ALREADY SATISFIED β
Verified 2026-06-08 via supabase secrets list --project-ref jrsgosnnyjonxaesqtln: there is no OPENAI_API_KEY secret β it was never set (GOOGLE_AI_API_KEY for Gemini is present). So the edge functions' OpenAI path is already non-functional: if a gpt-* model were ever passed, getProviderConfig throws OPENAI_API_KEY is not configured and never reaches api.openai.com.
Nothing to remove. If a future change ever adds the secret, drop it with:
supabase secrets unset OPENAI_API_KEY --project-ref jrsgosnnyjonxaesqtlnNet: OpenAI in the edge functions is doubly dormant β no caller passes gpt-* (Action 2 removes that dead code), and the key is absent (this action).
Action 2 (permanent removal at the source) β patch _shared/aiClient.ts β
Edit supabase/functions/_shared/aiClient.ts here and deploy the affected allowlisted functions from the canonical Flutter pipeline. One edit propagates to all bundled AI functions.
a) Delete the OPENAI_API constant:
// remove this line:
const OPENAI_API = 'https://api.openai.com/v1/chat/completions';b) Remove the gpt- branch in getProviderConfig (Gemini-only):
// BEFORE
function getProviderConfig(model: string): { url: string; apiKey: string; resolvedModel: string } {
if (model.startsWith('gpt-')) {
const key = Deno.env.get('OPENAI_API_KEY');
if (!key) throw new Error('OPENAI_API_KEY is not configured');
return { url: OPENAI_API, apiKey: key, resolvedModel: model };
}
// Google models β use native Gemini API with OpenAI-compatible endpoint
const key = Deno.env.get('GOOGLE_AI_API_KEY');
if (!key) throw new Error('GOOGLE_AI_API_KEY is not configured β set it in Supabase Edge Function secrets');
return { url: GOOGLE_AI_API, apiKey: key, resolvedModel: resolveGoogleModel(model) };
}
// AFTER (Gemini-only)
function getProviderConfig(model: string): { url: string; apiKey: string; resolvedModel: string } {
// Gemini-only. The OpenAI provider branch has been removed; any stray
// non-Gemini id is coerced to Gemini by resolveGoogleModel, so no request
// can reach api.openai.com.
const key = Deno.env.get('GOOGLE_AI_API_KEY');
if (!key) throw new Error('GOOGLE_AI_API_KEY is not configured β set it in Supabase Edge Function secrets');
return { url: GOOGLE_AI_API, apiKey: key, resolvedModel: resolveGoogleModel(model) };
}c) Harden resolveGoogleModel so a stray non-Gemini id can't reach the Google endpoint:
// BEFORE
function resolveGoogleModel(model: string): string {
return GOOGLE_MODEL_MAP[model] ?? model;
}
// AFTER
function resolveGoogleModel(model: string): string {
const mapped = GOOGLE_MODEL_MAP[model] ?? model;
return mapped.startsWith('gemini') ? mapped : 'gemini-2.5-flash';
}d) Delete the gpt-* cost rows in MODEL_COSTS_PER_1M:
// remove:
'gpt-4o-mini': { input: 0.15, output: 0.60 },
'gpt-4o': { input: 5.00, output: 15.00 },Then redeploy the AI functions (normal pipeline). Note: doing this per-function via the Supabase MCP was rejected β it would patch only one of ~28 bundles and diverge from this source, reintroducing OpenAI on the next source deploy. Fix it here, once.
Verify after deploy: recent ai-assistant rows in ai_usage_logs.model show only gemini-*; grep the deployed bundles for api.openai.com β none.
Action 3 (primary system) β confirm Hermes is Gemini-only β
/ai chat routes through Hermes (hermes.aldilaijan.com) first; the edge functions are only the fallback. Hermes is a separate repo this agent can't see. This is the one genuinely-important remaining item. Run these in the Hermes repo:
1. Grep for a real OpenAI provider path (an "OpenAI-compatible SSE" format comment is fine; api.openai.com, gpt-* model selection, or OPENAI_API_KEY are not):
grep -rniE 'api\.openai\.com|OPENAI_API_KEY|[^a-z]gpt-[0-9a-z]' \
--include='*.ts' --include='*.js' --include='*.py' .Expected: no hits.
2. Does Hermes share _shared/aiClient.ts / the same getProviderConfig?
grep -rn 'getProviderConfig\|aiClient' --include='*.ts' .- If yes β the single Action 2 patch above also fixes Hermes (one edit covers both surfaces).
- If Hermes has its own provider code β apply the same removal there (no
model.startsWith('gpt-')branch; default/fallback model is a Gemini id).
3. Confirm model resolution is Gemini-only. hermes_config is already 100% Gemini (verified); check the code's hardcoded fallback is too (per HERMES_MODEL_CONFIG.md: google/gemini-3-flash-preview / β¦-pro-preview):
grep -rniE 'FALLBACK|default.*model|model.*default' --include='*.ts' .4. Check Hermes' runtime env (host/platform secret store, .env*) for OPENAI_API_KEY β remove if present.
5. Runtime proof β send one chat through Hermes, then:
select model, count(*) from public.ai_usage_logs
where created_at > now() - interval '15 min' group by model; -- expect only gemini-*Only once Hermes is confirmed is "no OpenAI in my system" fully true.
This repo (Flutter) β done β
There was never an OpenAI provider here β only the OpenAI-compatible SSE wire format. The misleadingly-named helper has been renamed (streamOpenAIEdgeFunction β streamSseChatEdgeFunction, file openai_edge_stream.dart β sse_chat_edge_stream.dart) so nothing in the Flutter codebase implies the OpenAI provider. The app remains provider-agnostic β it just streams whatever Hermes/Gemini returns.
