generated from nhcarrigan/template
feat: include cost in announcements
This commit is contained in:
@@ -10,8 +10,8 @@ import {
|
||||
announcementJsonSchema,
|
||||
announcementSystemMessage,
|
||||
} from "../config/announcements.js";
|
||||
import type { AnnouncementResponse }
|
||||
from "../interfaces/announcementResponse.js";
|
||||
import { getAiCost } from "../utils/getAiCost.js";
|
||||
import type { AnnouncementResponse } from "../interfaces/announcementResponse.js";
|
||||
|
||||
/**
|
||||
* Generates announcements for all platforms using AI.
|
||||
@@ -20,7 +20,7 @@ import type { AnnouncementResponse }
|
||||
*/
|
||||
export const generateAnnouncements = async(
|
||||
content: string,
|
||||
): Promise<AnnouncementResponse | null> => {
|
||||
): Promise<{ cost: string; response: AnnouncementResponse } | null> => {
|
||||
if (process.env.ANTHROPIC_KEY === undefined) {
|
||||
return null;
|
||||
}
|
||||
@@ -46,12 +46,17 @@ export const generateAnnouncements = async(
|
||||
},
|
||||
system: announcementSystemMessage,
|
||||
});
|
||||
const text = response.content.find((m) => {
|
||||
const { usage, content: responseContent } = response;
|
||||
const text = responseContent.find((m) => {
|
||||
return m.type === "text";
|
||||
});
|
||||
if (text?.text === undefined) {
|
||||
return null;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Being lazy.
|
||||
return JSON.parse(text.text) as AnnouncementResponse;
|
||||
|
||||
return {
|
||||
cost: getAiCost(usage),
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Being lazy.
|
||||
response: JSON.parse(text.text) as AnnouncementResponse,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -86,7 +86,7 @@ export const announcementRoutes: FastifyPluginAsync = async(server) => {
|
||||
});
|
||||
}
|
||||
|
||||
const { bluesky, discord, reddit, twitter } = announcement;
|
||||
const { bluesky, discord, reddit, twitter } = announcement.response;
|
||||
const { title: discordTitle, content: discordContent } = discord;
|
||||
const { title: redditTitle, content: redditContent } = reddit;
|
||||
|
||||
@@ -111,8 +111,9 @@ export const announcementRoutes: FastifyPluginAsync = async(server) => {
|
||||
const blueskyPost = await announceOnBluesky(bluesky);
|
||||
const twitterPost = await announceOnTwitter(twitter);
|
||||
return await reply.status(201).send({
|
||||
cost: announcement.cost,
|
||||
message: `Announcement processed. Discord: ${discordPost}, Reddit: ${redditPost}, Bluesky: ${blueskyPost}, Twitter: ${twitterPost}`,
|
||||
rawPost: announcement,
|
||||
rawPost: announcement.response,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import type { BetaUsage } from "@anthropic-ai/sdk/resources/beta.js";
|
||||
|
||||
/**
|
||||
* Calculates the cost of an AI response.
|
||||
* @param usage - The usage payload from Anthropic.
|
||||
* @returns A description of the cost of the AI response.
|
||||
*/
|
||||
export const getAiCost = (usage: BetaUsage): string => {
|
||||
const { input_tokens: inputTokens, output_tokens: outputTokens } = usage;
|
||||
const costPerInputToken = 5 / 1_000_000;
|
||||
const costPerOutputToken = 25 / 1_000_000;
|
||||
const inputCost = inputTokens * costPerInputToken;
|
||||
const outputCost = outputTokens * costPerOutputToken;
|
||||
const totalCost = inputCost + outputCost;
|
||||
return `Input cost: ${inputCost.toLocaleString("en-GB", {
|
||||
currency: "USD",
|
||||
style: "currency",
|
||||
})} Output cost: ${outputCost.toLocaleString("en-GB", {
|
||||
currency: "USD",
|
||||
style: "currency",
|
||||
})} Total cost: ${totalCost.toLocaleString("en-GB", {
|
||||
currency: "USD",
|
||||
style: "currency",
|
||||
})}`;
|
||||
};
|
||||
Reference in New Issue
Block a user