Skip to content

DiscordRetrieveTool

autogen.tools.experimental.DiscordRetrieveTool #

DiscordRetrieveTool(*, bot_token, channel_name, guild_name)

Bases: Tool

Retrieves messages from a Discord channel.

Initialize the DiscordRetrieveTool.

PARAMETER DESCRIPTION
bot_token

The bot token to use for retrieving messages.

TYPE: str

channel_name

The name of the channel to retrieve messages from.

TYPE: str

guild_name

The name of the guild for the channel.

TYPE: str

Source code in autogen/tools/experimental/messageplatform/discord/discord.py
def __init__(self, *, bot_token: str, channel_name: str, guild_name: str) -> None:
    """
    Initialize the DiscordRetrieveTool.

    Args:
        bot_token: The bot token to use for retrieving messages.
        channel_name: The name of the channel to retrieve messages from.
        guild_name: The name of the guild for the channel.
    """

    async def discord_retrieve_messages(
        bot_token: Annotated[str, Depends(on(bot_token))],
        guild_name: Annotated[str, Depends(on(guild_name))],
        channel_name: Annotated[str, Depends(on(channel_name))],
        messages_since: Annotated[
            Union[str, None],
            "Date to retrieve messages from (ISO format) OR Discord snowflake ID. If None, retrieves latest messages.",
        ] = None,
        maximum_messages: Annotated[
            Union[int, None], "Maximum number of messages to retrieve. If None, retrieves all messages since date."
        ] = None,
    ) -> Any:
        """
        Retrieves messages from a Discord channel.

        Args:
            bot_token: The bot token to use for Discord. (uses dependency injection)
            guild_name: The name of the server. (uses dependency injection)
            channel_name: The name of the channel. (uses dependency injection)
            messages_since: ISO format date string OR Discord snowflake ID, to retrieve messages from. If None, retrieves latest messages.
            maximum_messages: Maximum number of messages to retrieve. If None, retrieves all messages since date.
        """
        intents = Intents.default()
        intents.message_content = True
        intents.guilds = True
        intents.guild_messages = True

        client = Client(intents=intents)
        result_future: asyncio.Future[list[dict[str, Any]]] = asyncio.Future()

        messages_since_date: Union[str, None] = None
        if messages_since is not None:
            if DiscordRetrieveTool._is_snowflake(messages_since):
                messages_since_date = DiscordRetrieveTool._snowflake_to_iso(messages_since)
            else:
                messages_since_date = messages_since

        @client.event  # type: ignore[misc]
        async def on_ready() -> None:
            try:
                messages = []

                # Get guild and channel
                guild = utils.get(client.guilds, name=guild_name)
                if not guild:
                    result_future.set_result([{"error": f"Could not find guild: {guild_name}"}])
                    return

                channel = utils.get(guild.text_channels, name=channel_name)
                if not channel:
                    result_future.set_result([{"error": f"Could not find channel: {channel_name}"}])
                    return

                # Setup retrieval parameters
                last_message_id = None
                messages_retrieved = 0

                # Convert to ISO format
                after_date = None
                if messages_since_date:
                    try:
                        from datetime import datetime

                        after_date = datetime.fromisoformat(messages_since_date)
                    except ValueError:
                        result_future.set_result([
                            {"error": f"Invalid date format: {messages_since_date}. Use ISO format."}
                        ])
                        return

                while True:
                    # Setup fetch options
                    fetch_options = {
                        "limit": MAX_BATCH_RETRIEVE_MESSAGES,
                        "before": last_message_id if last_message_id else None,
                        "after": after_date if after_date else None,
                    }

                    # Fetch batch of messages
                    message_batch = []
                    async for message in channel.history(**fetch_options):  # type: ignore[arg-type]
                        message_batch.append(message)
                        messages_retrieved += 1

                        # Check if we've reached the maximum
                        if maximum_messages and messages_retrieved >= maximum_messages:
                            break

                    if not message_batch:
                        break

                    # Process messages
                    for msg in message_batch:
                        messages.append({
                            "id": str(msg.id),
                            "content": msg.content,
                            "author": str(msg.author),
                            "timestamp": msg.created_at.isoformat(),
                        })

                    # Update last message ID for pagination
                    last_message_id = message_batch[-1]  # Use message object directly as 'before' parameter

                    # Break if we've reached the maximum
                    if maximum_messages and messages_retrieved >= maximum_messages:
                        break

                result_future.set_result(messages)

            except Exception as e:
                result_future.set_exception(e)
            finally:
                try:
                    await client.close()
                except Exception as e:
                    raise Exception(f"Unable to close Discord client: {e}")

        try:
            await client.start(bot_token)
            return await result_future
        except Exception as e:
            raise Exception(f"Failed to start Discord client: {e}")

    super().__init__(
        name="discord_retrieve",
        description="Retrieves messages from a Discord channel based datetime/message ID and/or number of latest messages.",
        func_or_tool=discord_retrieve_messages,
    )

