Skip to content

Commit d87759f

Browse files
committed
feat: make GLM 5.3 Flash the only AI model
1 parent 75d221d commit d87759f

20 files changed

Lines changed: 263 additions & 214 deletions

‎docs/architecture.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ Supabase Auth owns user sessions. Protected routes provide a client navigation b
8383

8484
Checkout and portal functions create Stripe sessions after authenticated ownership and redirect validation. The webhook updates subscription state and records event processing for idempotency. AI handlers record provider usage and calculated cost using shared pricing logic.
8585

86-
All supported model requests use the single OpenRouter backend route and `OPENROUTER_API_KEY`; the shared allowlist and request controls live in [`supabase/functions/_shared/model-catalog.ts`](../supabase/functions/_shared/model-catalog.ts). OpenRouter usage remains raw in the audit row, and the reported charge is unknown when the provider does not return a complete cost.
86+
All model requests use the single OpenRouter backend route and `OPENROUTER_API_KEY`. The only selectable and default model is `z-ai/glm-5.3-flash`; the shared allowlist and request controls live in [`supabase/functions/_shared/model-catalog.ts`](../supabase/functions/_shared/model-catalog.ts). OpenRouter usage remains raw in the audit row, and the reported charge is unknown when the provider does not return a complete cost.
8787

8888
Historical provider pricing evidence is retained under [`docs/pricing-snapshots/`](pricing-snapshots/). Those snapshots support legacy calculator records and are evidence, not runtime configuration for the OpenRouter route.
8989

‎src/lib/stores/settings-store.ts‎

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import { create } from 'zustand';
22
import { persist } from 'zustand/middleware';
33
import i18n from '@/i18n';
4-
import {
5-
DEFAULT_MODEL,
6-
DEFAULT_PRO_MODEL,
7-
} from '../ai/providers/types';
4+
import { DEFAULT_MODEL } from '../ai/providers/types';
85
import type { ProviderConfig } from '../ai/providers/types';
96
import {
107
getModelCatalogEntry,
@@ -43,13 +40,13 @@ const LEGACY_MODEL_SUCCESSORS: Record<string, string> = {
4340
'gpt-5.4-mini': DEFAULT_MODEL,
4441
'gpt-4o': DEFAULT_MODEL,
4542
'gpt-4o-mini': DEFAULT_MODEL,
46-
'claude-opus-4-7': DEFAULT_PRO_MODEL,
47-
'claude-sonnet-4-6': DEFAULT_PRO_MODEL,
43+
'claude-opus-4-7': DEFAULT_MODEL,
44+
'claude-sonnet-4-6': DEFAULT_MODEL,
4845
'claude-haiku-4-5-20251001': DEFAULT_MODEL,
49-
'gemini-3.1-pro-preview': 'google/gemini-3.8-flash',
50-
'gemini-3.5-flash': 'google/gemini-3.8-flash',
51-
'gemini-3-flash-preview': 'google/gemini-3.8-flash',
52-
'gemini-3.1-flash-lite-preview': 'google/gemini-3.8-flash',
46+
'gemini-3.1-pro-preview': DEFAULT_MODEL,
47+
'gemini-3.5-flash': DEFAULT_MODEL,
48+
'gemini-3-flash-preview': DEFAULT_MODEL,
49+
'gemini-3.1-flash-lite-preview': DEFAULT_MODEL,
5350
};
5451

5552
const defaultConfig: ProviderConfig = {
@@ -109,6 +106,24 @@ function normalizeFeatureConfigs(configs: unknown, preserveLocalMock = false): R
109106
})) as Record<FeatureTab, ProviderConfig>;
110107
}
111108

