Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace context AI #106

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
DISCORD_BOT_TOKEN=<discord_bot_token>
DISCORD_SUPPORT_ROLE_ID=<role_id>,<role_id>
CONTEXT_ID=<use_context_id>
ASKAI_CHANNEL=<channel_id_for_askai_bot>
REDIS_SERVER_URL=<REDIS_SERVER_DETAILS>
REDIS_SERVER_URL=<REDIS_SERVER_DETAILS>
THIRDWEB_SECRET_KEY=<THIRDWEB_SECRET_KEY>
NEBULA_API_ENDPOINT=<NEBULA_API_ENDPOINT>
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"license": "GPL-3.0",
"private": true,
"dependencies": {
"@context-labs/sdk": "^0.0.107",
"axios": "^1.7.9",
"discord.js": "^14.14.1",
"dotenv": "^16.0.3",
"fs-extra": "^11.1.1",
Expand All @@ -20,6 +20,5 @@
"ioredis": "^5.4.1",
"moment": "^2.30.1",
"nodemon": "^3.1.0"
},
"devDependencies": {}
}
}
17 changes: 8 additions & 9 deletions src/config.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
{
"command_prefix": "!",
"utc_offset": -8,
"ai_thinking_message": "**🤖 Beep Boop Boop Beep:** <a:load:1210497921158619136> thinking...",
"getting_started_ai_message": "Hello, kindly use \\`!ask\\` or \\`!askai\\` followed by your question to get started.",
"helpful_message": "Thank you so much for your feedback!",
"not_helpful_messsage": "Thank you for your valuable feedback, this will help us improve the responses of our AI assistant.\n\nIn the meantime, would you like to contact a human customer success agent? Just click the link or the button below to submit a ticket.",
"reminder_mention": "Hey there! If you need assistance, please don't hesitate to reach out on our official support platform and create a ticket: https://thirdweb.com/support. Our dedicated team is always ready to help you out. Thank you for choosing to build with us!"
}

"command_prefix": "!",
"utc_offset": -8,
"ai_thinking_message": "Nebula is thinking...",
"getting_started_ai_message": "Hello, kindly use \\`!ask\\` or \\`!askai\\` followed by your question to get started.",
"helpful_message": "Thank you so much for your feedback!",
"not_helpful_messsage": "Thank you for your valuable feedback, this will help us improve the responses of our AI assistant.\n\nIn the meantime, would you like to contact a human customer success agent? Just click the link or the button below to submit a ticket.",
"reminder_mention": "Hey there! If you need assistance, please don't hesitate to reach out on our official support platform and create a ticket: https://thirdweb.com/support. Our dedicated team is always ready to help you out. Thank you for choosing to build with us!"
}
26 changes: 16 additions & 10 deletions src/events/interaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ const {
sendEmbedMessage,
serverTime,
CloseButtonComponent } = require("../utils/core");
const { ContextSDK } = require("@context-labs/sdk");
const { sendAIFeedback } = require("../utils/nebula")
const redis = require("./database");
const config = require("../config.json");
const context = new ContextSDK({});

module.exports = {
name: Events.InteractionCreate,
Expand All @@ -27,10 +26,13 @@ module.exports = {
if (err) {
console.error(err);
} else {
await context.setQueryFeedback({
queryId: result,
helpful: true,
});
const data = JSON.parse(result);

await sendAIFeedback(
data.session_id,
data.request_id,
true,
);
}
});
await interaction.message.edit({ components: [] });
Expand All @@ -41,20 +43,24 @@ module.exports = {
}

if (interaction.customId === "not-helpful") {

await interaction.reply({
embeds: [sendEmbedMessage(config.not_helpful_messsage)],
content: `🔔 <@${interaction.user.id}>`,
ephemeral: true,
components: [CloseButtonComponent()],
});

await redis.get(messageId, async (err, result) => {
if (err) {
console.error(err);
} else {
await context.setQueryFeedback({
queryId: result,
helpful: false,
});
const data = JSON.parse(result);
await sendAIFeedback(
data.session_id,
data.request_id,
true,
);
}
});
await interaction.message.edit({ components: [] });
Expand Down
71 changes: 31 additions & 40 deletions src/events/message.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@ const {
sendEmbedMessage,
serverTime,
FeedbackButtonComponent } = require("../utils/core");

const { getAIResponse } = require("../utils/nebula")
const { version } = require("../../package.json");
const config = require("../config.json");
const redis = require("./database");
const { ContextSDK } = require("@context-labs/sdk");

// discord bot env
const {
DISCORD_SUPPORT_ROLE_ID,
ASKAI_CHANNEL,
CONTEXT_ID } = process.env;
ASKAI_CHANNEL} = process.env;
const roleIDs = DISCORD_SUPPORT_ROLE_ID.split(",");

const context = new ContextSDK({});

