generated from nhcarrigan/template
feat: add makeAiRequest utility with Amari personality prompt
- Centralise all Claude API calls through a shared makeAiRequest module - Apply a consistent Amari personality to all AI-generated content - Add try/catch with logger.error to all AI and external API call sites - Extract postGiteaIssue helper in createIssue for better structure
This commit is contained in:
+36
-37
@@ -6,46 +6,36 @@
|
||||
|
||||
import { MessageFlags, type ChatInputCommandInteraction } from "discord.js";
|
||||
import { ids } from "../config/ids.js";
|
||||
import { anthropic } from "../utils/anthropic.js";
|
||||
import { logger } from "../utils/logger.js";
|
||||
import { makeAiRequest } from "../utils/makeAiRequest.js";
|
||||
|
||||
interface LeantimeResponse {
|
||||
error?: { message: string };
|
||||
result?: number;
|
||||
}
|
||||
|
||||
const taskSystemPrompt = "You are a helpful assistant that creates"
|
||||
+ " well-structured task descriptions. Be concise and actionable."
|
||||
const taskSystemPrompt = "Create well-structured task descriptions."
|
||||
+ " Be concise and actionable."
|
||||
+ " Return only the description text with no extra formatting or headers.";
|
||||
|
||||
/**
|
||||
* Generates an AI-augmented task description using Claude.
|
||||
* Generates an AI-augmented task description.
|
||||
* @param description - Optional additional context for the task.
|
||||
* @param title - The subject of the Leantime task.
|
||||
* @returns The generated task description text.
|
||||
* @returns The generated task description text, or the original description as fallback.
|
||||
*/
|
||||
const generateTaskDescription = async(
|
||||
description: string,
|
||||
title: string,
|
||||
): Promise<string> => {
|
||||
const aiResponse = await anthropic.messages.create({
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention -- Anthropic API field.
|
||||
max_tokens: 500,
|
||||
messages: [
|
||||
{
|
||||
content: `Create a clear, concise task description for a personal productivity board.\n\nTask title: ${title}${description === ""
|
||||
? ""
|
||||
: `\nAdditional context: ${description}`}`,
|
||||
role: "user",
|
||||
},
|
||||
],
|
||||
model: "claude-haiku-4-5-20251001",
|
||||
system: taskSystemPrompt,
|
||||
const result = await makeAiRequest({
|
||||
maxTokens: 500,
|
||||
systemPrompt: taskSystemPrompt,
|
||||
userMessage: `Create a clear, concise task description for a personal productivity board.\n\nTask title: ${title}${description === ""
|
||||
? ""
|
||||
: `\nAdditional context: ${description}`}`,
|
||||
});
|
||||
const [ firstContent ] = aiResponse.content;
|
||||
return firstContent?.type === "text"
|
||||
? firstContent.text
|
||||
: description;
|
||||
return result ?? description;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -110,23 +100,32 @@ export const createTask = async(
|
||||
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
|
||||
const augmentedDesc = await generateTaskDescription(description, title);
|
||||
const data = await postLeantimeTask(augmentedDesc, priority, title);
|
||||
try {
|
||||
const augmentedDesc = await generateTaskDescription(description, title);
|
||||
const data = await postLeantimeTask(augmentedDesc, priority, title);
|
||||
|
||||
if (data.error !== undefined) {
|
||||
if (data.error !== undefined) {
|
||||
await interaction.editReply({
|
||||
content: `❌ Failed to create task: ${data.error.message}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const taskId = data.result;
|
||||
const taskUrl = taskId === undefined
|
||||
? "https://board.nhcarrigan.com"
|
||||
: `https://board.nhcarrigan.com/dashboard/home#/tickets/showTicket/${taskId.toString()}`;
|
||||
|
||||
await logger.metric("created_task", 1, { title });
|
||||
await interaction.editReply({
|
||||
content: `❌ Failed to create task: ${data.error.message}`,
|
||||
content: `✅ Task created: **${title}**\n${taskUrl}`,
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
await logger.error("createTask command", error);
|
||||
}
|
||||
await interaction.editReply({
|
||||
content: "❌ An unexpected error occurred while creating the task.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const taskId = data.result;
|
||||
const taskUrl = taskId === undefined
|
||||
? "https://board.nhcarrigan.com"
|
||||
: `https://board.nhcarrigan.com/dashboard/home#/tickets/showTicket/${taskId.toString()}`;
|
||||
|
||||
await logger.metric("created_task", 1, { title });
|
||||
await interaction.editReply({
|
||||
content: `✅ Task created: **${title}**\n${taskUrl}`,
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user