Files
genesis-2/notebooks/background-openai.ipynb
T

26 KiB

import { load } from "jsr:@std/dotenv";
import OpenAI from "jsr:@openai/openai";

const env = await load({
    export: true,
});

const openai = new OpenAI();
import { createClient } from "@supabase/supabase-js";
const supabaseUrl = Deno.env.get("SUPABASE_URL") || env.SUPABASE_URL;
const supabaseKey = Deno.env.get("SUPABASE_ANON_KEY") || env.SUPABASE_ANON_KEY;
const supabase = createClient(supabaseUrl, supabaseKey);
const ID_ASIGNATURA = "fe5eb09c-501b-4db6-b6d3-f02bdcfdc4b4";
console.log(
  `Esperando a que la IA termine con la asignatura ${ID_ASIGNATURA}...`,
);

if (!supabase) {
  console.log("No hay supabase");
} else {
  // 2. Armas la "trampa" (el listener)
  await new Promise((resolve) => {
    const canal = supabase
      .channel("test-asignatura")
      .on(
        "postgres_changes",
        {
          event: "UPDATE",
          schema: "public",
          table: "asignaturas",
          filter: `id=eq.${ID_ASIGNATURA}`,
        },
        (payload) => {
          const nuevoEstado = payload.new.estado;

          if (nuevoEstado !== "generando") {
            console.log(
              `¡Proceso completado! El nuevo estado es: ${nuevoEstado}`,
            );

            supabase.removeChannel(canal);
            resolve(true); // ¡Aquí destrabamos la celda de Jupyter!
          } else {
            console.log("Hubo un update, pero sigue generando...");
          }
        },
      )
      .subscribe((status) => {
        if (status === "SUBSCRIBED") {
          console.log(
            "Conexión WebSocket establecida. La celda está esperando cambios...",
          );
        }
      });
  });

  console.log("Script finalizado correctamente.");
}
Esperando a que la IA termine con la asignatura fe5eb09c-501b-4db6-b6d3-f02bdcfdc4b4...
Conexión WebSocket establecida. La celda está esperando cambios...
The Kernel crashed while executing code in the current cell or a previous cell. 

Please review the code in the cell(s) to identify a possible cause of the failure. 

Click <a href='https://aka.ms/vscodeJupyterKernelCrash'>here</a> for more info. 

View Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details.
console.log(`Iniciando conexión abierta y sin filtros...`);

await new Promise((resolve) => {
  const canal = supabase
    .channel("test-global-asignaturas")
    .on(
      "postgres_changes",
      {
        event: "*", // Escuchamos absolutamente TODO
        schema: "public",
        table: "asignaturas",
      },
      (payload) => {
        // Imprimimos todo el objeto tal como llega del servidor
        console.log("🚨 ¡EVENTO RECIBIDO EN CRUDO!", payload);

        // Cerramos la conexión para liberar la celda
        supabase.removeChannel(canal);
        resolve(true);
      },
    )
    .subscribe((status, err) => {
      if (status === "SUBSCRIBED") {
        console.log(
          "Conectado. Esperando cualquier cambio en la tabla asignaturas...",
        );
      }
      if (err) {
        console.error("Error en el socket:", err);
      }
    });
});

console.log("Script finalizado.");
Iniciando conexión abierta y sin filtros...
Conectado. Esperando cualquier cambio en la tabla asignaturas...
The Kernel crashed while executing code in the current cell or a previous cell. 

Please review the code in the cell(s) to identify a possible cause of the failure. 

Click <a href='https://aka.ms/vscodeJupyterKernelCrash'>here</a> for more info. 

View Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details.
import("https://esm.sh/@supabase/supabase-js").then(({ createClient }) => {
    const supabase = createClient(
        "https://bxkskdxwppdlplrkidcz.supabase.co",
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJ4a3NrZHh3cHBkbHBscmtpZGN6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzIwMzU2NDMsImV4cCI6MjA4NzYxMTY0M30.RIyvmB8Ij_qrsiMn0f65awiG5VaCUA5dvb117wuU3jo",
    );

    supabase.channel("prueba-consola")
        .on("postgres_changes", {
            event: "*",
            schema: "public",
            table: "asignaturas",
        }, (payload) => {
            console.log("🔥 ¡LLEGÓ EL EVENTO DESDE SUPABASE!", payload);
        })
        .subscribe((status) => console.log("Estado de la conexión:", status));
});
// plan Crear un plan en la base (sin datos) estado generando
const { data: plan, error } = await supabase.from("planes_estudio").insert({
    "carrera_id": "8208da08-d549-4359-8865-9d806bc54f19",
    "estructura_id": "69fb2b77-5a95-47e0-bf1f-389d384200e4",
    "estado_actual_id": "18f49b67-8077-4371-be6e-2019a3be3562",
    "nombre": "Ingeniearía en Cifbernética y Ciberseguridad (2025)",
    "nivel": "Doctorado",
    "tipo_ciclo": "Semestre",
    "numero_ciclos": 8,
    "activo": true,
    "tipo_origen": "IA",
    "creado_por": "11111111-1111-1111-1111-111111111111",
    "actualizado_por": "11111111-1111-1111-1111-111111111111",
}).select("*").single();
plan.id;
{
  message: "TypeError: error sending request for url (http://127.0.0.1:54321/rest/v1/planes_estudio?select=*): client error (Connect): tcp connect error: No se puede establecer una conexión ya que el equipo de destino denegó expresamente dicha conexión. (os error 10061)",
  details: "TypeError: error sending request for url (http://127.0.0.1:54321/rest/v1/planes_estudio?select=*): client error (Connect): tcp connect error: No se puede establecer una conexión ya que el equipo de destino denegó expresamente dicha conexión. (os error 10061)\n" +
    "    at async mainFetch (ext:deno_fetch/26_fetch.js:192:12)\n" +
    "    at async fetch (ext:deno_fetch/26_fetch.js:475:11)\n" +
    "    at async <anonymous>:2:31",
  hint: "",
  code: ""
}
let response = await openai.responses.create({
    model: "gpt-5-mini",
    input: "Hola mundo",
    metadata: {
        tabla: "planes_estudio",
        id: '2',
    },
    text: {
        format: {
            type: "json_schema",
            name: "response_schema",
            schema: {
                type: "object",
                properties: {
                    "ai-message": {
                        type: "string",
                        description:
                            "Un mensaje de texto que la IA generará para el usuario final. Este mensaje debe ser claro y directo, proporcionando la información solicitada por el usuario o indicando que no se puede procesar la solicitud si no está relacionada con planes de estudio o asignaturas.",
                    },
                    "suggested-topic": {
                        type: "string",
                        description:
                            "Un tema de investigación sugerido por la IA que sea relevante para el plan de estudio o asignatura mencionada en la solicitud del usuario. Este tema debe ser específico y relacionado con el área de estudio correspondiente.",
                    },
                },
                required: ["ai-message", "suggested-topic"],
                additionalProperties: false,
            },
        },
    },
    background: true,
});

response;
{
  id: "resp_0ae72cbd0894279200699c8e42941c8192ba4a09e280b21a17",
  object: "response",
  created_at: 1771867714,
  status: "queued",
  background: true,
  completed_at: null,
  error: null,
  frequency_penalty: 0,
  incomplete_details: null,
  instructions: null,
  max_output_tokens: null,
  max_tool_calls: null,
  model: "gpt-5-mini-2025-08-07",
  output: [],
  parallel_tool_calls: true,
  presence_penalty: 0,
  previous_response_id: null,
  prompt_cache_key: null,
  prompt_cache_retention: null,
  reasoning: { effort: "medium", summary: null },
  safety_identifier: null,
  service_tier: "auto",
  store: true,
  temperature: 1,
  text: {
    format: {
      type: "json_schema",
      description: null,
      name: "response_schema",
      schema: {
        type: "object",
        properties: { "ai-message": [Object], "suggested-topic": [Object] },
        required: [ "ai-message", "suggested-topic" ],
        additionalProperties: false
      },
      strict: true
    },
    verbosity: "medium"
  },
  tool_choice: "auto",
  tools: [],
  top_logprobs: 0,
  top_p: 1,
  truncation: "disabled",
  usage: null,
  user: null,
  metadata: { tabla: "planes_estudio", id: "2" },
  output_text: ""
}
while (response.status === "queued" || response.status === "in_progress") {
    console.log("Current status: " + response.status);
    await new Promise((resolve) => setTimeout(resolve, 2000)); // wait 2 seconds
    response = await openai.responses.retrieve(response.id);
}

