import { Enumeration, Num, OpenAPIRoute } from "chanfana"; import { z } from "zod"; import { type AppContext } from "../types"; export class CondenseTextEndpoint extends OpenAPIRoute { schema = { tags: ["Processing"], summary: "Condense a given text based on a directive", security: [ { apiKey: [], }, ], request: { body: { content: { "application/json": { schema: z.object({ text: z.string({ description: "The text to be condensed.", required_error: "Text is required for condensation.", }).min(1, "Text cannot be empty."), mediaType: z.enum(["video", "image"], { description: "The type of media being described", required_error: "Media type is required.", }), }), }, }, }, }, responses: { "200": { description: "Returns the condensed text", content: { "application/json": { schema: z.object({ success: z.boolean(), condensedText: z.string().nullable(), error: z.string().optional(), }), }, }, }, "500": { description: "Internal Server Error - Issue with Cloud Function or API call", content: { "application/json": { schema: z.object({ success: z.boolean(), message: z.string(), }), }, }, }, }, }; async handle(c: AppContext) { const data = await this.getValidatedData(); const { text, mediaType } = data.body; const targetLength = c.env.MAX_ALT_TEXT_LENGTH - 100; try { const res = await c.var.gemini.models.generateContent({ // * Original cloud function used "gemini-2.0-flash", but I think the lite version should work fine too. model: "gemini-2.0-flash-lite", contents: [{ parts: [ { text: `You are an expert at writing concise, informative alt text. Please condense the following ${mediaType} description to be no more than ${targetLength} characters while preserving the most important details. The description needs to be accessible and useful for screen readers:`, }, { text: text }, ], }], config: { temperature: 0.2, maxOutputTokens: 1024, }, }); const condensedText = res.candidates?.[0]?.content?.parts?.[0] ?.text; if (!condensedText) { return { success: false, error: "Failed to condense text.", }; } return { success: true, altText: condensedText, }; } catch (e) { return { success: false, message: e, }; } } }