fixes for bot-to-bot replie race condition
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"id": "1374708264306212894",
|
||||
"name": "bot-playroom",
|
||||
"user": "aidoll-kuroki-tomoko#2395",
|
||||
"messages": []
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"id": "1374708264306212894",
|
||||
"name": "bot-playroom",
|
||||
"user": "aidoll-nagatoro-hayase#9848",
|
||||
"messages": []
|
||||
}
|
||||
@@ -3,21 +3,6 @@
|
||||
"name": "bot-playroom",
|
||||
"user": "quarterturn",
|
||||
"messages": [
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "U-um... that sounds... interesting. A dating sim, huh? With... bots? Competing for... you? I-I guess... that could be fun... for *you*...",
|
||||
"images": []
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "You don't like it?",
|
||||
"images": []
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "H-hey! What do you mean, 'You don't like it?' I... I thought you were having fun!",
|
||||
"images": []
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Maybe you could even help me write it. Would you like that?",
|
||||
@@ -237,6 +222,36 @@
|
||||
"role": "assistant",
|
||||
"content": "U-um... y-yes! I think... it was... Senren*Banka, right? The one with the, uh, really good music and... and the interesting story? I-I'm pretty sure we were talking about that...",
|
||||
"images": []
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Never heard of Senren Banka. Hmm... what could that mean in Japanese? Senren... life love? Banka... I have no idea.",
|
||||
"images": []
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "U-um... S-Senren Banka... it's a song! From No Longer Human. It's... really good. You should listen to it. I-I mean, if you want to. It's not like I'm trying to force you or anything...",
|
||||
"images": []
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Cool. I will listen to it.\n(Tomoko status: \"acquaintance\" -> \"friends\")",
|
||||
"images": []
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "R-really? You... you will? Th-that's... that's nice. I-I'm glad you think so.",
|
||||
"images": []
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "You're cute!",
|
||||
"images": []
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "U-um... d-did you just...? Th-that's... nice, I guess. B-but don't get any weird ideas!",
|
||||
"images": []
|
||||
}
|
||||
]
|
||||
}
|
||||
7
discord_data/aidoll-kuroki-tomoko-config.json
Normal file
7
discord_data/aidoll-kuroki-tomoko-config.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "User Confirgurations",
|
||||
"options": {
|
||||
"message-style": false,
|
||||
"switch-model": "aidoll-gemma3-12b-q6:latest"
|
||||
}
|
||||
}
|
||||
7
discord_data/aidoll-nagatoro-hayase-config.json
Normal file
7
discord_data/aidoll-nagatoro-hayase-config.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "User Confirgurations",
|
||||
"options": {
|
||||
"message-style": false,
|
||||
"switch-model": "aidoll-gemma3-12b-q6:latest"
|
||||
}
|
||||
}
|
||||
19
example.env
Normal file
19
example.env
Normal file
@@ -0,0 +1,19 @@
|
||||
# Discord token for the bot
|
||||
CLIENT_TOKEN = MTM3MzY5MzcwNjk5Mjg3NzY3OQ.GN4JNU.SumD_y2p2Blh4wXiQ30Ns6XkUFahpESc27R7z8
|
||||
|
||||
# Default model for new users
|
||||
MODEL = aidoll-gemma3-12b-q6:latest
|
||||
|
||||
# ip/port address of docker container, I use 172.33.0.3 for docker, 127.0.0.1 for local
|
||||
OLLAMA_IP = 192.168.0.80
|
||||
OLLAMA_PORT = 11434
|
||||
|
||||
# ip address for discord bot container, I use 172.33.0.2, use different IP than ollama_ip
|
||||
DISCORD_IP = 172.33.0.2
|
||||
|
||||
# subnet address, ex. 172.33.0.0 as we use /16.
|
||||
SUBNET_ADDRESS = 172.33.0.0
|
||||
|
||||
# redis port and ip, default redis port is 6379
|
||||
REDIS_IP = 172.33.0.4
|
||||
REDIS_PORT = 6379
|
||||
@@ -40,6 +40,16 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client
|
||||
const randomChance = Math.random() < 0.1 // 10% chance for non-directed or bot messages
|
||||
if (!isMentioned && !isBotMessage && (isCommand || !randomChance)) return
|
||||
|
||||
// Check if message is a bot response to avoid loops
|
||||
const isBotResponseKey = `message:${message.id}:is_bot_response`
|
||||
if (isBotMessage) {
|
||||
const isBotResponse = await redis.get(isBotResponseKey)
|
||||
if (isBotResponse === 'true') {
|
||||
log(`Skipping bot message ${message.id} as it is a bot response.`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Check cooldown for bot-to-bot responses
|
||||
const botResponseCooldownKey = `bot:${clientId}:last_bot_response`
|
||||
const cooldownPeriod = 60 // 60 seconds cooldown
|
||||
@@ -105,7 +115,8 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client
|
||||
if (config === undefined) {
|
||||
openConfig(`${message.author.username}-config.json`, 'message-style', false)
|
||||
openConfig(`${message.author.username}-config.json`, 'switch-model', defaultModel)
|
||||
reject(new Error('No User Preferences is set up.\n\nCreating preferences file with `message-style` set as `false` for regular message style.\nPlease try chatting again.'))
|
||||
openConfig(`${message.author.username}-config.json`, 'modify-capacity', 50)
|
||||
reject(new Error('No User Preferences is set up.\n\nCreating preferences file with defaults.\nPlease try chatting again.'))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -113,7 +124,8 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client
|
||||
log(`New Capacity found. Setting Context Capacity to ${config.options['modify-capacity']}.`)
|
||||
msgHist.capacity = config.options['modify-capacity']
|
||||
} else {
|
||||
log(`Capacity is undefined, using default capacity of ${msgHist.capacity}.`)
|
||||
log(`Capacity is undefined, using default capacity of 50.`)
|
||||
msgHist.capacity = 50
|
||||
}
|
||||
|
||||
shouldStream = config.options['message-stream'] as boolean || false
|
||||
@@ -137,29 +149,35 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve Channel Messages
|
||||
let chatMessages: UserMessage[] = await new Promise((resolve) => {
|
||||
// Retrieve Channel Messages with Retry
|
||||
let chatMessages: UserMessage[] = []
|
||||
attempt = 0
|
||||
while (attempt < maxRetries) {
|
||||
try {
|
||||
chatMessages = await new Promise((resolve, reject) => {
|
||||
getChannelInfo(`${message.channelId}-${message.author.username}.json`, (channelInfo) => {
|
||||
if (channelInfo?.messages) {
|
||||
resolve(channelInfo.messages)
|
||||
} else {
|
||||
log(`Channel/Thread ${message.channelId}-${message.author.username} does not exist. File will be created shortly...`)
|
||||
resolve([])
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
if (chatMessages.length === 0) {
|
||||
chatMessages = await new Promise((resolve, reject) => {
|
||||
log(`Channel/Thread ${message.channelId}-${message.author.username} does not exist. Creating file...`)
|
||||
openChannelInfo(message.channelId, message.channel as TextChannel, message.author.tag)
|
||||
getChannelInfo(`${message.channelId}-${message.author.username}.json`, (config) => {
|
||||
if (config?.messages) {
|
||||
resolve(config.messages)
|
||||
} else {
|
||||
reject(new Error(`Failed to find ${message.author.username}'s history. Try chatting again.`))
|
||||
reject(new Error('Channel file created, retrying...'))
|
||||
}
|
||||
})
|
||||
})
|
||||
break
|
||||
} catch (error) {
|
||||
++attempt
|
||||
if (attempt < maxRetries) {
|
||||
log(`Attempt ${attempt} failed for Channel Info. Retrying in 500ms...`)
|
||||
await new Promise(ret => setTimeout(ret, 500))
|
||||
} else {
|
||||
log(`Failed to retrieve or create channel history after ${maxRetries} attempts. Using empty history.`)
|
||||
chatMessages = []
|
||||
openChannelInfo(message.channelId, message.channel as TextChannel, message.author.tag, [])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!userConfig) {
|
||||
@@ -334,9 +352,17 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client
|
||||
log(`Updated sentiments - Self: ${(jsonResponse.metadata.self_sentiment || 0).toFixed(2)}, User ${message.author.id}: ${(jsonResponse.metadata.user_sentiment[message.author.id] || 0).toFixed(2)}`)
|
||||
}
|
||||
|
||||
// Send reply to Discord
|
||||
// Send reply to Discord and mark as bot response
|
||||
const reply = jsonResponse.reply || 'Sorry, I didn’t get that. Can you try again?'
|
||||
await message.reply(reply)
|
||||
const replyMessage = await message.reply(reply)
|
||||
if (isBotMessage) {
|
||||
try {
|
||||
await redis.set(`message:${replyMessage.id}:is_bot_response`, 'true', { EX: 3600 }) // 1 hour TTL
|
||||
log(`Marked message ${replyMessage.id} as bot response`)
|
||||
} catch (error) {
|
||||
log(`Failed to mark message as bot response: ${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Update message history
|
||||
while (msgHist.size() >= msgHist.capacity) msgHist.dequeue()
|
||||
|
||||
Reference in New Issue
Block a user