109+
function featureConfigsAreCanonical(value: unknown, expected: Record<FeatureTab, ProviderConfig>): boolean {
110+
const saved = asRecord(value);
111+
const features = Object.keys(expected) as FeatureTab[];
112+
if (!saved || Object.keys(saved).length !== features.length) return false;
113+
114+
const allowedKeys = new Set(['provider', 'model', 'temperature', 'reasoningEffort']);
115+
return features.every((feature) => {
116+
const config = asRecord(saved[feature]);
117+
if (!config) return false;
118+
const target = expected[feature];
119+
return Object.keys(config).every((key) => allowedKeys.has(key))
120+
&& config.provider === target.provider
121+
&& config.model === target.model
122+
&& config.temperature === target.temperature
123+
&& config.reasoningEffort === target.reasoningEffort;
124+
});
125+
}
126+
112127
async function getUserId() {
113128
const { data } = await supabase.auth.getUser();
114129
return data.user?.id || null;
@@ -222,17 +237,30 @@ export const useSettingsStore = create<SettingsState>()(
222237
if (error || !data) return;
223238

224239
const mergedConfigs = normalizeFeatureConfigs(data.feature_configs);
240+
const configsNeedMigration = !featureConfigsAreCanonical(data.feature_configs, mergedConfigs);
225241

226242
const language = (data.language as 'en' | 'es' | 'hu') || 'en';
243+
const outputLanguage = (data.output_language as 'en' | 'es' | 'hu') || get().outputLanguage || 'en';
244+
const theme = (data.theme as 'light' | 'dark' | 'system') || 'system';
245+
const customSystemPrompt = data.custom_system_prompt || undefined;
227246
await i18n.changeLanguage(language);
228247
set({
229248
language,
230-
outputLanguage: (data.output_language as 'en' | 'es' | 'hu') || get().outputLanguage || 'en',
231-
theme: (data.theme as 'light' | 'dark' | 'system') || 'system',
249+
outputLanguage,
250+
theme,
232251
featureConfigs: mergedConfigs,
233-
customSystemPrompt: data.custom_system_prompt || undefined,
252+
customSystemPrompt,
234253
wikiResearchEnabled: get().wikiResearchEnabled,
235254
});
255+
if (configsNeedMigration) {
256+
await upsertSettings({
257+
language,
258+
output_language: outputLanguage,
259+
theme,
260+
feature_configs: mergedConfigs,
261+
custom_system_prompt: customSystemPrompt ?? null,
262+
});
263+
}
236264
},
237265
resetLocalData: () => {
238266
set({
@@ -247,6 +275,15 @@ export const useSettingsStore = create<SettingsState>()(
247275
}),
248276
{
249277
name: 'debate-trainer-settings',
278+
version: 1,
279+
migrate: (persistedState: unknown) => {
280+
const saved = asRecord(persistedState);
281+
if (!saved) return persistedState;
282+
return {
283+
...saved,
284+
featureConfigs: normalizeFeatureConfigs(saved.featureConfigs, true),
285+
};
286+
},
250287
onRehydrateStorage: () => (state) => {
251288
if (!state) return;
252289
state.featureConfigs = normalizeFeatureConfigs(state.featureConfigs, true);

‎src/locales/en.json‎

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,11 @@
408408
"recommended": "Recommended",
409409
"trialFeature1": "Starter AI prep access",
410410
"trialFeature2": "All 9 prep modes",
411-
"trialFeature3": "Basic models only",
411+
"trialFeature3": "GLM 5.3 Flash with low reasoning",
412412
"trialFeature4": "3-day access",
413413
"proFeature1": "Expanded AI prep access",
414414
"proFeature2": "All 9 prep modes",
415-
"proFeature3": "Premium models (GPT-5.5, Claude Opus, Gemini Pro)",
415+
"proFeature3": "GLM 5.3 Flash with high reasoning",
416416
"proFeature4": "Priority support",
417417
"proFeature5": "Active Grounding™ research",
418418
"startTrial": "Start Free Trial",
@@ -421,14 +421,14 @@
421421
"trialBadge": "New Users",
422422
"trialDesc": "Use the full workflow before deciding on Pro.",
423423
"proBadge": "Power Users",
424-
"proDesc": "For heavy prep weeks, tougher topics, and advanced model access."
424+
"proDesc": "For heavy prep weeks, tougher topics, and higher daily limits."
425425
},
426426
"faq": {
427427
"title": "Frequently Asked Questions",
428428
"q1": "How much does DebateLab cost?",
429-
"a1": "DebateLab offers a 3-day free trial. After that, Pro is $5/month + tax for expanded access and premium models.",
429+
"a1": "DebateLab offers a 3-day free trial. After that, Pro is $5/month + tax for expanded access and high-reasoning responses.",
430430
"q2": "What do I get with Pro?",
431-
"a2": "Expanded AI prep access, premium models (GPT-5.5, Claude Opus 4.7, Gemini 3.1 Pro), Active Grounding™ research, and priority support.",
431+
"a2": "Expanded AI prep access, high reasoning on GLM 5.3 Flash, Active Grounding™ research, and priority support.",
432432
"q3": "Can I cancel my subscription?",
433433
"a3": "Yes, you can cancel anytime from your Settings page. You'll retain access until the end of your billing period.",
434434
"q4": "Does the AI make things up?",
@@ -454,7 +454,7 @@
454454
"title": "What's New",
455455
"subtitle": "Latest updates and improvements.",
456456
"sub1Title": "Subscription Tiers",
457-
"sub1Desc": "Free trial and Pro plan with premium models.",
457+
"sub1Desc": "Free trial and Pro plan with higher usage limits.",
458458
"sub2Title": "Argument Flowcharts",
459459
"sub2Desc": "Visual argument mapping with drag-and-drop nodes.",
460460
"sub3Title": "Upgraded Timer",
@@ -817,20 +817,20 @@
817817
"trialEndedDesc": "Your 3-day free trial has ended. Upgrade to Pro to keep using DebateLab.",
818818
"limitReached": "Daily Access Paused",
819819
"limitReachedDesc": "You've used {{current}} of {{limit}} included AI uses today. Access refreshes at midnight UTC.",
820-
"upgrade": "Upgrade to Pro — $5/mo",
821-
"upgradeNote": "More AI prep access + advanced models"
820+
"upgrade": "Upgrade to Pro - $5/mo",
821+
"upgradeNote": "More AI prep access + high reasoning"
822822
},
823823
"modelModal": {
824-
"title": "Pro Model",
825-
"description": "This model is reserved for Pro members.",
826-
"descriptionWithModel": "{{model}} is reserved for Pro members.",
827-
"upgradeNote": "Upgrade to unlock advanced AI models.",
828-
"upgrade": "Upgrade to Pro — $5/mo",
829-
"useFree": "Use a free model instead"
824+
"title": "Pro Reasoning",
825+
"description": "High reasoning is reserved for Pro members.",
826+
"descriptionWithModel": "High reasoning with {{model}} is reserved for Pro members.",
827+
"upgradeNote": "Upgrade to unlock high reasoning.",
828+
"upgrade": "Upgrade to Pro - $5/mo",
829+
"useFree": "Use low reasoning instead"
830830
},
831831
"pricingModal": {
832832
"title": "Upgrade to Pro",
833-
"subtitle": "Unlock the full power of DebateLab with advanced AI models and expanded access.",
833+
"subtitle": "Unlock higher usage limits and high reasoning with GLM 5.3 Flash.",
834834
"free": "Free",
835835
"pro": "Pro",
836836
"current": "Current",
@@ -840,11 +840,11 @@
840840
"freePeriod": "/mo",
841841
"proPeriod": "/mo + tax",
842842
"freeFeature1": "Starter AI prep access",
843-
"freeFeature2": "Standard AI models",
843+
"freeFeature2": "GLM 5.3 Flash with low reasoning",
844844
"freeFeature3": "All debate features",
845845
"freeFeature4": "3-day free trial",
846846
"proFeature1": "Expanded AI prep access",
847-
"proFeature2": "Advanced models (GPT-5.5, Claude Opus 4.7, Gemini 3.1 Pro)",
847+
"proFeature2": "GLM 5.3 Flash with high reasoning",
848848
"proFeature3": "Deep research with Exa",
849849
"proFeature4": "Priority processing",
850850
"proFeature5": "All debate features",
@@ -1163,11 +1163,11 @@
11631163
"s2": "How We Use Your Information",
11641164
"p2": "Your information is used to provide and improve our services, generate AI responses, maintain your saved content, and communicate service updates.",
11651165
"s3": "AI Processing",
1166-
"p3": "Your inputs are sent to third-party AI providers (OpenAI, Anthropic, Google) for processing. We do not use your content to train AI models.",
1166+
"p3": "Your inputs are sent to OpenRouter for AI processing using GLM 5.3 Flash. We do not use your content to train AI models.",
11671167
"s4": "Data Storage",
1168-
"p4": "Your data is stored securely using Firebase/Google Cloud infrastructure with encryption at rest and in transit.",
1168+
"p4": "Your data is stored securely using Supabase infrastructure with encryption at rest and in transit.",
11691169
"s5": "Data Sharing",
1170-
"p5": "We do not sell your personal data. We share data only with AI providers for processing and payment processors for billing.",
1170+
"p5": "We do not sell your personal data. We share data only with OpenRouter for AI processing and payment processors for billing.",
11711171
"s6": "Your Rights",
11721172
"p6": "You may access, export, or delete your data at any time from your account settings. Account deletion removes all associated data.",
11731173
"s7": "Cookies and Tracking",

‎src/locales/es.json‎

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,11 @@
408408
"recommended": "Recomendado",
409409
"trialFeature1": "Acceso inicial a preparación con IA",
410410
"trialFeature2": "Los 9 modos de preparación",
411-
"trialFeature3": "Solo modelos básicos",
411+
"trialFeature3": "GLM 5.3 Flash con razonamiento bajo",
412412
"trialFeature4": "Acceso por 3 días",
413413
"proFeature1": "Acceso ampliado a preparación con IA",
414414
"proFeature2": "Los 9 modos de preparación",
415-
"proFeature3": "Modelos premium (GPT-5.5, Claude Opus, Gemini Pro)",
415+
"proFeature3": "GLM 5.3 Flash con razonamiento alto",
416416
"proFeature4": "Soporte prioritario",
417417
"proFeature5": "Investigación Active Grounding™",
418418
"startTrial": "Comenzar Prueba Gratis",
@@ -421,14 +421,14 @@
421421
"trialBadge": "Usuarios nuevos",
422422
"trialDesc": "Usa el flujo de trabajo completo antes de decidirte por Pro.",
423423
"proBadge": "Usuarios avanzados",
424-
"proDesc": "Para semanas de preparación intensiva, temas difíciles y acceso a modelos avanzados."
424+
"proDesc": "Para semanas de preparación intensiva, temas difíciles y límites diarios más altos."
425425
},
426426
"faq": {
427427
"title": "Preguntas Frecuentes",
428428
"q1": "¿Cuánto cuesta DebateLab?",
429-
"a1": "DebateLab ofrece una prueba gratis de 3 días. Después, Pro cuesta $5/mes + impuestos para acceso ampliado y modelos premium.",
429+
"a1": "DebateLab ofrece una prueba gratis de 3 días. Después, Pro cuesta $5/mes + impuestos para acceso ampliado y respuestas con razonamiento alto.",
430430
"q2": "¿Qué obtengo con Pro?",
431-
"a2": "Acceso ampliado a preparación con IA, modelos premium (GPT-5.5, Claude Opus 4.7, Gemini 3.1 Pro), investigación Active Grounding™ y soporte prioritario.",
431+
"a2": "Acceso ampliado a preparación con IA, razonamiento alto con GLM 5.3 Flash, investigación Active Grounding™ y soporte prioritario.",
432432
"q3": "¿Puedo cancelar mi suscripción?",
433433
"a3": "Sí, puedes cancelar en cualquier momento desde tu página de Ajustes. Mantendrás el acceso hasta el final de tu período de facturación.",
434434
"q4": "¿La IA inventa cosas?",
@@ -454,7 +454,7 @@
454454
"title": "Novedades",
455455
"subtitle": "Últimas actualizaciones y mejoras.",
456456
"sub1Title": "Niveles de Suscripción",
457-
"sub1Desc": "Prueba gratis y plan Pro con modelos premium.",
457+
"sub1Desc": "Prueba gratis y plan Pro con límites de uso más altos.",
458458
"sub2Title": "Diagramas de Argumentos",
459459
"sub2Desc": "Mapeo visual de argumentos con nodos arrastrables.",
460460
"sub3Title": "Cronómetro Mejorado",
@@ -817,20 +817,20 @@
817817
"trialEndedDesc": "Tu prueba gratuita de 3 días ha terminado. Actualiza a Pro para seguir usando DebateLab.",
818818
"limitReached": "Acceso diario pausado",
819819
"limitReachedDesc": "Has usado {{current}} de {{limit}} usos de IA incluidos hoy. El acceso se renueva a medianoche UTC.",
820-
"upgrade": "Actualizar a Pro — $5/mes",
821-
"upgradeNote": "Más acceso a preparación con IA + modelos avanzados"
820+
"upgrade": "Actualizar a Pro - $5/mes",
821+
"upgradeNote": "Más acceso a preparación con IA + razonamiento alto"
822822
},
823823
"modelModal": {
824-
"title": "Modelo Pro",
825-
"description": "Este modelo está reservado para miembros Pro.",
826-
"descriptionWithModel": "{{model}} está reservado para miembros Pro.",
827-
"upgradeNote": "Actualiza para desbloquear modelos avanzados de IA.",
828-
"upgrade": "Actualizar a Pro — $5/mes",
829-
"useFree": "Usar un modelo gratuito"
824+
"title": "Razonamiento Pro",
825+
"description": "El razonamiento alto está reservado para miembros Pro.",
826+
"descriptionWithModel": "El razonamiento alto con {{model}} está reservado para miembros Pro.",
827+
"upgradeNote": "Actualiza para desbloquear el razonamiento alto.",
828+
"upgrade": "Actualizar a Pro - $5/mes",
829+
"useFree": "Usar razonamiento bajo"
830830
},
831831
"pricingModal": {
832832
"title": "Actualizar a Pro",
833-
"subtitle": "Desbloquea todo el poder de DebateLab con modelos avanzados de IA y acceso ampliado.",
833+
"subtitle": "Desbloquea límites de uso más altos y razonamiento alto con GLM 5.3 Flash.",
834834
"free": "Gratis",
835835
"pro": "Pro",
836836
"current": "Actual",
@@ -840,11 +840,11 @@
840840
"freePeriod": "/mes",
841841
"proPeriod": "/mes + impuestos",
842842
"freeFeature1": "Acceso inicial a preparación con IA",
843-
"freeFeature2": "Modelos estándar de IA",
843+
"freeFeature2": "GLM 5.3 Flash con razonamiento bajo",
844844
"freeFeature3": "Todas las funciones de debate",
845845
"freeFeature4": "Prueba gratis de 3 días",
846846
"proFeature1": "Acceso ampliado a preparación con IA",
847-
"proFeature2": "Modelos avanzados (GPT-5.5, Claude Opus 4.7, Gemini 3.1 Pro)",
847+
"proFeature2": "GLM 5.3 Flash con razonamiento alto",
848848
"proFeature3": "Investigación profunda con Exa",
849849
"proFeature4": "Procesamiento prioritario",
850850
"proFeature5": "Todas las funciones de debate",
@@ -1163,11 +1163,11 @@
11631163
"s2": "Cómo Usamos Tu Información",
11641164
"p2": "Tu información se usa para proporcionar y mejorar nuestros servicios, generar respuestas de IA, mantener tu contenido guardado y comunicar actualizaciones.",
11651165
"s3": "Procesamiento de IA",
1166-
"p3": "Tus entradas se envían a proveedores de IA terceros (OpenAI, Anthropic, Google) para procesamiento. No usamos tu contenido para entrenar modelos de IA.",
1166+
"p3": "Tus entradas se envían a OpenRouter para el procesamiento de IA con GLM 5.3 Flash. No usamos tu contenido para entrenar modelos de IA.",
11671167
"s4": "Almacenamiento de Datos",
1168-
"p4": "Tus datos se almacenan de forma segura usando infraestructura Firebase/Google Cloud con cifrado en reposo y en tránsito.",
1168+
"p4": "Tus datos se almacenan de forma segura usando infraestructura de Supabase con cifrado en reposo y en tránsito.",
11691169
"s5": "Compartir Datos",
1170-
"p5": "No vendemos tus datos personales. Solo compartimos datos con proveedores de IA para procesamiento y procesadores de pago para facturación.",
1170+
"p5": "No vendemos tus datos personales. Solo compartimos datos con OpenRouter para el procesamiento de IA y con procesadores de pago para la facturación.",
11711171
"s6": "Tus Derechos",
11721172
"p6": "Puedes acceder, exportar o eliminar tus datos en cualquier momento desde la configuración de tu cuenta.",
11731173
"s7": "Cookies y Seguimiento",

0 commit comments

Comments
 (0)