response;
Current status: queued
Current status: in_progress
Current status: in_progress
{
  id: "resp_0ae72cbd0894279200699c8e42941c8192ba4a09e280b21a17",
  object: "response",
  created_at: 1771867714,
  status: "completed",
  background: true,
  billing: { payer: "developer" },
  completed_at: 1771867721,
  error: null,
  frequency_penalty: 0,
  incomplete_details: null,
  instructions: null,
  max_output_tokens: null,
  max_tool_calls: null,
  model: "gpt-5-mini-2025-08-07",
  output: [
    {
      id: "rs_0ae72cbd0894279200699c8e43cd4c8192bcbc70792b6aa621",
      type: "reasoning",
      summary: []
    },
    {
      id: "msg_0ae72cbd0894279200699c8e48976481928e1f205210636717",
      type: "message",
      status: "completed",
      content: [
        {
          type: "output_text",
          annotations: [],
          logprobs: [],
          text: '{"ai-message":"¡Hola! ¿En qué puedo ayudarte hoy? Puedo mostrar ejemplos de \\"Hola mundo\\" en distintos lenguajes, explicar conceptos de programación, ayudar con una tarea o sugerir recursos. Dime qué prefieres.","suggested-topic":"El papel del programa \\"Hola Mundo\\" en la enseñanza de la programación: comparación práctica entre Python, Java y C (sintaxis, tiempo de arranque, facilidad de aprendizaje y percepción del estudiante)."}'
        }
      ],
      role: "assistant"
    }
  ],
  parallel_tool_calls: true,
  presence_penalty: 0,
  previous_response_id: null,
  prompt_cache_key: null,
  prompt_cache_retention: null,
  reasoning: { effort: "medium", summary: null },
  safety_identifier: null,
  service_tier: "default",
  store: true,
  temperature: 1,
  text: {
    format: {
      type: "json_schema",
      description: null,
      name: "response_schema",
      schema: {
        type: "object",
        properties: { "ai-message": [Object], "suggested-topic": [Object] },
        required: [ "ai-message", "suggested-topic" ],
        additionalProperties: false
      },
      strict: true
    },
    verbosity: "medium"
  },
  tool_choice: "auto",
  tools: [],
  top_logprobs: 0,
  top_p: 1,
  truncation: "disabled",
  usage: {
    input_tokens: 167,
    input_tokens_details: { cached_tokens: 0 },
    output_tokens: 482,
    output_tokens_details: { reasoning_tokens: 320 },
    total_tokens: 649
  },
  user: null,
  metadata: { tabla: "planes_estudio", id: "2" },
  output_text: '{"ai-message":"¡Hola! ¿En qué puedo ayudarte hoy? Puedo mostrar ejemplos de \\"Hola mundo\\" en distintos lenguajes, explicar conceptos de programación, ayudar con una tarea o sugerir recursos. Dime qué prefieres.","suggested-topic":"El papel del programa \\"Hola Mundo\\" en la enseñanza de la programación: comparación práctica entre Python, Java y C (sintaxis, tiempo de arranque, facilidad de aprendizaje y percepción del estudiante)."}'
}
response.metadata;
{ tabla: "planes_estudio", id: "e39952c1-a53b-43bf-8033-feda493a0651" }
await supabase.from(response.metadata.tabla).update({
    datos: JSON.parse(response.output_text),
}).eq("id", response.metadata.id).select("*").single();
{
  error: null,
  data: {
    id: "e39952c1-a53b-43bf-8033-feda493a0651",
    carrera_id: "8208da08-d549-4359-8865-9d806bc54f19",
    estructura_id: "69fb2b77-5a95-47e0-bf1f-389d384200e4",
    nombre: "Ingeniearía en Cifbernética y Ciberseguridad (2025)",
    nivel: "Doctorado",
    tipo_ciclo: "Semestre",
    numero_ciclos: 8,
    datos: {
      "ai-message": "¡Hola! ¿Cómo puedo ayudarte hoy? Si te refieres al clásico “Hola mundo” en programación, puedo mostrarte ejemplos en varios lenguajes, explicar su historia o ayudarte a crear tu primer programa. ¿Qué prefieres?",
      "suggested-topic": "El uso del programa “Hola mundo” como herramienta pedagógica en la enseñanza de la programación: impacto en la comprensión inicial, variaciones por lenguaje y mejores prácticas didácticas."
    },
    estado_actual_id: "18f49b67-8077-4371-be6e-2019a3be3562",
    activo: true,
    tipo_origen: "IA",
    meta_origen: {},
    creado_por: "11111111-1111-1111-1111-111111111111",
    actualizado_por: "11111111-1111-1111-1111-111111111111",
    creado_en: "2026-02-20T17:11:28.995222+00:00",
    actualizado_en: "2026-02-20T17:12:40.170995+00:00",
    nombre_search: "ingeniearia en cifbernetica y ciberseguridad (2025)",
    plan_hash: "70d28457bbddfe4f5cde0574"
  },
  count: null,
  status: 200,
  statusText: "OK"
}