{ "cells": [ { "cell_type": "code", "execution_count": null, "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();" ] }, { "cell_type": "code", "execution_count": null, "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);" ] }, { "cell_type": "code", "execution_count": 19, "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": 21, "id": "8abb080e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\u001b[32m\"e39952c1-a53b-43bf-8033-feda493a0651\"\u001b[39m" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plan.id" ] }, { "cell_type": "code", "execution_count": 22, "id": "a382bdc6", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{\n", " id: \u001b[32m\"resp_0f1906be7e83879e00699895d7f1cc8193a960e6ccdab1d377\"\u001b[39m,\n", " object: \u001b[32m\"response\"\u001b[39m,\n", " created_at: \u001b[33m1771607511\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: {\n", " tabla: \u001b[32m\"planes_estudio\"\u001b[39m,\n", " id: \u001b[32m\"e39952c1-a53b-43bf-8033-feda493a0651\"\u001b[39m\n", " },\n", " output_text: \u001b[32m\"\"\u001b[39m\n", "}" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "let response = await openai.responses.create({\n", " model: \"gpt-5-mini\",\n", " input: \"Hola mundo\",\n", " metadata: {\n", " tabla: \"planes_estudio\",\n", " id: plan.id,\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": 23, "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_0f1906be7e83879e00699895d7f1cc8193a960e6ccdab1d377\"\u001b[39m,\n", " object: \u001b[32m\"response\"\u001b[39m,\n", " created_at: \u001b[33m1771607511\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[33m1771607519\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_0f1906be7e83879e00699895d976548193ad40e9aae0b1b4f2\"\u001b[39m,\n", " type: \u001b[32m\"reasoning\"\u001b[39m,\n", " summary: []\n", " },\n", " {\n", " id: \u001b[32m\"msg_0f1906be7e83879e00699895ddf62881938811097ba62e8724\"\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! ¿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.\"}'\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[33m437\u001b[39m,\n", " output_tokens_details: { reasoning_tokens: \u001b[33m320\u001b[39m },\n", " total_tokens: \u001b[33m604\u001b[39m\n", " },\n", " user: \u001b[1mnull\u001b[22m,\n", " metadata: {\n", " tabla: \u001b[32m\"planes_estudio\"\u001b[39m,\n", " id: \u001b[32m\"e39952c1-a53b-43bf-8033-feda493a0651\"\u001b[39m\n", " },\n", " output_text: \u001b[32m'{\"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.\"}'\u001b[39m\n", "}" ] }, "execution_count": 23, "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;" ] }, { "cell_type": "code", "execution_count": 24, "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" ] }, { "cell_type": "code", "execution_count": 27, "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();" ] }, { "cell_type": "code", "execution_count": null, "id": "cbbfd8c0", "metadata": {}, "outputs": [ { "ename": "Expected ';', '}' or 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 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 }