Skip to main content
Conversation history enables agents to maintain context across multiple interactions. By preserving previous messages, agents can reference earlier exchanges and build upon prior context, facilitating natural, context-aware conversations.

Overview

When a conversation history manager is provided to an agent, it performs the following operations:
  • Loads Previous Messages: Automatically retrieves conversation history based on the thread ID
  • Saves Automatically: Persists new messages after each execution

Enabling Conversation History

To enable conversation history, create a history manager with hastekit.NewFileHistory and pass the created instance to the agent’s History field. While invoking the agent, optionally set Namespace to bucket the conversations by namespaces.

Continuing the conversation

To continue the conversation, pass same thread ID while invoking the agent again.
Passing ThreadID alone continues from the thread’s tip.

Branching from an earlier turn

To continue from a specific earlier run instead of the thread’s tip — a retry, or an edit of an earlier message — set PreviousRunID to the RunID of the run you want to continue from:

Reading a thread back

To render a thread — a chat window, an audit view — use LoadTranscript:
It returns the thread as written: every turn, in order, with no summary standing in for any of them.
That is deliberately not what the agent reads for itself. The agent’s own history load is summary-aware — once a thread has been summarized it returns the summary in place of the turns the summary covers, which is what keeps a long conversation inside the context window. Right for the model, wrong for a UI: a chat window hydrating from that view shows the user their own conversation with the early part replaced by a machine-written paragraph, and the turns are still on disk, so nothing signals that anything is missing.
Adapters opt in by implementing history.TranscriptReader; the built-in in-memory and file adapters both do. An adapter that doesn’t falls back to the summary-aware load.

Persistence

The conversation manager supports three persistence configurations for storing conversation history:

1. File Persistence

When the SDK client is initialized without an endpoint, messages are persisted as JSON files written to the disk (under ./conversations).

2. HasteKit Gateway Persistence

When the SDK client is initialized with an endpoint, the conversation manager automatically persists messages to the HasteKit’s Gateway server.

3. Custom Persistence

To implement custom persistence, implement the ConversationPersistenceAdapter interface:
Then pass your implementation to the conversation manager constructor:
When you use hastekit.NewFileHistory("./conversations"), the SDK wires a file-backed adapter that persists messages as JSON on disk. Optionally implement history.TranscriptReader so a UI can read the thread as written, and history.ThreadLister so threads can be enumerated.

Options

Both history.NewConversationManager and hastekit.NewFileHistory take history.ConversationManagerOptions:

Message Filtering

Each stored message bundle (messages.Message) carries a SenderID, which lets the conversation manager attribute turns to a specific participant in multi-participant conversations. You can transform a run’s message bundles before they are attributed and sent to the provider by supplying a MessageFilter. A common use is rewriting each bundle’s SenderID from an opaque id into a human-friendly name.

Attribution

WithMessageAttribution() rewrites messages from senders other than the running agent with (Agent) <sender> said: / (Human) <sender> said: prefixes before they go to the provider. It is off by default, in which case bundles are flattened as-is.

Steering notices

A message that reaches a run after it has started working — delivered with handle.EnqueueMessage, or POSTed to a thread already running over AG-UI — is followed by a short note saying so:
[The message above arrived from the user while this run was already in progress… Treat it as their most recent instruction.]
Without it the two are the same message in the same position, and the model has no way to tell a correction shouted mid-task from the instruction it is already carrying out — so it tends to finish the original plan and address the interruption afterwards, if at all. The note is added to the outgoing message list only. It is never stored, so history keeps exactly the turn the user sent. Turn it off with history.WithoutSteeringNotices() only when something upstream already conveys the distinction, or when an agent’s prompt depends on the exact message sequence.

Listing Threads

agent.History() returns the agent’s *history.CommonConversationManager. When its persistence adapter implements history.ThreadLister, you can enumerate stored threads. Pass an empty namespace ("") to list across all namespaces.

Complete Example

The following example demonstrates an agent with conversation history: