bsky-alt-text-worker/src/endpoints/condense_text.ts

108 lines
2.5 KiB
TypeScript

import { Num, OpenAPIRoute } from "chanfana";
import { z } from "zod";
import { type AppContext } from "../types";
export class CondenseTextEndpoint extends OpenAPIRoute {
schema = {
tags: ["AltText"],
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."),
directive: z.string({
description:
"Instructions for condensing the text (e.g., 'Summarize this article', 'Extract keywords').",
required_error:
"A condensation directive is required.",
}).min(1, "Directive cannot be empty."),
targetLength: Num({
description:
"The approximate target length for the condensed text (e.g., number of sentences, characters, or words).",
default: 200,
}).optional(),
}),
},
},
},
},
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<typeof this.schema>();
const { text, directive, targetLength } = data.body;
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: directive },
{ 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,
};
}
}
}