Examples / Standard Library / Message History

Message History

Has SpecsRequires API Keys

Shows how to manage conversation history with the MessageHistory primitive. This example demonstrates: - Manually injecting system messages with `MessageHistory.inject_system()` - Appending user messages with `MessageHistory.append()` - Retrieving full conversation history with `MessageHistory.get()` - Iterating through messages with `python.iter()` - Tracking conversation length and message roles - Clearing history when needed with `MessageHistory.clear()`

Source Code

-- Message History Demo
-- Demonstrates using the MessageHistory primitive to manage conversation history
-- Aligned with pydantic-ai's message_history concept

chatbot = Agent {
    model = "openai/gpt-4o-mini",
    system_prompt = "You are a helpful chatbot. Answer questions concisely.",
}

-- Procedure with message_history configuration
Procedure {
    input = {
        user_message = field.string{default = "Hello"}
    },
    output = {
        response = field.string{required = true},
        history_length = field.number{required = true}
    },
    function(input)
        Log.info("Message history demo starting")

        -- Manually add a user message to the message history
        MessageHistory.inject_system("You are having a friendly conversation")
        MessageHistory.append({
            role = "user",
            content = input.user_message
        })

        -- Have the agent respond
        chatbot()

        -- Get the conversation history (message_history in pydantic-ai terms)
        local history = MessageHistory.get()

        -- Count messages (Python list doesn't support # operator in Lua).
        -- python.iter(...) may yield either (value) or (index, value) depending on adapter.
        local count = 0
        for a, b in python.iter(history) do
            local msg = b or a
            count = count + 1
            local role = nil
            local content = nil
            pcall(function() role = msg.role end)
            pcall(function() content = msg.content end)
            Log.info("Message " .. count, {role = role, content = content})
        end

        Log.info("Conversation history", {length = count})

        -- Clear history if needed
        -- MessageHistory.clear()

        return {
            response = "Conversation completed",
            history_length = count
        }
    end
}

-- BDD Specifications
Specification([[
Feature: Message History Management
  Demonstrate message history manipulation (aligned with pydantic-ai)

  Scenario: Message history tracks messages
    Given the procedure has started
    And the agent "chatbot" responds with "Hello! How can I help you today?"
    When the procedure runs
    Then the procedure should complete successfully
    And the output history_length should exist
]])

Quick Start

Run the example:

$tactus run 03-standard-library/03-message-history.tac

Test with mocks:

$tactus test 03-standard-library/03-message-history.tac --mock

Note

This example requires API keys. Set your OPENAI_API_KEY environment variable before running.

View source on GitHub →

Explore more examples

Learn Tactus through practical, runnable examples organized by topic.