Chats de la IA en segundo plano #42 #50
@@ -1,34 +1,90 @@
|
|||||||
// ./plan_mensajes_ia/index.ts
|
// ./plan_mensajes_ia/index.ts
|
||||||
import { getSupabaseServiceClient } from "../_shared/supabase.ts";
|
import type { OpenAI } from "openai";
|
||||||
|
|
||||||
export async function handlePlanMensajesResponse(response: any) {
|
import type { Json } from "../../_shared/database.types.ts";
|
||||||
const supabase = getSupabaseServiceClient();
|
import { ResponseMetadata } from "../../_shared/utils.ts";
|
||||||
const { mensaje_id, is_structured } = response.metadata;
|
import { supabase } from "../../openai-webhook-responses/supabase.ts";
|
||||||
|
|
||||||
// Extraer el texto de la respuesta (usando tu lógica de filtrado de output)
|
|
||||||
const outputText = response.output_text || ""; // Ajustar según cómo venga el objeto
|
|
||||||
const respuestaJSON = JSON.parse(outputText || "{}");
|
|
||||||
|
|
||||||
const is_refusal = !!respuestaJSON.is_refusal || respuestaJSON["is-refusal"] === true;
|
function extractOutputText(response: OpenAI.Responses.Response): string {
|
||||||
|
const direct = (response as unknown as { output_text?: unknown }).output_text;
|
||||||
|
if (typeof direct === "string") return direct;
|
||||||
|
|
||||||
let recommendations = [];
|
const output = (response as unknown as { output?: unknown }).output;
|
||||||
if (is_structured) {
|
if (!Array.isArray(output)) return "";
|
||||||
recommendations = Object.entries(respuestaJSON)
|
|
||||||
.filter(([k]) => k !== "ai-message" && k !== "is-refusal")
|
// Fallback similar al usado en index.ts
|
||||||
.map(([campo, valor]) => ({
|
try {
|
||||||
campo_afectado: campo,
|
return output
|
||||||
texto_mejora: valor,
|
.filter((item) => (item as { type?: unknown })?.type === "message")
|
||||||
aplicada: false,
|
.flatMap((item) => (item as { content?: unknown })?.content ?? [])
|
||||||
}));
|
.filter((c) => (c as { type?: unknown })?.type === "output_text")
|
||||||
|
.map((c) => String((c as { text?: unknown })?.text ?? ""))
|
||||||
|
.join("");
|
||||||
|
} catch {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function handlePlanMensajesResponse(
|
||||||
|
response: OpenAI.Responses.Response,
|
||||||
|
): Promise<void> {
|
||||||
|
const metadata = response.metadata as any;
|
||||||
|
const mensajeId = metadata?.mensaje_id;
|
||||||
|
console.log("ya entre aqui");
|
||||||
|
|
||||||
|
const isStructured = metadata?.is_structured === "true" || metadata?.is_structured === true;
|
||||||
|
if (!mensajeId) {
|
||||||
|
console.warn("No se recibió mensaje_id en la metadata del webhook");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await supabase
|
try {
|
||||||
.from("plan_mensajes_ia")
|
const outputText = extractOutputText(response);
|
||||||
.update({
|
if (!outputText) {
|
||||||
respuesta: respuestaJSON["ai-message"] || "",
|
throw new Error("La respuesta de OpenAI está vacía");
|
||||||
propuesta: { recommendations },
|
}
|
||||||
is_refusal,
|
|
||||||
estado: "COMPLETADO",
|
let respuestaJSON: any;
|
||||||
})
|
try {
|
||||||
.eq("id", mensaje_id);
|
respuestaJSON = JSON.parse(outputText);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Error parseando JSON de OpenAI: ${e.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const is_refusal = !!respuestaJSON.is_refusal || respuestaJSON["is-refusal"] === true;
|
||||||
|
|
||||||
|
let recommendations = [];
|
||||||
|
if (isStructured && !is_refusal) {
|
||||||
|
recommendations = Object.entries(respuestaJSON)
|
||||||
|
.filter(([k]) => k !== "ai-message" && k !== "is-refusal" && k !== "is_refusal")
|
||||||
|
.map(([campo, valor]) => ({
|
||||||
|
campo_afectado: campo,
|
||||||
|
texto_mejora: valor,
|
||||||
|
aplicada: false,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
const { error } = await supabase
|
||||||
|
.from("plan_mensajes_ia")
|
||||||
|
.update({
|
||||||
|
respuesta: respuestaJSON["ai-message"] || "",
|
||||||
|
propuesta: { recommendations },
|
||||||
|
is_refusal,
|
||||||
|
estado: "COMPLETADO",
|
||||||
|
})
|
||||||
|
.eq("id", mensajeId);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error procesando handlePlanMensajesResponse:", { mensajeId, e });
|
||||||
|
// Opcional: Marcar el mensaje como fallido en la tabla si tienes ese estado
|
||||||
|
await supabase
|
||||||
|
.from("plan_mensajes_ia")
|
||||||
|
.update({ estado: "ERROR" })
|
||||||
|
.eq("id", mensajeId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,8 @@ import OpenAI from "openai";
|
|||||||
import { ResponseMetadata } from "../_shared/utils.ts";
|
import { ResponseMetadata } from "../_shared/utils.ts";
|
||||||
import { handlePlanesEstudioResponse } from "./planes_estudio/index.ts";
|
import { handlePlanesEstudioResponse } from "./planes_estudio/index.ts";
|
||||||
import { handleAsignaturasResponse } from "./asignaturas/index.ts";
|
import { handleAsignaturasResponse } from "./asignaturas/index.ts";
|
||||||
import { handlePlanMensajesResponse } from "./planes_estudio/crear.ts";
|
import { handlePlanMensajesResponse } from "../create-chat-conversation/plan/crear.ts";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
console.log("Starting OpenAI webhook responses function");
|
console.log("Starting OpenAI webhook responses function");
|
||||||
@@ -36,9 +37,7 @@ async function handleCompletedResponse(
|
|||||||
case "asignaturas":
|
case "asignaturas":
|
||||||
await handleAsignaturasResponse(response);
|
await handleAsignaturasResponse(response);
|
||||||
break;
|
break;
|
||||||
case "plan_mensajes_ia": // <-- Nueva tabla añadida
|
case "plan_mensajes_ia":
|
||||||
console.log("entre aqui");
|
|
||||||
|
|
||||||
await handlePlanMensajesResponse(response);
|
await handlePlanMensajesResponse(response);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -106,66 +106,3 @@ export async function handleCrearPlanEstudio(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function handlePlanMensajesResponse(
|
|
||||||
response: OpenAI.Responses.Response,
|
|
||||||
): Promise<void> {
|
|
||||||
const metadata = response.metadata as any;
|
|
||||||
const mensajeId = metadata?.mensaje_id;
|
|
||||||
console.log("ya entre aqui");
|
|
||||||
|
|
||||||
const isStructured = metadata?.is_structured === "true" || metadata?.is_structured === true;
|
|
||||||
if (!mensajeId) {
|
|
||||||
console.warn("No se recibió mensaje_id en la metadata del webhook");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const outputText = extractOutputText(response);
|
|
||||||
if (!outputText) {
|
|
||||||
throw new Error("La respuesta de OpenAI está vacía");
|
|
||||||
}
|
|
||||||
|
|
||||||
let respuestaJSON: any;
|
|
||||||
try {
|
|
||||||
respuestaJSON = JSON.parse(outputText);
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(`Error parseando JSON de OpenAI: ${e.message}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const is_refusal = !!respuestaJSON.is_refusal || respuestaJSON["is-refusal"] === true;
|
|
||||||
|
|
||||||
let recommendations = [];
|
|
||||||
if (isStructured && !is_refusal) {
|
|
||||||
recommendations = Object.entries(respuestaJSON)
|
|
||||||
.filter(([k]) => k !== "ai-message" && k !== "is-refusal" && k !== "is_refusal")
|
|
||||||
.map(([campo, valor]) => ({
|
|
||||||
campo_afectado: campo,
|
|
||||||
texto_mejora: valor,
|
|
||||||
aplicada: false,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
const { error } = await supabase
|
|
||||||
.from("plan_mensajes_ia")
|
|
||||||
.update({
|
|
||||||
respuesta: respuestaJSON["ai-message"] || "",
|
|
||||||
propuesta: { recommendations },
|
|
||||||
is_refusal,
|
|
||||||
estado: "COMPLETADO",
|
|
||||||
})
|
|
||||||
.eq("id", mensajeId);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Error procesando handlePlanMensajesResponse:", { mensajeId, e });
|
|
||||||
// Opcional: Marcar el mensaje como fallido en la tabla si tienes ese estado
|
|
||||||
await supabase
|
|
||||||
.from("plan_mensajes_ia")
|
|
||||||
.update({ estado: "ERROR" })
|
|
||||||
.eq("id", mensajeId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user