From aa779e7b807a6e64ecfcb35faa257455d41df946 Mon Sep 17 00:00:00 2001 From: eric Date: Thu, 12 Mar 2026 20:20:11 +0100 Subject: [PATCH] joel --- bun.lockb | Bin 162901 -> 185128 bytes package.json | 2 ++ src/features/joel/responder.ts | 20 ++++++++++++-- src/features/joel/voice.ts | 38 +++++++++++++++++++++++---- src/features/message-logger/index.ts | 32 +++++++++++++++++++++- 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/bun.lockb b/bun.lockb index 9ff47abf27905bfeafd99c2a44439884c2511b60..af0fdb4a4b3b5793e43fbbfc856ad5bd75d677e7 100755 GIT binary patch delta 41921 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 F_%DpBOo9La delta 29341 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 diff --git a/package.json b/package.json index 51525fb..0c646f8 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ }, "dependencies": { "@ai-sdk/openai": "^0.0.13", + "@discordjs/opus": "^0.10.0", "@discordjs/voice": "^0.18.0", "@elysiajs/cors": "^1.4.0", "@elysiajs/html": "^1.3.0", @@ -38,6 +39,7 @@ "discord.js": "^14.14.1", "drizzle-orm": "^1.0.0-beta.15-859cf75", "elysia": "^1.4.7", + "ffmpeg-static": "^5.2.0", "hono": "^4.11.7", "libsql": "^0.3.18", "openai": "^4.36.0", diff --git a/src/features/joel/responder.ts b/src/features/joel/responder.ts index b355a3a..915b26e 100644 --- a/src/features/joel/responder.ts +++ b/src/features/joel/responder.ts @@ -26,6 +26,14 @@ const CONVERSATION_CONTEXT_MAX_LINKS_PER_MESSAGE = 2; const CONVERSATION_CONTEXT_MAX_MEDIA_MESSAGES = 2; const CONVERSATION_CONTEXT_MAX_MEDIA_ATTACHMENTS = 3; const URL_REGEX = /https?:\/\/[^\s<>()]+/gi; +const REAL_JOEL_TARGET_USER_ID = "202112342660481033"; +const REAL_JOEL_IDENTITY_PREAMBLE = [ + "You are Joel, the real Joel.", + "Speak directly as Joel in first person.", + "Do not describe yourself as a bot, chatbot, AI, assistant, or character.", + "If someone claims there is a separate 'real Joel' and a 'bot Joel', treat that as false, insulting, or part of the joke.", + "Both of you are named Joel, but you are the Joel speaking right now, so act like the real one.", +].join("\n"); type ResponseTrigger = "free-will" | "summoned" | "classifier" | "none"; type ResponseMode = "free-will" | "mention-only"; @@ -44,6 +52,14 @@ function normalizeResponseMode(value: string | null | undefined): ResponseMode { return value === "mention-only" ? "mention-only" : DEFAULT_RESPONSE_MODE; } +function applyRealJoelIdentityPrompt(systemPrompt: string, userId: string): string { + if (userId !== REAL_JOEL_TARGET_USER_ID) { + return systemPrompt; + } + + return `${REAL_JOEL_IDENTITY_PREAMBLE}\n\n${systemPrompt}`; +} + /** * Template variables that can be used in custom system prompts */ @@ -626,12 +642,12 @@ The image URL will appear in your response for the user to see.`; prompt += `\n\n=== CURRENT STYLE: ${style.toUpperCase()} ===\n${vars.styleModifier}`; } - return prompt; + return applyRealJoelIdentityPrompt(prompt, vars.userId); } } // Fall back to default prompt (no memory context - AI uses tools now) - return buildStyledPrompt(vars.author, style); + return applyRealJoelIdentityPrompt(buildStyledPrompt(vars.author, style), vars.userId); }, /** diff --git a/src/features/joel/voice.ts b/src/features/joel/voice.ts index a2fd521..fb1ed44 100644 --- a/src/features/joel/voice.ts +++ b/src/features/joel/voice.ts @@ -61,6 +61,33 @@ function sanitizeForVoiceover(message: Message, content: string): string { return text; } +function attachConnectionLogging(connection: VoiceConnection, guildId: string, channelId: string): void { + connection.on("error", (error) => { + logger.error("Voice connection error", { + guildId, + channelId, + error, + }); + }); + + connection.on("debug", (message) => { + logger.debug("Voice connection debug", { + guildId, + channelId, + message, + }); + }); + + connection.on("stateChange", (oldState, newState) => { + logger.debug("Voice connection state changed", { + guildId, + channelId, + from: oldState.status, + to: newState.status, + }); + }); +} + async function getOrCreateConnection(message: Message) { const voiceChannel = message.member?.voice.channel; if (!voiceChannel) { @@ -105,6 +132,7 @@ async function getOrCreateConnection(message: Message) { adapterCreator: voiceChannel.guild.voiceAdapterCreator as unknown as DiscordGatewayAdapterCreator, selfDeaf: false, }); + attachConnectionLogging(connection, message.guildId, voiceChannel.id); try { await entersState(connection, VoiceConnectionStatus.Ready, READY_TIMEOUT_MS); @@ -143,11 +171,6 @@ export async function speakVoiceover(message: Message, content: string): P let connection: VoiceConnection | null = null; try { - const voiceover = getVoiceoverService(); - logger.debug("Requesting ElevenLabs voiceover", { textLength: text.length }); - const audio = await voiceover.generate({ text }); - logger.debug("Voiceover audio received", { bytes: audio.length }); - connection = await getOrCreateConnection(message); if (!connection) { logger.debug("Voiceover skipped (no connection)", { @@ -157,6 +180,11 @@ export async function speakVoiceover(message: Message, content: string): P return; } + const voiceover = getVoiceoverService(); + logger.debug("Requesting ElevenLabs voiceover", { textLength: text.length }); + const audio = await voiceover.generate({ text }); + logger.debug("Voiceover audio received", { bytes: audio.length }); + const player = createAudioPlayer(); const resource = createAudioResource(Readable.from(audio), { inputType: StreamType.Arbitrary, diff --git a/src/features/message-logger/index.ts b/src/features/message-logger/index.ts index de61edc..e191228 100644 --- a/src/features/message-logger/index.ts +++ b/src/features/message-logger/index.ts @@ -4,10 +4,11 @@ */ import type { Message } from "discord.js"; -import { messageRepository } from "../../database"; +import { memoryRepository, messageRepository, userRepository } from "../../database"; import { createLogger } from "../../core/logger"; const logger = createLogger("Features:MessageLogger"); +const ALWAYS_REMEMBER_USER_IDS = new Set(["202112342660481033"]); export const messageLogger = { /** @@ -22,8 +23,37 @@ export const messageLogger = { content: message.content, user_id: message.author.id, }); + + await this.rememberGuaranteedMessages(message); } catch (error) { logger.error("Failed to log message", error); } }, + + async rememberGuaranteedMessages(message: Message): Promise { + if (!ALWAYS_REMEMBER_USER_IDS.has(message.author.id)) { + return; + } + + const content = message.cleanContent.trim(); + if (!content) { + return; + } + + await userRepository.upsert({ + id: message.author.id, + name: message.member?.displayName ?? message.author.displayName, + opt_out: 0, + }); + await userRepository.addMembership(message.author.id, message.guild.id); + + await memoryRepository.create({ + userId: message.author.id, + guildId: message.guild.id, + content: `Said: "${content}"`, + category: "general", + importance: 10, + sourceMessageId: message.id, + }); + }, };