feat: joel may sometimes answer even when he's not called for.

This commit is contained in:
eric
2026-02-23 13:47:25 +01:00
parent 66b1ef15af
commit 283802ae55
10 changed files with 375 additions and 41 deletions

View File

@@ -56,6 +56,16 @@ export class AiService {
return "snarky";
}
/**
* Classify whether the message is directed at Joel
*/
async classifyJoelDirected(message: string): Promise<boolean> {
if (this.provider.classifyJoelDirected) {
return this.provider.classifyJoelDirected(message);
}
return false;
}
/**
* Extract and save memorable information from a message
*/

View File

@@ -281,4 +281,44 @@ Category:`,
return "snarky"; // Default to snarky on error
}
}
/**
* Cheap binary classifier to detect if a message is directed at Joel
*/
async classifyJoelDirected(message: string): Promise<boolean> {
try {
const classification = await this.client.chat.completions.create({
model: config.ai.classificationModel,
messages: [
{
role: "user",
content: `Determine if this Discord message is directed at Joel (the bot), or talking about Joel in a way Joel should respond.
Only respond with one token: YES or NO.
Guidance:
- YES if the user is asking Joel a question, requesting Joel to do something, replying conversationally to Joel, or maybe discussing Joel as a participant.
- NO if it's general chat between humans, statements that do not involve Joel.
Message: "${message}"
Answer:`,
},
],
max_tokens: 3,
temperature: 0,
});
const result = classification.choices[0]?.message?.content?.trim().toUpperCase();
return result?.startsWith("YES") ?? false;
} catch (error) {
logger.error("Failed to classify directed message", {
method: "classifyJoelDirected",
model: config.ai.classificationModel,
messageLength: message.length,
});
logger.error("Directed classification error details", error);
return false;
}
}
}

View File

@@ -35,6 +35,11 @@ export interface AiProvider {
*/
classifyMessage?(message: string): Promise<MessageStyle>;
/**
* Classify whether a message is directed at Joel
*/
classifyJoelDirected?(message: string): Promise<boolean>;
/**
* Extract memorable information from a message
*/