Stateful Agents
July 18, 2026 · View on GitHub
By default each run() is independent — the agent has no memory of previous runs. For
conversational or long-lived agents, Conductor offers three complementary mechanisms.
Sessions — multi-turn continuity
Give an agent a sessionId and the server keys conversation continuity to it. Multiple runs that
share a session id form one conversation.
Agent assistant = Agent.builder()
.name("assistant")
.model("anthropic/claude-sonnet-4-6")
.instructions("You are a helpful assistant.")
.sessionId("user-42")
.build();
Stateful mode — durable history + isolation
stateful(true) tells the server to persist conversation history across runs of the same agent.
It also flips on per-execution worker domain isolation: each run gets a unique domain so that
concurrent stateful runs never dequeue each other's tool tasks.
Agent agent = Agent.builder()
.name("hr_assistant")
.model("anthropic/claude-sonnet-4-6")
.instructions("You are an HR assistant. Remember earlier turns.")
.stateful(true)
.build();
// Subsequent runs against this agent see prior exchanges.
A tool can be marked stateful too (ToolDef.builder()...stateful(true)); any stateful tool in the
agent tree triggers the same domain isolation for the whole run.
Conversation memory — seed prior turns
ConversationMemory lets you supply message history up front (e.g. restored from your own store)
and optionally cap how many messages the server retains:
import org.conductoross.conductor.ai.model.ConversationMemory;
ConversationMemory memory = new ConversationMemory(20) // retain at most 20 messages; null = unbounded
.addSystem("You are concise.")
.addUser("My name is Alice.")
.addAssistant("Nice to meet you, Alice.");
Agent agent = Agent.builder()
.name("assistant")
.model("anthropic/claude-sonnet-4-6")
.memory(memory)
.build();
addUser, addAssistant, and addSystem are chainable; each message serializes as
{"role": ..., "message": ...}. Oldest messages beyond maxMessages are trimmed server-side.
Sharing state between tools
Within a single execution, tools can pass data through ToolContext.getState() — a mutable map
that persists across tool calls. See Tools → ToolContext.