feat: update deno.json and deno.lock to include OpenAI and Zod imports; add sample PDF file
- Added imports for OpenAI and Zod in deno.json - Updated deno.lock with new versions for OpenAI and Zod - Introduced a sample PDF file demonstrating bookmark functionality - Refactored ai-structured function to improve error handling and logging - Updated tests to reflect changes in input structure and expected output
This commit is contained in:
@@ -25,7 +25,9 @@ function mustEnv() {
|
||||
if (!SUPABASE_ANON_KEY) throw new Error("SUPABASE_ANON_KEY is required");
|
||||
}
|
||||
|
||||
async function getAuthedClient(): Promise<{ client: SupabaseClient; accessToken: string }> {
|
||||
async function getAuthedClient(): Promise<
|
||||
{ client: SupabaseClient; accessToken: string }
|
||||
> {
|
||||
mustEnv();
|
||||
const client = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, options);
|
||||
|
||||
@@ -36,7 +38,9 @@ async function getAuthedClient(): Promise<{ client: SupabaseClient; accessToken:
|
||||
if (error) throw new Error("Sign-in failed: " + error.message);
|
||||
|
||||
const accessToken = data.session?.access_token;
|
||||
if (!accessToken) throw new Error("No access_token returned from signInWithPassword");
|
||||
if (!accessToken) {
|
||||
throw new Error("No access_token returned from signInWithPassword");
|
||||
}
|
||||
|
||||
return { client, accessToken };
|
||||
}
|
||||
@@ -44,58 +48,45 @@ async function getAuthedClient(): Promise<{ client: SupabaseClient; accessToken:
|
||||
Deno.test("ai-structured (JSON body)", async () => {
|
||||
const { client, accessToken } = await getAuthedClient();
|
||||
|
||||
const form = new FormData();
|
||||
form.append(
|
||||
"options",
|
||||
JSON.stringify({
|
||||
input: "Genera 3 ideas de negocio innovadoras en formato JSON.",
|
||||
model: "gpt-5-nano",
|
||||
text: {
|
||||
format: {
|
||||
"type": "json_schema",
|
||||
"name": "business_ideas",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"properties": {
|
||||
"idea": { "type": "string", "description": "The business idea" },
|
||||
},
|
||||
"required": ["idea"],
|
||||
"additionalProperties": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const { data, error } = await client.functions.invoke("ai-structured", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`, // 👈 clave para que tu función pase el authHeader check
|
||||
},
|
||||
body: {
|
||||
response: {
|
||||
model: "gpt-5",
|
||||
input: [
|
||||
{ role: "system", content: "Responde SIEMPRE en JSON válido." },
|
||||
{ role: "user", content: "Dame 3 ideas de proyecto de IA para educación." },
|
||||
],
|
||||
},
|
||||
structured: {
|
||||
type: "json_schema",
|
||||
name: "ideas",
|
||||
strict: true,
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
ideas: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
titulo: { type: "string" },
|
||||
descripcion: { type: "string" },
|
||||
},
|
||||
required: ["titulo", "descripcion"],
|
||||
additionalProperties: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
required: ["ideas"],
|
||||
additionalProperties: false,
|
||||
},
|
||||
},
|
||||
references: {},
|
||||
usarMCP: false,
|
||||
},
|
||||
body: form,
|
||||
});
|
||||
|
||||
if (error) throw new Error("Invoke failed: " + error.message);
|
||||
assert(data, "Expected data from function");
|
||||
|
||||
// tu función responde { ok, output, outputText, ... }
|
||||
assertEquals(data.ok, true);
|
||||
assert(Array.isArray(data.output?.ideas), "output.ideas should be an array");
|
||||
assertEquals(data.output.ideas.length, 3);
|
||||
for (const it of data.output.ideas) {
|
||||
assert(typeof it.titulo === "string");
|
||||
assert(typeof it.descripcion === "string");
|
||||
}
|
||||
assert(
|
||||
Array.isArray(data.openai_raw.output),
|
||||
"Expected output to be an array",
|
||||
);
|
||||
assert(data.openai_raw.output.length === 3, "Expected 3 business ideas");
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
Deno.test("ai-structured (multipart + file)", async () => {
|
||||
@@ -106,7 +97,10 @@ Deno.test("ai-structured (multipart + file)", async () => {
|
||||
const file = new File([bytes], "carta.pdf", { type: "application/pdf" });
|
||||
|
||||
const payload = {
|
||||
response: { input: "Resume estos documentos en JSON.", model: "gpt-5" },
|
||||
response: {
|
||||
input: "Resume estos documentos en JSON.",
|
||||
model: "gpt-5-nano",
|
||||
},
|
||||
structured: {
|
||||
type: "json_schema",
|
||||
name: "resumen",
|
||||
|
||||
Reference in New Issue
Block a user