diff --git a/supabase/functions/ai-generate-plan/index.ts b/supabase/functions/ai-generate-plan/index.ts index 1db2eef..f370b75 100644 --- a/supabase/functions/ai-generate-plan/index.ts +++ b/supabase/functions/ai-generate-plan/index.ts @@ -118,6 +118,10 @@ Deno.serve(async (req: Request): Promise => { SERVICE_ROLE_KEY, ); + // Model name controlled via env var (single use) + const AI_GENERATE_PLAN_MODELO = Deno.env.get("AI_GENERATE_PLAN_MODELO") ?? + "gpt-5-nano"; + const formData = await req.formData(); const validation = parseAndValidate(formData); if (!validation.success) { @@ -185,7 +189,7 @@ Deno.serve(async (req: Request): Promise => { : {}; const aiStructuredPayload: StructuredResponseOptions = { - model: "gpt-5-nano", + model: AI_GENERATE_PLAN_MODELO, input: [ { role: "system", content: systemPrompt }, { role: "user", content: userPrompt }, diff --git a/supabase/functions/ai-generate-plan/prompts.ts b/supabase/functions/ai-generate-plan/prompts.ts index 399378b..b1dd913 100644 --- a/supabase/functions/ai-generate-plan/prompts.ts +++ b/supabase/functions/ai-generate-plan/prompts.ts @@ -34,4 +34,13 @@ Antes de ejecutar el trabajo, comienza con una lista concisa (3-7 puntos) de los # Validación de Salida Después de generar el objeto, realiza una validación breve para asegurar que todos los campos requeridos estén presentes, que los valores cumplan los criterios normativos y que la estructura cumpla con el json_schema indicado. -Corrige cualquier inconsistencia detectada antes de finalizar la entrega.`; +Corrige cualquier inconsistencia detectada antes de finalizar la entrega. + +# REGLAS DE FORMATO PARA CAMPOS DE TEXTO (STRING) +1. **Prioridad:** Estas reglas aplican por defecto. Si el prompt del usuario solicita explícitamente un formato distinto, esa instrucción tiene prioridad sobre estas reglas. +2. **Estilo Visual:** Redacta el contenido exclusivamente para visualización en texto plano (estilo 'white-space: pre-wrap'). +3. **Estructura Vertical:** Utiliza saltos de línea explícitos para romper líneas y doble salto de línea para separar párrafos. +4. **Indentación Estricta:** Usa exactamente 2 espacios para la indentación jerárquica. No uses tabuladores. +5. **Listas:** Utiliza un guion seguido de un espacio ("- ") para los elementos de lista. +6. **Prohibiciones:** No incluyas etiquetas HTML, sintaxis Markdown ni caracteres de escape literales visibles en el texto final. +`; diff --git a/supabase/functions/ai-generate-subject/index.ts b/supabase/functions/ai-generate-subject/index.ts index 972ca2c..7ab9f53 100644 --- a/supabase/functions/ai-generate-subject/index.ts +++ b/supabase/functions/ai-generate-subject/index.ts @@ -170,6 +170,14 @@ Deno.serve(async (req: Request): Promise => { SERVICE_ROLE_KEY, ); + // Model names (override via environment variables) + const AI_GENERATE_SUBJECT_UPDATE_MODELO = Deno.env.get( + "AI_GENERATE_SUBJECT_UPDATE_MODELO", + ) ?? "gpt-5-nano"; + const AI_GENERATE_SUBJECT_INSERT_MODELO = Deno.env.get( + "AI_GENERATE_SUBJECT_INSERT_MODELO", + ) ?? "gpt-5-nano"; + // ----------------------------- // JSON update flow // ----------------------------- @@ -307,7 +315,7 @@ Deno.serve(async (req: Request): Promise => { : {}; const aiStructuredPayload: StructuredResponseOptions = { - model: "gpt-5-nano", + model: AI_GENERATE_SUBJECT_UPDATE_MODELO, input: [ { role: "system", content: systemPrompt }, { role: "user", content: userPrompt }, @@ -510,7 +518,14 @@ Deno.serve(async (req: Request): Promise => { } const systemPrompt = - "Eres un asistente experto en diseño curricular. Responde únicamente con JSON válido que cumpla estrictamente el JSON Schema proporcionado."; + `Eres un asistente experto en diseño curricular. Responde únicamente con JSON válido que cumpla estrictamente el JSON Schema proporcionado. + # REGLAS DE FORMATO PARA CAMPOS DE TEXTO (STRING) +1. **Prioridad:** Estas reglas aplican por defecto. Si el prompt del usuario solicita explícitamente un formato distinto, esa instrucción tiene prioridad sobre estas reglas. +2. **Estilo Visual:** Redacta el contenido exclusivamente para visualización en texto plano (estilo 'white-space: pre-wrap'). +3. **Estructura Vertical:** Utiliza saltos de línea explícitos para romper líneas y doble salto de línea para separar párrafos. +4. **Indentación Estricta:** Usa exactamente 2 espacios para la indentación jerárquica. No uses tabuladores. +5. **Listas:** Utiliza un guion seguido de un espacio ("- ") para los elementos de lista. +6. **Prohibiciones:** No incluyas etiquetas HTML, sintaxis Markdown ni caracteres de escape literales visibles en el texto final.`; const userPrompt = `Genera un borrador completo completo de una ASIGNATURA con base en lo siguiente:\n` + @@ -540,7 +555,7 @@ Deno.serve(async (req: Request): Promise => { : {}; const aiStructuredPayload: StructuredResponseOptions = { - model: "gpt-5-nano", + model: AI_GENERATE_SUBJECT_INSERT_MODELO, input: [ { role: "system", content: systemPrompt }, { role: "user", content: userPrompt }, diff --git a/supabase/functions/create-chat-conversation/index.ts b/supabase/functions/create-chat-conversation/index.ts index cbb3572..f06bc58 100644 --- a/supabase/functions/create-chat-conversation/index.ts +++ b/supabase/functions/create-chat-conversation/index.ts @@ -29,6 +29,13 @@ app.options( ); const prefix = "/create-chat-conversation"; +// Model names (module-level) — pueden ser sobrescritos por variables de entorno +const CREATE_CHAT_CONVERSATION_NONSTRUCTURED_MODELO = Deno.env.get( + "CREATE_CHAT_CONVERSATION_NONSTRUCTURED_MODELO", +) ?? "gpt-5-nano"; +const CREATE_CHAT_CONVERSATION_STRUCTURED_MODELO = Deno.env.get( + "CREATE_CHAT_CONVERSATION_STRUCTURED_MODELO", +) ?? "gpt-5-nano"; app.get(`${prefix}/health`, (c) => withCors(jsonResponse({ ok: true }))); @@ -241,7 +248,7 @@ app.post(`${prefix}/conversations/:id/messages`, async (c) => { if (!wantsStructured) { await openai.responses.create({ conversation: row.openai_conversation_id, - model: "gpt-5-nano", + model: CREATE_CHAT_CONVERSATION_NONSTRUCTURED_MODELO, input: [ { role: "system", @@ -284,7 +291,7 @@ app.post(`${prefix}/conversations/:id/messages`, async (c) => { const schema = pickSchemaFields(definicion, body.campos); const planForPrompt = safePlanForPrompt(plan); - const model = "gpt-5-nano"; + const model = CREATE_CHAT_CONVERSATION_STRUCTURED_MODELO; const prompt = body.user_prompt ?? body.content; const resp = await openai.responses.create({ diff --git a/supabase/functions/generate-subject-suggestions/index.ts b/supabase/functions/generate-subject-suggestions/index.ts index 027ab06..a6f1eb5 100644 --- a/supabase/functions/generate-subject-suggestions/index.ts +++ b/supabase/functions/generate-subject-suggestions/index.ts @@ -160,6 +160,11 @@ Deno.serve(async (req: Request): Promise => { SERVICE_ROLE_KEY, ); + // Model name controlled via env var + const GENERATE_SUBJECT_SUGGESTIONS_MODELO = Deno.env.get( + "GENERATE_SUBJECT_SUGGESTIONS_MODELO", + ) ?? "gpt-5-mini"; + const { data: plan, error: planError } = await supabaseService .from("planes_estudio") .select("id,nombre,nivel,tipo_ciclo,numero_ciclos,datos") @@ -276,7 +281,7 @@ Deno.serve(async (req: Request): Promise => { } const options: StructuredResponseOptions = { - model: "gpt-5-mini", + model: GENERATE_SUBJECT_SUGGESTIONS_MODELO, input: [ { role: "system", content: systemPrompt }, {