This tutorial focuses on building a Telegram bot with a specific persona, in this case, Elon Musk. The bot leverages the Galadriel framework to handle message input/output, integrate with a language model, and provide custom tools. This setup allows for interactive and engaging conversations within a Telegram chat.

Features

  • 🤖 Responds to messages in Telegram chats with Elon Musk’s personality
  • 🌤️ Can check weather conditions using the Composio Weather API
  • ⏰ Provides current time information
  • 🔄 Maintains context and can engage in multi-turn conversations

Framework Components Used

This example demonstrates several key features of the Galadriel framework:

  • TelegramClient: Handles Telegram message input/output
  • ToolCallingAgent: Base agent class for handling tool-based interactions
  • LiteLLMModel: Integration with language models via LiteLLM
  • Custom tools:
    • Composio Weather API (converted using convert_action)
    • Time tool

Prerequisites

Before you begin, make sure you have the following:

  • Python 3.10 or higher
  • A Telegram account
  • An OpenAI API key
  • A Composio API key (optional, for weather information)

Step 1: Setting Up Your Environment

  1. Create a new directory for your project:

    mkdir telegram-elon-agent
    cd telegram-elon-agent
    
  2. Create a virtual environment:

    python3 -m venv venv
    source venv/bin/activate
    
  3. Install the Galadriel framework:

    pip install galadriel
    

Step 2: Creating a Telegram Bot

  1. Follow the instructions in this Telegram Bot Tutorial to create a new bot and obtain a token.

Step 3: Setting Up Environment Variables

  1. Create a .env file in your project directory with the following variables:

    OPENAI_API_KEY=<YOUR_OPENAI_API_KEY>
    TELEGRAM_TOKEN=<YOUR_TELEGRAM_BOT_TOKEN>
    COMPOSIO_API_KEY=<YOUR_COMPOSIO_API_KEY> # Optional
    

    Replace the placeholder values with your actual API keys and bot token.

Step 4: Implementing the Telegram Agent

  1. Create a file named agent.py and add the following code:

    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 TelegramClient
    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 Telegram client which
    # - pushes users' messages to the agent
    # - sends agent's responses back to the users
    telegram_client = TelegramClient(token=os.getenv("TELEGRAM_TOKEN"), logger=logger)
    
    # 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=[composio_weather_tool, get_time],
        model=model,
    )
    
    # Set up the runtime
    runtime = AgentRuntime(
        inputs=[telegram_client],
        outputs=[telegram_client],
        agent=elon_musk_agent,
    )
    
    # Run the agent
    asyncio.run(runtime.run())
    
  2. Create a file named character_agent.py and add 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
    
    TELEGRAM_SYSTEM_PROMPT = """
    {{system}}
    
    # Areas of Expertise
    {{knowledge}}
    
    # About {{agent_name}}:
    {{bio}}
    {{lore}}
    {{topics}}
    
    # Task: You received a new message on telegram 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 telegram, 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(TELEGRAM_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(TELEGRAM_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
    
  3. Create a file named tools.py and add the following code:

    from galadriel.core_agent import tool
    from datetime import datetime
    
    
    @tool
    def get_time(location: str) -> str:
        """
        Get current time in the given location.
        Args:
            location: the location
        """
        return f"The time in {location} is {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
    
  4. Create a file named agent.json and add the following code:

    {
      "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"
      ],
    }
    

Step 5: Running the Agent

  1. Run the agent.py file:

    python agent.py
    
  2. Start a conversation with your bot on Telegram!

Code Explanation

Dependencies

  • LiteLLMModel: Used for accessing and managing the OpenAI GPT-4o model.
  • TelegramClient: Handles communication with the Telegram bot, sending and receiving messages.
  • ToolCallingAgent: The agent implementation that processes user messages and generates responses.
  • convert_action: Converts Composio actions into Galadriel tools.

Bot Logic

  • The CharacterAgent class extends the ToolCallingAgent to simulate Elon Musk’s persona.
  • The TELEGRAM_SYSTEM_PROMPT template defines the system prompt for the bot, incorporating information from the agent.json file.
  • The execute method handles incoming messages, formats the prompt, and generates a response using the OpenAI GPT-4o model.
  • The Composio and Time tool and used to enhance agent capabilities.

API

Customization

Modifying the Agent’s Persona

  1. Edit the agent.json file to change the agent’s name, system prompt, bio, lore, topics, and style.
  2. Update the TELEGRAM_SYSTEM_PROMPT in character_agent.py to reference the new attributes in agent.json.
  3. Modify the character_json_path variable in the CharacterAgent class to point to the new agent.json file.

Adding New Tools

  1. Create a new Python file for your tool or use one of the available built-in tools from Galadriel or Composio

  2. Import the new tool in agent.py.

  3. Add the new tool to the tools list in the CharacterAgent class.

Running the Agent with Different Clients

  1. Modify the inputs and outputs lists in the AgentRuntime class to use a different client.

  2. Update the client-specific configurations, such as API keys and tokens.

Conclusion

You’ve successfully created a Telegram bot that simulates Elon Musk’s personality using the Galadriel framework. By leveraging different components and customization options, you can create your own unique AI agents that seamlessly integrate with various platforms and provide engaging experiences to users.