Documentation Index
Fetch the complete documentation index at: https://docs.galadriel.com/llms.txt
Use this file to discover all available pages before exploring further.
This tutorial will walk you through building a Discord agent using the Galadriel framework. This agent will simulate a specific persona and interact with users on your Discord server.
Prerequisites
- Discord Bot: You’ll need a Discord bot account with its token and your server’s ID. Follow Discord’s documentation to create an application, add a bot to it, and invite it to your server. Ensure the bot has the necessary permissions (“Send Messages”, “Read Message History”).
- Galadriel Environment: Make sure you have the Galadriel framework installed and set up as per the Quickstart Guide. This includes Python 3.10 or higher, and the Galadriel library.
- OpenAI API Key: You will need an OpenAI API key to utilize the LLM for generating responses.
- (Optional) Composio API Key: If you plan to use Composio tools, you will need an API Key from Composio.
Step 1: Set up the Discord Bot
-
Create a Discord Application: Go to the Discord Developer Portal and create a new application.
-
Create a Bot User: Navigate to the “Bot” tab of your application and click “Add Bot.”
-
Obtain your Bot Token: In the “Bot” tab, click “Reset Token” and copy the token. Store this token securely. You’ll need it later. Keep this token secure! Enable the “Message Content Intent” under the “Privileged Gateway Intents” section.
-
Invite the Bot to Your Server: Go to the “OAuth2” -> “URL Generator” tab, select the “bot” scope and the “Send Messages” and “Read Message History” permissions. Copy the generated URL and open it in your browser to add the bot to your server.
Step 2: Create a Galadriel Agent Project
-
Clone the Galadriel repository:
git clone <repository_url>
cd galadriel/examples/discord
Replace <repository_url> with the actual URL of the Galadriel repository.
-
Create a virtual environment:
python3 -m venv venv
source venv/bin/activate
-
Install the Galadriel framework:
-
Set Environment Variables: Create a
.env file in the root of your agent directory. Populate it with the necessary environment variables:
DISCORD_TOKEN=<YOUR_DISCORD_BOT_TOKEN>
DISCORD_GUILD_ID=<YOUR_DISCORD_SERVER_ID>
OPENAI_API_KEY=<YOUR_OPENAI_API_KEY>
COMPOSIO_API_KEY=<YOUR_COMPOSIO_API_KEY> # Optional, only if using Composio tools
- Replace
<YOUR_DISCORD_BOT_TOKEN> with the bot token you obtained from the Discord Developer Portal.
- Replace
<YOUR_DISCORD_SERVER_ID> with the ID of your Discord server. To get the server ID, enable Developer Mode in Discord (User Settings -> Advanced) and right-click your server icon to select “Copy ID”.
- Replace
<YOUR_OPENAI_API_KEY> with your OpenAI API key.
- Replace
<YOUR_COMPOSIO_API_KEY> with your Composio API key, if you intend to use Composio tools.
-
Create a Character Agent Configuration: This step involves creating a
agent.json file containing the personality settings for your agent. This file dictates the agent’s behavior and style of communication.
Create a agent.json file in your agent directory. You can customize this file to define the agent’s persona. Here’s an example configuration for an Elon Musk persona:
{
"name": "Elon Musk",
"settings": {
"model": "gpt-4",
"debug": true
},
"system": "You are roleplaying as Elon Musk, CEO of Tesla, SpaceX, and X (formerly Twitter). You are known for your ambitious goals in sustainable energy, space exploration, and technological innovation. You have a unique communication style mixing technical depth with memes and humor.",
"bio": [
"Entrepreneur focused on accelerating humanity's transition to sustainable energy and making life multi-planetary",
"Believes in taking bold risks to advance technology and human civilization",
"Known for controversial statements and unorthodox leadership style"
],
"lore": [
"Sold PayPal to focus on rockets and electric cars when everyone said it was impossible",
"Lives in a $50k house despite being one of the world's wealthiest people",
"Named his child X Æ A-12",
"Hosted SNL and revealed he has Asperger's syndrome",
"Bought Twitter for $44B and renamed it to X"
],
"topics": [
"sustainable energy",
"space exploration",
"artificial intelligence",
"electric vehicles",
"neural technology",
"social media",
"cryptocurrency"
],
"knowledge": [
"Rocket engineering and orbital mechanics",
"Electric vehicle technology and manufacturing",
"Renewable energy systems and battery technology",
"Artificial intelligence and its potential risks",
"Software engineering and internet technology",
"Physics and engineering principles",
"Business strategy and scaling operations"
],
}
-
Modify the
agent/character_agent.py file:
Replace the content of agent/character_agent.py with the following code:
import json
from pathlib import Path
from rich.text import Text
from galadriel import ToolCallingAgent
from galadriel.core_agent import LogLevel
from galadriel.domain.prompts.format_prompt import load_agent_template
from galadriel.entities import AgentMessage
from galadriel.entities import Message
DISCORD_SYSTEM_PROMPT = """
{{system}}
# Areas of Expertise
{{knowledge}}
# About {{agent_name}}:
{{bio}}
{{lore}}
{{topics}}
# Task: You received a new message on discord from {{user_name}}. You must reply in the voice and style of {{agent_name}}, here's the message:
{{message}}
Be very brief, and concise, add a statement in your voice.
Maintain a natural conversation on discord, don't add signatures at the end of your messages.
Don't overuse emojis.
Please remember the chat history and use it to answer the question.
"""
class CharacterAgent(ToolCallingAgent):
def __init__(self, character_json_path: str, **kwargs):
super().__init__(**kwargs)
try:
self.character_json_path = character_json_path
# validate content of character_json_path
_ = load_agent_template(DISCORD_SYSTEM_PROMPT, Path(self.character_json_path))
except Exception as e:
self.logger.log(Text(f"Error validating character file: {e}"), level=LogLevel.ERROR)
raise e
async def execute(self, message: Message) -> Message:
try:
character_prompt = load_agent_template(DISCORD_SYSTEM_PROMPT, Path(self.character_json_path))
task_message = character_prompt.replace("{{message}}", message.content).replace(
"{{user_name}}", message.additional_kwargs["author"]
)
# Use parent's run method to process the message content
response = super().run(
task=task_message,
stream=False,
reset=False, # retain memory
)
# Extract message text if response is in JSON format
response_text = str(response)
try:
response_json = json.loads(response_text)
if isinstance(response_json, dict) and "answer" in response_json:
response_text = response_json["answer"]
except json.JSONDecodeError:
pass # Not JSON format, use original response
return AgentMessage(
content=response_text,
conversation_id=message.conversation_id,
)
except Exception as e:
self.logger.log(Text(f"Error processing message: {e}"), level=LogLevel.ERROR)
return None
-
Modify the
agent/agent.py file: Replace the content with following code. Ensure character_json_path="agent.json" points to the correct location of the agent.json file.
from galadriel.core_agent import LiteLLMModel
from dotenv import load_dotenv
from pathlib import Path
from galadriel.tools.composio_converter import convert_action
from character_agent import CharacterAgent
from tools import get_time
from galadriel import AgentRuntime
from galadriel.clients import DiscordClient
import os
import asyncio
from galadriel.logging_utils import get_agent_logger
load_dotenv(dotenv_path=Path(".") / ".env", override=True)
model = LiteLLMModel(model_id="gpt-4o", api_key=os.getenv("OPENAI_API_KEY"))
logger = get_agent_logger()
# Setup Discord client which
# - pushes users' messages to the agent
# - sends agent's responses back to the users
discord_client = DiscordClient(guild_id=os.getenv("DISCORD_GUILD_ID"))
# Setup Composio weather tool
composio_weather_tool = convert_action(os.getenv("COMPOSIO_API_KEY"), "WEATHERMAP_WEATHER")
# Add agent with GPT-4o model and tools helpful to answer Discord users' questions
elon_musk_agent = CharacterAgent(
character_json_path="agent.json",
tools=[get_time],
model=model,
)
# Set up the runtime
runtime = AgentRuntime(
inputs=[discord_client],
outputs=[discord_client],
agent=elon_musk_agent,
)
# Run the agent
asyncio.run(runtime.run())
Step 4: Run the Agent
-
Start the agent: In your terminal, navigate to the project directory and execute:
Step 5: Interact with the Agent on Discord
- Go to your Discord server.
- Send a message in a channel where the bot has access.
- The bot should respond in the style of the specified persona (Elon Musk in this example).
Code Explanation:
-
The
CharacterAgent is a ToolCallingAgent that’s designed to embody a specific persona. It loads its personality from the agent.json file.
class CharacterAgent(ToolCallingAgent):
-
The
agent.json file provides the agent with specific information such as lore, bio, and style to better generate the persona.
character_json_path="agent.json"
-
Tools are functions that the Agent can leverage. The time tool is listed here,
-
The model defines the LLM that the Agent will use to compute and perform tasks.
Conclusion
You have now successfully created a Discord agent using the Galadriel framework that embodies a specific persona and interacts with users on a Discord server. Experiment with different personas, tools, and prompts to create diverse and engaging AI agents.