{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "bb61ec88",
      "metadata": {},
      "outputs": [],
      "source": [
        "import { load } from \"jsr:@std/dotenv\";\n",
        "import OpenAI from \"jsr:@openai/openai\";\n",
        "\n",
        "const env = await load({\n",
        "    export: true,\n",
        "});\n",
        "\n",
        "const openai = new OpenAI();\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "8baca5f2",
      "metadata": {},
      "outputs": [],
      "source": [
        "import { createClient } from \"@supabase/supabase-js\";\n",
        "const supabaseUrl = Deno.env.get(\"SUPABASE_URL\") || env.SUPABASE_URL;\n",
        "const supabaseKey = Deno.env.get(\"SUPABASE_ANON_KEY\") || env.SUPABASE_ANON_KEY;\n",
        "const supabase = createClient(supabaseUrl, supabaseKey);\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "923b8e08",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Esperando a que la IA termine con la asignatura fe5eb09c-501b-4db6-b6d3-f02bdcfdc4b4...\n",
            "Conexión WebSocket establecida. La celda está esperando cambios...\n"
          ]
        },
        {
          "ename": "",
          "evalue": "",
          "output_type": "error",
          "traceback": [
            "\u001b[1;31mThe Kernel crashed while executing code in the current cell or a previous cell. \n",
            "\u001b[1;31mPlease review the code in the cell(s) to identify a possible cause of the failure. \n",
            "\u001b[1;31mClick <a href='https://aka.ms/vscodeJupyterKernelCrash'>here</a> for more info. \n",
            "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details."
          ]
        }
      ],
      "source": [
        "const ID_ASIGNATURA = \"fe5eb09c-501b-4db6-b6d3-f02bdcfdc4b4\";\n",
        "console.log(\n",
        "  `Esperando a que la IA termine con la asignatura ${ID_ASIGNATURA}...`,\n",
        ");\n",
        "\n",
        "if (!supabase) {\n",
        "  console.log(\"No hay supabase\");\n",
        "} else {\n",
        "  // 2. Armas la \"trampa\" (el listener)\n",
        "  await new Promise((resolve) => {\n",
        "    const canal = supabase\n",
        "      .channel(\"test-asignatura\")\n",
        "      .on(\n",
        "        \"postgres_changes\",\n",
        "        {\n",
        "          event: \"UPDATE\",\n",
        "          schema: \"public\",\n",
        "          table: \"asignaturas\",\n",
        "          filter: `id=eq.${ID_ASIGNATURA}`,\n",
        "        },\n",
        "        (payload) => {\n",
        "          const nuevoEstado = payload.new.estado;\n",
        "\n",
        "          if (nuevoEstado !== \"generando\") {\n",
        "            console.log(\n",
        "              `¡Proceso completado! El nuevo estado es: ${nuevoEstado}`,\n",
        "            );\n",
        "\n",
        "            supabase.removeChannel(canal);\n",
        "            resolve(true); // ¡Aquí destrabamos la celda de Jupyter!\n",
        "          } else {\n",
        "            console.log(\"Hubo un update, pero sigue generando...\");\n",
        "          }\n",
        "        },\n",
        "      )\n",
        "      .subscribe((status) => {\n",
        "        if (status === \"SUBSCRIBED\") {\n",
        "          console.log(\n",
        "            \"Conexión WebSocket establecida. La celda está esperando cambios...\",\n",
        "          );\n",
        "        }\n",
        "      });\n",
        "  });\n",
        "\n",
        "  console.log(\"Script finalizado correctamente.\");\n",
        "}\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "8a1509d8",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Iniciando conexión abierta y sin filtros...\n",
            "Conectado. Esperando cualquier cambio en la tabla asignaturas...\n"
          ]
        },
        {
          "ename": "",
          "evalue": "",
          "output_type": "error",
          "traceback": [
            "\u001b[1;31mThe Kernel crashed while executing code in the current cell or a previous cell. \n",
            "\u001b[1;31mPlease review the code in the cell(s) to identify a possible cause of the failure. \n",
            "\u001b[1;31mClick <a href='https://aka.ms/vscodeJupyterKernelCrash'>here</a> for more info. \n",
            "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details."
          ]
        }
      ],
      "source": [
        "console.log(`Iniciando conexión abierta y sin filtros...`);\n",
        "\n",
        "await new Promise((resolve) => {\n",
        "  const canal = supabase\n",
        "    .channel(\"test-global-asignaturas\")\n",
        "    .on(\n",
        "      \"postgres_changes\",\n",
        "      {\n",
        "        event: \"*\", // Escuchamos absolutamente TODO\n",
        "        schema: \"public\",\n",
        "        table: \"asignaturas\",\n",
        "      },\n",
        "      (payload) => {\n",
        "        // Imprimimos todo el objeto tal como llega del servidor\n",
        "        console.log(\"🚨 ¡EVENTO RECIBIDO EN CRUDO!\", payload);\n",
        "\n",
        "        // Cerramos la conexión para liberar la celda\n",
        "        supabase.removeChannel(canal);\n",
        "        resolve(true);\n",
        "      },\n",
        "    )\n",
        "    .subscribe((status, err) => {\n",
        "      if (status === \"SUBSCRIBED\") {\n",
        "        console.log(\n",
        "          \"Conectado. Esperando cualquier cambio en la tabla asignaturas...\",\n",
        "        );\n",
        "      }\n",
        "      if (err) {\n",
        "        console.error(\"Error en el socket:\", err);\n",
        "      }\n",
        "    });\n",
        "});\n",
        "\n",
        "console.log(\"Script finalizado.\");\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "3602b930",
      "metadata": {},
      "outputs": [],
      "source": [
        "import(\"https://esm.sh/@supabase/supabase-js\").then(({ createClient }) => {\n",
        "    const supabase = createClient(\n",
        "        \"https://bxkskdxwppdlplrkidcz.supabase.co\",\n",
        "        \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJ4a3NrZHh3cHBkbHBscmtpZGN6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzIwMzU2NDMsImV4cCI6MjA4NzYxMTY0M30.RIyvmB8Ij_qrsiMn0f65awiG5VaCUA5dvb117wuU3jo\",\n",
        "    );\n",
        "\n",
        "    supabase.channel(\"prueba-consola\")\n",
        "        .on(\"postgres_changes\", {\n",
        "            event: \"*\",\n",
        "            schema: \"public\",\n",
        "            table: \"asignaturas\",\n",
        "        }, (payload) => {\n",
        "            console.log(\"🔥 ¡LLEGÓ EL EVENTO DESDE SUPABASE!\", payload);\n",
        "        })\n",
        "        .subscribe((status) => console.log(\"Estado de la conexión:\", status));\n",
        "});\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "26b3bb36",
      "metadata": {},
      "outputs": [],
      "source": [
        "// plan Crear un plan en la base (sin datos) estado generando\n",
        "const { data: plan, error } = await supabase.from(\"planes_estudio\").insert({\n",
        "    \"carrera_id\": \"8208da08-d549-4359-8865-9d806bc54f19\",\n",
        "    \"estructura_id\": \"69fb2b77-5a95-47e0-bf1f-389d384200e4\",\n",
        "    \"estado_actual_id\": \"18f49b67-8077-4371-be6e-2019a3be3562\",\n",
        "    \"nombre\": \"Ingeniearía en Cifbernética y Ciberseguridad (2025)\",\n",
        "    \"nivel\": \"Doctorado\",\n",
        "    \"tipo_ciclo\": \"Semestre\",\n",
        "    \"numero_ciclos\": 8,\n",
        "    \"activo\": true,\n",
        "    \"tipo_origen\": \"IA\",\n",
        "    \"creado_por\": \"11111111-1111-1111-1111-111111111111\",\n",
        "    \"actualizado_por\": \"11111111-1111-1111-1111-111111111111\",\n",
        "}).select(\"*\").single();\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "8abb080e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{\n",
              "  message: \u001b[32m\"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)\"\u001b[39m,\n",
              "  details: \u001b[32m\"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\"\u001b[39m +\n",
              "    \u001b[32m\"    at async mainFetch (ext:deno_fetch/26_fetch.js:192:12)\\n\"\u001b[39m +\n",
              "    \u001b[32m\"    at async fetch (ext:deno_fetch/26_fetch.js:475:11)\\n\"\u001b[39m +\n",
              "    \u001b[32m\"    at async <anonymous>:2:31\"\u001b[39m,\n",
              "  hint: \u001b[32m\"\"\u001b[39m,\n",
              "  code: \u001b[32m\"\"\u001b[39m\n",
              "}"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "plan.id;\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "a382bdc6",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{\n",
              "  id: \u001b[32m\"resp_0ae72cbd0894279200699c8e42941c8192ba4a09e280b21a17\"\u001b[39m,\n",
              "  object: \u001b[32m\"response\"\u001b[39m,\n",
              "  created_at: \u001b[33m1771867714\u001b[39m,\n",
              "  status: \u001b[32m\"queued\"\u001b[39m,\n",
              "  background: \u001b[33mtrue\u001b[39m,\n",
              "  completed_at: \u001b[1mnull\u001b[22m,\n",
              "  error: \u001b[1mnull\u001b[22m,\n",
              "  frequency_penalty: \u001b[33m0\u001b[39m,\n",
              "  incomplete_details: \u001b[1mnull\u001b[22m,\n",
              "  instructions: \u001b[1mnull\u001b[22m,\n",
              "  max_output_tokens: \u001b[1mnull\u001b[22m,\n",
              "  max_tool_calls: \u001b[1mnull\u001b[22m,\n",
              "  model: \u001b[32m\"gpt-5-mini-2025-08-07\"\u001b[39m,\n",
              "  output: [],\n",
              "  parallel_tool_calls: \u001b[33mtrue\u001b[39m,\n",
              "  presence_penalty: \u001b[33m0\u001b[39m,\n",
              "  previous_response_id: \u001b[1mnull\u001b[22m,\n",
              "  prompt_cache_key: \u001b[1mnull\u001b[22m,\n",
              "  prompt_cache_retention: \u001b[1mnull\u001b[22m,\n",
              "  reasoning: { effort: \u001b[32m\"medium\"\u001b[39m, summary: \u001b[1mnull\u001b[22m },\n",
              "  safety_identifier: \u001b[1mnull\u001b[22m,\n",
              "  service_tier: \u001b[32m\"auto\"\u001b[39m,\n",
              "  store: \u001b[33mtrue\u001b[39m,\n",
              "  temperature: \u001b[33m1\u001b[39m,\n",
              "  text: {\n",
              "    format: {\n",
              "      type: \u001b[32m\"json_schema\"\u001b[39m,\n",
              "      description: \u001b[1mnull\u001b[22m,\n",
              "      name: \u001b[32m\"response_schema\"\u001b[39m,\n",
              "      schema: {\n",
              "        type: \u001b[32m\"object\"\u001b[39m,\n",
              "        properties: { \u001b[32m\"ai-message\"\u001b[39m: \u001b[36m[Object]\u001b[39m, \u001b[32m\"suggested-topic\"\u001b[39m: \u001b[36m[Object]\u001b[39m },\n",
              "        required: [ \u001b[32m\"ai-message\"\u001b[39m, \u001b[32m\"suggested-topic\"\u001b[39m ],\n",
              "        additionalProperties: \u001b[33mfalse\u001b[39m\n",
              "      },\n",
              "      strict: \u001b[33mtrue\u001b[39m\n",
              "    },\n",
              "    verbosity: \u001b[32m\"medium\"\u001b[39m\n",
              "  },\n",
              "  tool_choice: \u001b[32m\"auto\"\u001b[39m,\n",
              "  tools: [],\n",
              "  top_logprobs: \u001b[33m0\u001b[39m,\n",
              "  top_p: \u001b[33m1\u001b[39m,\n",
              "  truncation: \u001b[32m\"disabled\"\u001b[39m,\n",
              "  usage: \u001b[1mnull\u001b[22m,\n",
              "  user: \u001b[1mnull\u001b[22m,\n",
              "  metadata: { tabla: \u001b[32m\"planes_estudio\"\u001b[39m, id: \u001b[32m\"2\"\u001b[39m },\n",
              "  output_text: \u001b[32m\"\"\u001b[39m\n",
              "}"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "let response = await openai.responses.create({\n",
        "    model: \"gpt-5-mini\",\n",
        "    input: \"Hola mundo\",\n",
        "    metadata: {\n",
        "        tabla: \"planes_estudio\",\n",
        "        id: '2',\n",
        "    },\n",
        "    text: {\n",
        "        format: {\n",
        "            type: \"json_schema\",\n",
        "            name: \"response_schema\",\n",
        "            schema: {\n",
        "                type: \"object\",\n",
        "                properties: {\n",
        "                    \"ai-message\": {\n",
        "                        type: \"string\",\n",
        "                        description:\n",
        "                            \"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.\",\n",
        "                    },\n",
        "                    \"suggested-topic\": {\n",
        "                        type: \"string\",\n",
        "                        description:\n",
        "                            \"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.\",\n",
        "                    },\n",
        "                },\n",
        "                required: [\"ai-message\", \"suggested-topic\"],\n",
        "                additionalProperties: false,\n",
        "            },\n",
        "        },\n",
        "    },\n",
        "    background: true,\n",
        "});\n",
        "\n",
        "response;\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "6b2470ed",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Current status: queued\n",
            "Current status: in_progress\n",
            "Current status: in_progress\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "{\n",
              "  id: \u001b[32m\"resp_0ae72cbd0894279200699c8e42941c8192ba4a09e280b21a17\"\u001b[39m,\n",
              "  object: \u001b[32m\"response\"\u001b[39m,\n",
              "  created_at: \u001b[33m1771867714\u001b[39m,\n",
              "  status: \u001b[32m\"completed\"\u001b[39m,\n",
              "  background: \u001b[33mtrue\u001b[39m,\n",
              "  billing: { payer: \u001b[32m\"developer\"\u001b[39m },\n",
              "  completed_at: \u001b[33m1771867721\u001b[39m,\n",
              "  error: \u001b[1mnull\u001b[22m,\n",
              "  frequency_penalty: \u001b[33m0\u001b[39m,\n",
              "  incomplete_details: \u001b[1mnull\u001b[22m,\n",
              "  instructions: \u001b[1mnull\u001b[22m,\n",
              "  max_output_tokens: \u001b[1mnull\u001b[22m,\n",
              "  max_tool_calls: \u001b[1mnull\u001b[22m,\n",
              "  model: \u001b[32m\"gpt-5-mini-2025-08-07\"\u001b[39m,\n",
              "  output: [\n",
              "    {\n",
              "      id: \u001b[32m\"rs_0ae72cbd0894279200699c8e43cd4c8192bcbc70792b6aa621\"\u001b[39m,\n",
              "      type: \u001b[32m\"reasoning\"\u001b[39m,\n",
              "      summary: []\n",
              "    },\n",
              "    {\n",
              "      id: \u001b[32m\"msg_0ae72cbd0894279200699c8e48976481928e1f205210636717\"\u001b[39m,\n",
              "      type: \u001b[32m\"message\"\u001b[39m,\n",
              "      status: \u001b[32m\"completed\"\u001b[39m,\n",
              "      content: [\n",
              "        {\n",
              "          type: \u001b[32m\"output_text\"\u001b[39m,\n",
              "          annotations: [],\n",
              "          logprobs: [],\n",
              "          text: \u001b[32m'{\"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).\"}'\u001b[39m\n",
              "        }\n",
              "      ],\n",
              "      role: \u001b[32m\"assistant\"\u001b[39m\n",
              "    }\n",
              "  ],\n",
              "  parallel_tool_calls: \u001b[33mtrue\u001b[39m,\n",
              "  presence_penalty: \u001b[33m0\u001b[39m,\n",
              "  previous_response_id: \u001b[1mnull\u001b[22m,\n",
              "  prompt_cache_key: \u001b[1mnull\u001b[22m,\n",
              "  prompt_cache_retention: \u001b[1mnull\u001b[22m,\n",
              "  reasoning: { effort: \u001b[32m\"medium\"\u001b[39m, summary: \u001b[1mnull\u001b[22m },\n",
              "  safety_identifier: \u001b[1mnull\u001b[22m,\n",
              "  service_tier: \u001b[32m\"default\"\u001b[39m,\n",
              "  store: \u001b[33mtrue\u001b[39m,\n",
              "  temperature: \u001b[33m1\u001b[39m,\n",
              "  text: {\n",
              "    format: {\n",
              "      type: \u001b[32m\"json_schema\"\u001b[39m,\n",
              "      description: \u001b[1mnull\u001b[22m,\n",
              "      name: \u001b[32m\"response_schema\"\u001b[39m,\n",
              "      schema: {\n",
              "        type: \u001b[32m\"object\"\u001b[39m,\n",
              "        properties: { \u001b[32m\"ai-message\"\u001b[39m: \u001b[36m[Object]\u001b[39m, \u001b[32m\"suggested-topic\"\u001b[39m: \u001b[36m[Object]\u001b[39m },\n",
              "        required: [ \u001b[32m\"ai-message\"\u001b[39m, \u001b[32m\"suggested-topic\"\u001b[39m ],\n",
              "        additionalProperties: \u001b[33mfalse\u001b[39m\n",
              "      },\n",
              "      strict: \u001b[33mtrue\u001b[39m\n",
              "    },\n",
              "    verbosity: \u001b[32m\"medium\"\u001b[39m\n",
              "  },\n",
              "  tool_choice: \u001b[32m\"auto\"\u001b[39m,\n",
              "  tools: [],\n",
              "  top_logprobs: \u001b[33m0\u001b[39m,\n",
              "  top_p: \u001b[33m1\u001b[39m,\n",
              "  truncation: \u001b[32m\"disabled\"\u001b[39m,\n",
              "  usage: {\n",
              "    input_tokens: \u001b[33m167\u001b[39m,\n",
              "    input_tokens_details: { cached_tokens: \u001b[33m0\u001b[39m },\n",
              "    output_tokens: \u001b[33m482\u001b[39m,\n",
              "    output_tokens_details: { reasoning_tokens: \u001b[33m320\u001b[39m },\n",
              "    total_tokens: \u001b[33m649\u001b[39m\n",
              "  },\n",
              "  user: \u001b[1mnull\u001b[22m,\n",
              "  metadata: { tabla: \u001b[32m\"planes_estudio\"\u001b[39m, id: \u001b[32m\"2\"\u001b[39m },\n",
              "  output_text: \u001b[32m'{\"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).\"}'\u001b[39m\n",
              "}"
            ]
          },
          "execution_count": 13,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "while (response.status === \"queued\" || response.status === \"in_progress\") {\n",
        "    console.log(\"Current status: \" + response.status);\n",
        "    await new Promise((resolve) => setTimeout(resolve, 2000)); // wait 2 seconds\n",
        "    response = await openai.responses.retrieve(response.id);\n",
        "}\n",
        "\n",
        "response;\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "ebb67bd8",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{ tabla: \u001b[32m\"planes_estudio\"\u001b[39m, id: \u001b[32m\"e39952c1-a53b-43bf-8033-feda493a0651\"\u001b[39m }"
            ]
          },
          "execution_count": 24,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "response.metadata;\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "cd18fc2d",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{\n",
              "  error: \u001b[1mnull\u001b[22m,\n",
              "  data: {\n",
              "    id: \u001b[32m\"e39952c1-a53b-43bf-8033-feda493a0651\"\u001b[39m,\n",
              "    carrera_id: \u001b[32m\"8208da08-d549-4359-8865-9d806bc54f19\"\u001b[39m,\n",
              "    estructura_id: \u001b[32m\"69fb2b77-5a95-47e0-bf1f-389d384200e4\"\u001b[39m,\n",
              "    nombre: \u001b[32m\"Ingeniearía en Cifbernética y Ciberseguridad (2025)\"\u001b[39m,\n",
              "    nivel: \u001b[32m\"Doctorado\"\u001b[39m,\n",
              "    tipo_ciclo: \u001b[32m\"Semestre\"\u001b[39m,\n",
              "    numero_ciclos: \u001b[33m8\u001b[39m,\n",
              "    datos: {\n",
              "      \u001b[32m\"ai-message\"\u001b[39m: \u001b[32m\"¡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?\"\u001b[39m,\n",
              "      \u001b[32m\"suggested-topic\"\u001b[39m: \u001b[32m\"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.\"\u001b[39m\n",
              "    },\n",
              "    estado_actual_id: \u001b[32m\"18f49b67-8077-4371-be6e-2019a3be3562\"\u001b[39m,\n",
              "    activo: \u001b[33mtrue\u001b[39m,\n",
              "    tipo_origen: \u001b[32m\"IA\"\u001b[39m,\n",
              "    meta_origen: {},\n",
              "    creado_por: \u001b[32m\"11111111-1111-1111-1111-111111111111\"\u001b[39m,\n",
              "    actualizado_por: \u001b[32m\"11111111-1111-1111-1111-111111111111\"\u001b[39m,\n",
              "    creado_en: \u001b[32m\"2026-02-20T17:11:28.995222+00:00\"\u001b[39m,\n",
              "    actualizado_en: \u001b[32m\"2026-02-20T17:12:40.170995+00:00\"\u001b[39m,\n",
              "    nombre_search: \u001b[32m\"ingeniearia en cifbernetica y ciberseguridad (2025)\"\u001b[39m,\n",
              "    plan_hash: \u001b[32m\"70d28457bbddfe4f5cde0574\"\u001b[39m\n",
              "  },\n",
              "  count: \u001b[1mnull\u001b[22m,\n",
              "  status: \u001b[33m200\u001b[39m,\n",
              "  statusText: \u001b[32m\"OK\"\u001b[39m\n",
              "}"
            ]
          },
          "execution_count": 27,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "await supabase.from(response.metadata.tabla).update({\n",
        "    datos: JSON.parse(response.output_text),\n",
        "}).eq(\"id\", response.metadata.id).select(\"*\").single();\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "cbbfd8c0",
      "metadata": {},
      "outputs": [
        {
          "ename": "Expected ';', '}' or <eof> at file:///repl.tsx:2:93\n\n  ...} ha sido actualizado con los datos generados por la IA.`: response.output_text,\n                                                              ~",
          "evalue": "Expected ';', '}' or <eof> at file:///repl.tsx:2:93\n\n  ...} ha sido actualizado con los datos generados por la IA.`: response.output_text,\n                                                              ~",
          "output_type": "error",
          "traceback": []
        }
      ],
      "source": []
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "a00c79bd",
      "metadata": {},
      "outputs": [],
      "source": []
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Deno",
      "language": "typescript",
      "name": "deno"
    },
    "language_info": {
      "codemirror_mode": "typescript",
      "file_extension": ".ts",
      "mimetype": "text/x.typescript",
      "name": "typescript",
      "nbconvert_exporter": "script",
      "pygments_lexer": "typescript",
      "version": "5.9.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
