How to Manage Step Limits for Agents in OpenClaude: A Complete Guide
OpenClaude caps agent tool-use actions by configuring an agentStepLimit object with a maxSteps value, which triggers automatic enforcement and summary generation when the ceiling is reached.
The Gitlawb/openclaude repository provides built-in safeguards to prevent runaway agent loops through deterministic step limiting. By configuring agent step limits, you establish a hard ceiling on tool invocations per query, ensuring predictable resource consumption and forcing concise final summaries when budgets exhaust.
Understanding Agent Step Limits
Agent step limits in OpenClaude function as a protective boundary around tool-use operations. Rather than allowing an agent to invoke tools indefinitely, the system tracks each execution against a configured maximum and halts further processing once the threshold is reached.
This mechanism delivers three critical guarantees:
- Safety – Prevents infinite loops that could exhaust API quotas or hang CLI sessions.
- Predictability – Establishes an upper bound on LLM-driven tool calls for cost control.
- Deterministic summarization – Forces the model to generate a final answer without additional tool invocations once the budget depletes.
Configuring Step Limits at Query Time
To enable step limiting, pass an agentStepLimit object when initializing a query. This configuration undergoes normalization before execution begins.
The agentStepLimit Object Structure
The configuration accepts two properties:
maxSteps(required integer) – The absolute maximum number of tool calls permitted.agentType(optional string) – A classifier for the agent variant (e.g.,'general-purpose','explorer').
If maxSteps is omitted, non-integer, or less than or equal to zero, the system ignores the limit entirely.
Normalization Logic
The function normalizeAgentStepLimit in src/query.ts validates and sanitizes the input configuration. This ensures that only valid integer ceilings propagate through the execution pipeline, preventing malformed configurations from causing runtime errors.
import { OpenClaude } from '@gitlawb/openclaude/sdk';
const client = new OpenClaude({ apiKey: process.env.OPENCLAUDE_API_KEY });
const response = await client.query({
prompt: 'Analyze this repository and list its major components.',
agentStepLimit: { maxSteps: 4, agentType: 'general-purpose' },
});
Runtime Enforcement and State Tracking
Once normalized, OpenClaude instantiates an AgentStepLimitState object that persists alongside the query context. This state tracks the remaining budget and enforcement flags throughout the execution lifecycle.
State Management
The state object maintains three key fields:
maxSteps– The configured ceiling from initialization.stepsUsed– A counter incrementing with each tool execution.summaryRequested– A boolean flag set when the limit triggers.
The main query loop updates this state every iteration around line 2678 in src/query.ts, ensuring real-time accuracy as tool calls dispatch.
Enforcement Checks
Before each batch of tool calls executes, the system evaluates:
if (agentStepLimit && agentStepLimit.summaryRequested) {
// stop executing further tools
}
If the remaining steps (calculated as maxSteps - stepsUsed) are insufficient for the upcoming batch, the limit activates immediately.
Synthetic Tool Result Generation
When the step limit triggers, OpenClaude synthesizes a specialized tool-result message rather than allowing a partial execution. The helper function createAgentStepLimitToolResult in src/query.ts constructs this payload.
Message Structure
The synthetic result contains:
- A fixed prefix
Agent step limit reached(defined insrc/query/agentStepLimit.ts). - The agent identifier and progress counter (e.g.,
(3/5 tool uses)). - Instructions directing the LLM to cease tool use and return a final summary.
The resulting UserMessage carries the flag isAgentStepLimitToolResult: true, enabling downstream logic to distinguish synthetic limits from genuine tool failures.
Summary Request Handling
After limit activation, the function createAgentStepLimitSummaryRequest emits a final system message. This notification explicitly informs the model that the agent reached its configured step limit after exhausting the tool-use budget, compelling the LLM to produce a concluding answer without further tool invocations.
You can programmatically detect this condition by inspecting response messages:
if (response.toolResults?.some(r => r.content?.startsWith('Agent step limit reached'))) {
console.log('Step limit triggered – final summary follows.');
}
Propagation to Sub-Agents
Step limits cascade through agent hierarchies automatically. When a parent agent spawns a sub-agent via the AgentTool execution path, the configuration propagates through src/tools/AgentTool/runAgent.ts at line 832.
This inheritance ensures that nested calls respect the same budget constraints as their parent, preventing sub-agents from circumventing limits through delegation.
Sub-Agent Configuration Example
await client.query({
prompt: 'Run a sub-agent to explore the file tree.',
agentStepLimit: { maxSteps: 2, agentType: 'explorer' },
});
The sub-agent stops after two tool calls and returns a summary of its exploration, regardless of whether additional work remains pending.
Summary
Managing agent step limits in OpenClaude requires understanding the configuration interface, runtime state machine, and message synthesis pipeline:
- Pass an
agentStepLimitobject with a validmaxStepsinteger to activate limiting. - The system normalizes input via
normalizeAgentStepLimitinsrc/query.tsand tracks usage throughAgentStepLimitState. - When limits trigger,
createAgentStepLimitToolResultgenerates synthetic messages marked withisAgentStepLimitToolResult: true. - Sub-agents automatically inherit limits through
src/tools/AgentTool/runAgent.ts.
Frequently Asked Questions
What happens if I provide an invalid maxSteps value?
If maxSteps is missing, not an integer, or less than or equal to zero, the normalizeAgentStepLimit function in src/query.ts disregards the configuration entirely. The query executes without step limiting, allowing unlimited tool invocations.
Do sub-agents inherit step limits from parent agents?
Yes. The limit configuration propagates automatically through the AgentTool execution path at line 832 in src/tools/AgentTool/runAgent.ts. Sub-agents receive the same maxSteps ceiling and enforce it independently against their own tool usage.
How can I detect when a step limit was triggered programmatically?
Inspect the response's toolResults array for entries where content starts with the string Agent step limit reached (defined in src/query/agentStepLimit.ts). Alternatively, check for the boolean flag isAgentStepLimitToolResult: true on message objects to identify synthetic limit notifications.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →