OpenWalrusOpenWalrus

Agents

How OpenWalrus agents work — lifecycle, configuration, execution modes, and stop reasons.

An agent is the core execution unit in OpenWalrus. Each agent wraps an LLM model and can invoke tools. Agents are immutable — conversation history lives in sessions, not in the agent itself.

Agent configuration

Agent configuration has two parts:

Runtime config lives in walrus.toml under [agents.<name>]:

[agents.researcher]
description = "Research specialist"
model = "deepseek-chat"
max_iterations = 32
thinking = true
members = ["walrus"]
skills = ["web-search"]
mcps = ["github"]

[agents.researcher.heartbeat]
interval = 60
prompt = "Check for new tasks"
FieldDescriptionDefault
descriptionHuman-readable description
modelModel name (see providers)Default from config
max_iterationsMaximum tool-use rounds16
thinkingEnable reasoning/thinking modefalse
heartbeat.intervalMinutes between heartbeat ticks (0 = disabled)0
heartbeat.promptMessage sent on each heartbeat tick
membersAgents this agent can delegate to via tasks[] (no delegation)
skillsSkill names this agent can access (empty = all)[]
mcpsMCP server names this agent can access (empty = all)[]
compact_thresholdToken count before auto-compaction100000

System prompts are Markdown files in ~/.openwalrus/agents/:

<!-- ~/.openwalrus/agents/researcher.md -->
You are a research specialist. Find accurate, well-sourced information.

The agent's name comes from the TOML key (e.g., [agents.researcher] → name researcher). A matching .md file in the agents directory provides the system prompt. Agents with a .md file but no TOML entry are registered with default config.

Execution modes

Agents support three execution methods:

Step

Execute a single LLM round — one model call plus any tool dispatches:

let events = agent.step(&tools).await?;

Run

Loop until the agent stops (text response or max iterations):

let response = agent.run(&tools).await?;

Stream

The canonical execution mode. Returns an async stream of events:

let stream = agent.run_stream(&tools);

Agent events

During execution, agents emit events:

EventDescription
TextDeltaIncremental text from the model
ToolCallsStartTool calls initiated
ToolResultA single tool result returned
ToolCallsCompleteAll tool calls finished
DoneAgent has stopped

Stop reasons

An agent stops when one of these conditions is met:

  • TextResponse — the model produced text without requesting tools
  • MaxIterations — reached the configured limit
  • NoAction — the model returned neither text nor tool calls
  • Error — an execution error occurred

Delegation scope

When members is set, the agent gains access to delegation tools (delegate, collect). It can only delegate to the named agents. The agent catalog is provided automatically.

Similarly, skills and mcps restrict which skills and MCP servers the agent can discover and use. An empty list means unrestricted access.

At build time, the runtime computes a tool whitelist from these scopes and injects a <scope> block into the system prompt listing available tools.

Heartbeat

Agents with heartbeat.interval > 0 wake up periodically. On each tick, the daemon dispatches any pending work with the heartbeat prompt.

Concurrency

Agents are stored as immutable values in the runtime. Conversation state lives in sessions, each behind Arc<Mutex<Session>>. Multiple agents run concurrently via tokio::spawn, but a single session processes one request at a time.

See event loop for how events are dispatched across agents.

On this page