Skip to main content
The HistoryTools class provides agents with the ability to read and analyze Discord chat history from the current channel.

Overview

HistoryTools enables agents to:
  • Fetch recent messages from the current Discord channel
  • Access cached conversation history
  • Query past conversations and user interactions
  • Provide context-aware responses based on chat history

Installation

HistoryTools is part of the core Junkie toolkit and requires:
from tools.history_tools import HistoryTools
Dependencies:
  • agno.tools.Toolkit
  • discord_bot.context_cache
  • core.execution_context
  • core.database

HistoryTools Class

Initialization

from tools.history_tools import HistoryTools

history_tools = HistoryTools()
No parameters required. The toolkit automatically registers the read_chat_history method.

Methods

read_chat_history()

Reads the chat history for the current channel from the cache and database.
history = await history_tools.read_chat_history(limit=2000)
print(history)
limit
int
default:"2000"
Maximum number of messages to return. Defaults to 2000.
Returns: str - The chat history as a formatted string, or an error message if no history is found. Format: Each message is formatted as:
{timestamp} {author_name}({author_id}): {content}

Implementation Details

Execution Context

HistoryTools relies on the execution context to determine the current channel:
from core.execution_context import get_current_channel_id, get_current_channel

# Preferred: Get channel object
channel = get_current_channel()

# Fallback: Get channel ID
channel_id = get_current_channel_id()

Data Sources

HistoryTools uses two data sources:
  1. Context Cache (Primary): Fast in-memory cache via get_recent_context()
  2. Database (Fallback): PostgreSQL database via get_messages()
from discord_bot.context_cache import get_recent_context
from core.database import get_messages

# Primary: Fetch from cache
history_lines = await get_recent_context(channel, limit=limit)

# Fallback: Fetch from database
db_messages = await get_messages(channel_id, limit)

Error Handling

The method handles several error scenarios:
if not channel:
    return "Error: No execution context found. Cannot determine channel."

try:
    history_lines = await get_recent_context(channel, limit=limit)
    return "\n".join(history_lines)
except Exception as e:
    logger.error(f"Error fetching history: {e}", exc_info=True)
    return f"Error fetching history: {str(e)}"

Agent Integration

Integrating HistoryTools with Agno agents:
from agno.agent import Agent
from agno.models.openai import OpenAILike
from tools.history_tools import HistoryTools

context_qna_agent = Agent(
    id="context-qna-agent",
    name="Chat Context Q&A",
    role="Answering questions about users, topics, and past conversations",
    model=OpenAILike(
        id="gpt-4-turbo",
        max_tokens=8000,
        temperature=0.3,
        base_url="https://your-api.com",
        api_key="your-key",
    ),
    tools=[HistoryTools()],
    instructions="""
    You specialize in answering questions about chat history, users, and topics.
    
    Always call `read_chat_history` before answering questions.
    IMPORTANT: Fetch a minimum of 5000 messages on first try.
    
    Use the history to:
    - Answer "who said what" questions
    - Summarize discussions on specific topics
    - Track when topics were last mentioned
    - Identify user opinions and statements
    - Provide context about past conversations
    
    Be precise with timestamps and attribute statements accurately.
    """
)

Usage Examples

Basic History Query

history_tools = HistoryTools()

# Fetch last 1000 messages
history = await history_tools.read_chat_history(limit=1000)
print(history)

With Agent

from tools.history_tools import HistoryTools
from tools.bio_tools import BioTools

# Combine with BioTools for comprehensive user context
context_agent = Agent(
    name="Context Agent",
    model=my_model,
    tools=[HistoryTools(), BioTools(client=discord_client)],
    instructions="Use chat history and user details to answer questions."
)

Agent Factory Implementation

From agent_factory.py:264-290:
context_qna_agent = Agent(
    id="context-qna-agent",
    name="Chat Context Q&A",
    role="Answering questions about users, topics, and past conversations",
    model=OpenAILike(
        id=CONTEXT_AGENT_MODEL,
        max_tokens=8000,
        temperature=0.3,
        base_url=PROVIDER,
        api_key=CUSTOM_PROVIDER_API_KEY,
    ),
    tools=[HistoryTools(), BioTools(client=client)],
    add_datetime_to_context=True,
    timezone_identifier="Asia/Kolkata",
    instructions="""
    You specialize in answering questions about the chat history, users, and topics discussed.

    You have access to `read_chat_history`. Call this tool to get the conversation history before answering questions.
    IMPORTANT: always fetch a minimum of 5000 messages on first try.
    Use the history to:
    - Answer "who said what" questions
    - Summarize discussions on specific topics
    - Track when topics were last mentioned
    - Identify user opinions and statements
    - Provide context about past conversations

    Be precise with timestamps and attribute statements accurately to users.
    """
)

Database Schema

Messages are stored with the following fields:
{
    'timestamp_str': '2024-03-15 14:30:00',
    'author_name': 'JohnDoe',
    'author_id': '123456789',
    'content': 'Hello, world!'
}

Best Practices

  • Start with at least 5000 messages for comprehensive context
  • Use smaller limits (500-1000) for recent conversations only
  • Maximum limit is 2000 by default
  • Consider pagination for very large histories
  • Cache hits are much faster than database queries
  • Limit impacts memory usage and processing time
  • Use get_recent_context() for active channels (cache hit)
  • Fallback to database is slower but more reliable
  • Always check for execution context before calling
  • Handle “No history found” gracefully
  • Log errors with full stack traces
  • Provide user-friendly error messages
  • Always instruct agents to call read_chat_history first
  • Specify minimum message counts in instructions
  • Emphasize accuracy in attribution and timestamps
  • Combine with BioTools for user context

Common Use Cases

User Questions

# "What did Alice say about the project?"
# Agent calls read_chat_history(limit=5000)
# Searches for messages from Alice containing "project"

Topic Tracking

# "When was React last discussed?"
# Agent calls read_chat_history(limit=5000)
# Finds most recent message mentioning "React"

Conversation Summarization

# "Summarize today's discussion"
# Agent calls read_chat_history(limit=1000)
# Analyzes recent messages and creates summary

Logging

HistoryTools uses Python’s logging module:
import logging

logger = logging.getLogger(__name__)

# Log levels used:
logger.info(f"Fetching history for channel {channel.id} with limit {limit}")
logger.warning(f"Channel object missing, falling back to DB-only for ID {channel_id}")
logger.error(f"Error fetching history: {e}", exc_info=True)

See Also

Bio Tools

Get Discord user details and avatars

Execution Context

Learn about execution context management

Build docs developers (and LLMs) love