module.exports = {
name: Events.MessageCreate,
Expand Down Expand Up @@ -68,42 +67,34 @@ module.exports = {
let aiMessageLoading = await message.channel.send({
embeds: [sendEmbedMessage(config.ai_thinking_message)],
});

await context.query({
botId: CONTEXT_ID,
query: question,
onComplete: async (query) => {
// respond to the user with the answer from the AI
await message.channel.messages.fetch(aiMessageLoading.id).then((msg) => {
msg.edit({
content: `Hey <@${message.author.id}> 👇`,
embeds: [
sendEmbedMessage(`**Response:**\n${query.output.toString()}`),
],
components: [FeedbackButtonComponent()],

})
redis.set(msg.id, query._id);
}
);

},
onError: async (error) => {
console.error(error);

// send a message indicates unseccesful response from the AI
await message.channel.messages.fetch(aiMessageLoading.id).then((msg) =>
msg.edit({
content: `Hey <@${message.author.id}> 👇`,
embeds: [
sendEmbedMessage(`**Response:**\nI'm sorry, I couldn't find a response to your question. Please try again later.`),
],

})
);

},
});
let response = await getAIResponse(question)
await message.channel.messages.fetch(aiMessageLoading.id).then((msg) => {
msg.edit({
content: `Hey <@${message.author.id}> 👇`,
embeds: [
sendEmbedMessage(`${response.message}`),
],
components: [FeedbackButtonComponent()],

})
const data = {
request_id: response.request_id,
session_id: response.session_id,
};
redis.set(msg.id, JSON.stringify(data));
}
);
// to do
// send a message indicates unseccesful response from the AI
// await message.channel.messages.fetch(aiMessageLoading.id).then((msg) =>
// msg.edit({
// content: `Hey <@${message.author.id}> 👇`,
// embeds: [
// sendEmbedMessage(`**Response:**\nI'm sorry, I couldn't find a response to your question. Please try again later.`),
// ],

// })
// );

} else {
// if the command is not from the channel
Expand Down
29 changes: 20 additions & 9 deletions src/utils/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,27 @@ const config = require('../config.json');
* @returns pre-defined embed style
*/
const sendEmbedMessage = (message) => {
return new EmbedBuilder()
.setDescription(message)
.setColor(`#f213a4`)
.addFields(
{ name: 'Need Help?', value: 'Submit a ticket here: https://thirdweb.com/support', inline: false}
)
.setTimestamp()
.setFooter({ text: 'thirdweb', iconURL: 'https://ipfs.io/ipfs/QmTWMy6Dw1PDyMxHxNcmDmPE8zqFCQMfD6m2feHVY89zgu/Icon/Favicon-01.png' });
return new EmbedBuilder()
.setTitle('Nebula Response')
.setDescription(message)
.setColor('#f213a4')
.setThumbnail('https://ipfs.io/ipfs/QmTWMy6Dw1PDyMxHxNcmDmPE8zqFCQMfD6m2feHVY89zgu/Icon/Favicon-01.png') // Nebula thumbnail
.addFields(
{
name: 'Nebula Features',
value: '🔗 Proprietary Blockchain Model\n⚡ Execute Transactions with Ease\n🔐 Seamless Wallet Integration\n🛠️ Easy-to-use API\n🤖 Autonomous Agents for EVM Chains',
inline: false
}
)
.setTimestamp()
.setFooter({
text: 'Powered by thirdweb - Nebula | Disclaimer: Nebula may make mistakes. Please use with discretion.',
iconURL: 'https://ipfs.io/ipfs/QmTWMy6Dw1PDyMxHxNcmDmPE8zqFCQMfD6m2feHVY89zgu/Icon/Favicon-01.png'
});
};



}
/**
* close buttons
* @param {string} message
Expand Down
45 changes: 45 additions & 0 deletions src/utils/nebula.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const axios = require('axios');

const { THIRDWEB_SECRET_KEY, NEBULA_API_ENDPOINT } = process.env;

async function getAIResponse(query) {
try {
const response = await axios.post(NEBULA_API_ENDPOINT + '/chat', {
message: query
}, {
headers: {
'Content-Type': 'application/json',
'x-secret-key': THIRDWEB_SECRET_KEY
}
});


const data = response.data;

return data; // Return the data for further use
} catch (error) {
console.error('Error:', error);
throw error; // Re-throw the error for handling in the calling function
}
}

async function sendAIFeedback(session_id, request_id, helpful) {


const response = await axios.post(NEBULA_API_ENDPOINT + '/feedback', {
feedback_rating: helpful ? 1 : -1,
request_id: request_id,
session_id: session_id

}, {
headers: {
'Content-Type': 'application/json',
'x-secret-key': THIRDWEB_SECRET_KEY
}
});
return response


}

module.exports = { getAIResponse, sendAIFeedback };