Skip to main content
Cap how many tool-use steps an agent may take before wrapping up with its best final answer. max_steps is the unified outer-loop step budget honoured identically by both tool-execution loops (OpenAI-native and LiteLLM). On the final permitted step the model is asked to wrap up, so you get a coherent answer instead of a hard cut.

Quick Start

1

Raise the budget with a scalar

2

Detect truncation with last_stop_reason


How It Works

On the final permitted step both loops inject an internal user-role message so the model produces a coherent final answer:
“You are approaching the maximum number of tool-use steps for this task. Stop calling tools now and provide your best final answer, summarising the work completed so far and clearly noting anything left incomplete.”
The wrap-up message works on a local copy of the conversation, so it never leaks into the caller’s history.

On the CLI

A step-limit-truncated run through praisonai run / praisonai-code run exits 2 and emits status: "truncated" under --output json, preserving the wrap-up summary in result.
Interactive (non-JSON) mode additionally prints a one-line stderr warning:
See praisonai run → Exit Codes for the full CLI contract.

Choosing a Value


Configuration Options

Full list of options, types, and defaults — ExecutionConfig
Two helpers resolve the effective values:

How it relates to max_tool_calls_per_turn

max_steps bounds outer-loop iterations — one LLM round-trip each. max_tool_calls_per_turn caps how many tool calls the model can fire inside one response. They are independent on purpose: if they were coupled, a single parallel-tool response could exhaust the whole step budget (e.g. max_steps=5 truncating after one round of 5 parallel calls). Set them separately when you need both a long overall budget and a small per-turn burst.
Safe to read on any agent, including LiteLLM-only ones — reading agent.last_stop_reason never lazily creates the OpenAI client. Returns "completed" by default when no run has finished yet.

Common Patterns

Pattern 1 — Raise the budget for long runs

Pattern 2 — Detect and continue after truncation

Pattern 3 — Independent per-turn guardrail


Best Practices

The default (20, via max_iter) is fine for short tasks but truncates deep refactors and multi-step research. Raise max_steps to 50–100 for those.
Check agent.last_stop_reason == "max_steps" instead of parsing the answer text. The old magic "Tool call limit reached" string is now suppressed when a genuine final answer exists.
max_steps and max_tool_calls_per_turn govern different things — a per-turn cap of 5 does not halve your step budget. Coupling them would let one parallel-tool response exhaust the whole budget.
max_steps must be >= 1 when set, otherwise ExecutionConfig raises ValueError. Catch it in config-driven setups.

Execution

Iteration limits, retries, rate limiting, and code execution

Error Handling

Catch and recover from agent, tool, and LLM errors

Turn Completion Notes

Surface the reason to chat users when a turn hits the step limit

praisonai run → Exit Codes

How a truncated run maps to exit 2 and status: "truncated" on the CLI