name property #

name

description property #

description

func property #

func

tool_schema property #

tool_schema

Get the schema for the tool.

This is the preferred way of handling function calls with OpeaAI and compatible frameworks.

function_schema property #

function_schema

Get the schema for the function.

This is the old way of handling function calls with OpenAI and compatible frameworks. It is provided for backward compatibility.

realtime_tool_schema property #

realtime_tool_schema

Get the schema for the tool.

This is the preferred way of handling function calls with OpeaAI and compatible frameworks.

register_for_llm #

register_for_llm(agent)

Registers the tool for use with a ConversableAgent's language model (LLM).

This method registers the tool so that it can be invoked by the agent during interactions with the language model.

PARAMETER DESCRIPTION
agent

The agent to which the tool will be registered.

TYPE: ConversableAgent

Source code in autogen/tools/tool.py
def register_for_llm(self, agent: "ConversableAgent") -> None:
    """Registers the tool for use with a ConversableAgent's language model (LLM).

    This method registers the tool so that it can be invoked by the agent during
    interactions with the language model.

    Args:
        agent (ConversableAgent): The agent to which the tool will be registered.
    """
    agent.register_for_llm()(self)

register_for_execution #

register_for_execution(agent)

Registers the tool for direct execution by a ConversableAgent.

This method registers the tool so that it can be executed by the agent, typically outside of the context of an LLM interaction.

PARAMETER DESCRIPTION
agent

The agent to which the tool will be registered.

TYPE: ConversableAgent

Source code in autogen/tools/tool.py
def register_for_execution(self, agent: "ConversableAgent") -> None:
    """Registers the tool for direct execution by a ConversableAgent.

    This method registers the tool so that it can be executed by the agent,
    typically outside of the context of an LLM interaction.

    Args:
        agent (ConversableAgent): The agent to which the tool will be registered.
    """
    agent.register_for_execution()(self)

register_tool #

register_tool(agent)

Register a tool to be both proposed and executed by an agent.

Equivalent to calling both register_for_llm and register_for_execution with the same agent.

Note: This will not make the agent recommend and execute the call in the one step. If the agent recommends the tool, it will need to be the next agent to speak in order to execute the tool.

PARAMETER DESCRIPTION
agent

The agent to which the tool will be registered.

TYPE: ConversableAgent

Source code in autogen/tools/tool.py
def register_tool(self, agent: "ConversableAgent") -> None:
    """Register a tool to be both proposed and executed by an agent.

    Equivalent to calling both `register_for_llm` and `register_for_execution` with the same agent.

    Note: This will not make the agent recommend and execute the call in the one step. If the agent
    recommends the tool, it will need to be the next agent to speak in order to execute the tool.

    Args:
        agent (ConversableAgent): The agent to which the tool will be registered.
    """
    self.register_for_llm(agent)
    self.register_for_execution(agent)