This commit is contained in:
1tzEmerald committed 2026-03-27 16:25:59 +00:00
1 parent 15b780ab62
commit 78b804176a
3 files changed
+200 -23

No files matched your search

+11 -1
View File
@@ -10,7 +10,7 @@ Enabled: true
General:
Provider: "openai"
Model: "gpt-5.4"
Model_API_Key: "MODEL_API_KEY"
Model_API_Key: "AI_API_KEY"
# Providers Available:
# "openai" - Use OpenAI's GPT models. Example: "gpt-5.4" "gpt-5-mini"
# "groq" - Use Groq's GroqAI models. Example: "meta-llama/llama-4-scout-17b-16e-instruct"
@@ -43,8 +43,18 @@ Embed:
Memory:
Enabled: true
StoreFacts: true
# StoreFacts - Enables saving important facts the AI learns.
StoreSummaries: true
# StoreSummaries - Enables saving conversation summaries.
MaxRecentMessages: 15
# MaxRecentMessages - Number of recent messages used for context.
Scope: "guild" # channel | guild
# Available Scopes for Memory:
# "channel" - Memory is per channel only.
# "guild" - Memory is shared across the server.
CustomInstructions:
- "You are SupportBot AI made by Emerald Services"
+47 -20
View File
@@ -113,10 +113,11 @@ function buildSystemPrompt(message) {
return sections.join("\n- ").replace(/^/, "- ");
}
function buildConversationFromMemory(channelId, currentMessage) {
function buildConversationFromMemory(currentMessage) {
const memoryConfig = supportbotai.Memory || {};
const memoryEnabled = memoryConfig.Enabled !== false;
const maxRecentMessages = memoryConfig.MaxRecentMessages || 15;
const memoryScope = String(memoryConfig.Scope || "guild").toLowerCase();
const conversation = [
{
@@ -127,32 +128,61 @@ function buildConversationFromMemory(channelId, currentMessage) {
if (!memoryEnabled) return conversation;
const recentMessages = AIDatabase.getRecentMessages(
channelId,
maxRecentMessages,
);
const recentMessages =
typeof AIDatabase.getRecentMessagesByScope === "function"
? AIDatabase.getRecentMessagesByScope({
guildId: currentMessage.guild?.id || null,
channelId: currentMessage.channel?.id || null,
limit: maxRecentMessages,
scope: memoryScope,
})
: AIDatabase.getRecentMessages(
currentMessage.channel?.id,
maxRecentMessages,
);
const latestSummary =
memoryConfig.StoreSummaries !== false
? AIDatabase.getLatestSummary(channelId)
? typeof AIDatabase.getLatestSummaryByScope === "function"
? AIDatabase.getLatestSummaryByScope({
guildId: currentMessage.guild?.id || null,
channelId: currentMessage.channel?.id || null,
scope: memoryScope,
})
: AIDatabase.getLatestSummary(currentMessage.channel?.id)
: null;
const facts =
memoryConfig.StoreFacts !== false ? AIDatabase.getFacts(channelId) : [];
memoryConfig.StoreFacts !== false
? typeof AIDatabase.getFactsByScope === "function"
? AIDatabase.getFactsByScope({
guildId: currentMessage.guild?.id || null,
channelId: currentMessage.channel?.id || null,
scope: memoryScope,
})
: AIDatabase.getFacts(currentMessage.channel?.id)
: [];
const userFacts =
memoryConfig.StoreFacts !== false &&
typeof AIDatabase.getUserFacts === "function"
? AIDatabase.getUserFacts(
currentMessage.guild?.id,
currentMessage.author?.id,
)
: [];
typeof AIDatabase.getUserFactsByScope === "function"
? AIDatabase.getUserFactsByScope({
guildId: currentMessage.guild?.id || null,
userId: currentMessage.author?.id || null,
scope: memoryScope,
})
: memoryConfig.StoreFacts !== false &&
typeof AIDatabase.getUserFacts === "function"
? AIDatabase.getUserFacts(
currentMessage.guild?.id,
currentMessage.author?.id,
)
: [];
if (latestSummary?.summary) {
conversation.push({
role: "system",
content: `Conversation summary:\n${latestSummary.summary}`,
content: `Shared memory summary (${memoryScope} scope):\n${latestSummary.summary}`,
});
}
@@ -165,7 +195,7 @@ function buildConversationFromMemory(channelId, currentMessage) {
conversation.push({
role: "system",
content: `Known facts in this chat:\n${factText}`,
content: `Known shared facts (${memoryScope} scope):\n${factText}`,
});
}
@@ -422,10 +452,7 @@ module.exports = new Event("messageCreate", async (client, message) => {
const ticket = getTicketContextForMessage(message);
const conversation = buildConversationFromMemory(
message.channel.id,
message,
);
const conversation = buildConversationFromMemory(message);
if (ticket) {
conversation.push({
@@ -532,4 +559,4 @@ module.exports = new Event("messageCreate", async (client, message) => {
message.reply({ embeds: [embed] }).catch(() => {});
}
});
});
+142 -2
View File
@@ -85,7 +85,6 @@ try {
}
module.exports = {
saveUserFact({ guildId, userId, factType, factKey, factValue }) {
const existing = db
.prepare(
@@ -138,6 +137,32 @@ module.exports = {
.all(guildId || null, userId || null);
},
getUserFactsByScope({ guildId = null, userId = null, scope = "guild" }) {
if (!userId) return [];
if (scope === "global") {
return db
.prepare(
`
SELECT * FROM ai_facts
WHERE user_id IS ?
ORDER BY updated_at DESC
`,
)
.all(userId || null);
}
return db
.prepare(
`
SELECT * FROM ai_facts
WHERE guild_id IS ? AND user_id IS ?
ORDER BY updated_at DESC
`,
)
.all(guildId || null, userId || null);
},
addMessage({ guildId, channelId, userId, role, content }) {
db.prepare(
`
@@ -169,6 +194,47 @@ module.exports = {
.reverse();
},
getRecentMessagesByScope({ guildId = null, channelId = null, limit = 15, scope = "guild" }) {
if (scope === "channel") {
return db
.prepare(
`
SELECT * FROM ai_conversations
WHERE channel_id = ?
ORDER BY created_at DESC
LIMIT ?
`,
)
.all(channelId || null, limit)
.reverse();
}
if (scope === "global") {
return db
.prepare(
`
SELECT * FROM ai_conversations
ORDER BY created_at DESC
LIMIT ?
`,
)
.all(limit)
.reverse();
}
return db
.prepare(
`
SELECT * FROM ai_conversations
WHERE guild_id IS ?
ORDER BY created_at DESC
LIMIT ?
`,
)
.all(guildId || null, limit)
.reverse();
},
saveSummary({ guildId, channelId, summary }) {
const existing = db
.prepare(
@@ -214,6 +280,44 @@ module.exports = {
.get(channelId);
},
getLatestSummaryByScope({ guildId = null, channelId = null, scope = "guild" }) {
if (scope === "channel") {
return db
.prepare(
`
SELECT * FROM ai_summaries
WHERE channel_id = ?
ORDER BY updated_at DESC
LIMIT 1
`,
)
.get(channelId || null);
}
if (scope === "global") {
return db
.prepare(
`
SELECT * FROM ai_summaries
ORDER BY updated_at DESC
LIMIT 1
`,
)
.get();
}
return db
.prepare(
`
SELECT * FROM ai_summaries
WHERE guild_id IS ?
ORDER BY updated_at DESC
LIMIT 1
`,
)
.get(guildId || null);
},
saveFact({ guildId, channelId, factType, factKey, factValue }) {
const existing = db
.prepare(
@@ -265,6 +369,42 @@ module.exports = {
.all(channelId);
},
getFactsByScope({ guildId = null, channelId = null, scope = "guild" }) {
if (scope === "channel") {
return db
.prepare(
`
SELECT * FROM ai_facts
WHERE channel_id = ? AND user_id IS NULL
ORDER BY updated_at DESC
`,
)
.all(channelId || null);
}
if (scope === "global") {
return db
.prepare(
`
SELECT * FROM ai_facts
WHERE user_id IS NULL
ORDER BY updated_at DESC
`,
)
.all();
}
return db
.prepare(
`
SELECT * FROM ai_facts
WHERE guild_id IS ? AND user_id IS NULL
ORDER BY updated_at DESC
`,
)
.all(guildId || null);
},
addKnowledge({ sourceType, sourceName, title, content }) {
db.prepare(
`
@@ -286,4 +426,4 @@ module.exports = {
)
.all(limit);
},
};
};