Skip to main content
When the model calls WebSearch but your tool is registered as web_search, PraisonAI fixes the name automatically — and when it can’t, it tells the model exactly which tools exist and how to call them.

Quick Start

1

Case and separator drift auto-fixes

Both dispatch to web_search. No configuration required.
2

Unknown names return a corrective message

The message is what the model sees, so on the next turn it retries with a valid name.
3

Bind failures echo the parameters

The model learns which arguments to send next. This hint fires only when the kwargs cannot bind — a genuine argument-binding error.
4

Value errors pass through unchanged

The kwargs bound cleanly, so the model isn’t told to change the parameter names — it’s told to fix the value.
No new API and no new Agent(...) parameter. Self-repair is a runtime behavior of the existing tool-dispatch path, triggered whenever an LLM tool call arrives.

How It Works

Every tool call runs through Agent.execute_tool; a dispatch miss triggers normalisation, repair, or a corrective error before the result returns to the model. Normalisation compares str(name).lower().replace('_', '').replace('-', '').replace(' ', ''). Repair fires only when exactly one active tool normalises to the same key — ambiguous matches skip repair and fall through to the corrective error, so there is never an ambiguous dispatch.

Four failure modes, four responses

Silent auto-fix. The tool runs and returns its normal result. A debug log records the repair:

Why the hints reach the model

ToolExecutionError preserves only its message through conversion, so the corrective payload is folded into the message string itself.
The Did you mean '<nearest>'? hint and the Available tools: [...] list live inside the error string, so the follow-up model turn sees them via the raised ToolExecutionError.message.
The bind-failure branch appends Expected parameters for '<tool>' — required: [...], optional: [...]. to the message string. The same names are also returned as a structured expected_parameters dict on the impl-level result.
A TypeError or ValueError raised inside a successfully-bound tool is a value problem, not a parameter problem. The runtime gates the schema hint on inspect.signature(target).bind(**kwargs) — the required/optional names only appear in the error message when the kwargs actually failed to bind. Otherwise the tool’s own error string reaches the model unchanged, so the model fixes the value instead of renaming the parameters.
No new public API, no new Agent parameters, and no new environment variables. The prior behavior on unknown tools was a bare Tool 'X' is not callable — not a stable contract, so no valid callers depended on it. When signature introspection itself is impossible (e.g. a C-implemented callable), the gate fails closed — it omits the hint rather than echo a misleading one.

MCP tools participate too

MCP-container tools are expanded into their contained tools, so their names appear in the corrective inventory and can be name-repaired — not just the opaque MCP container.
If none of the MCP tools match, the corrective error’s Available tools: list contains the MCP-provided tool names instead of the container. Only MCP instances that iterate into per-tool callables exposing __name__ or name benefit — the standard praisonaiagents.mcp.MCP satisfies this.

Init-time vs runtime

Two resolvers cover two different moments. Self-repair complements — it does not replace — init-time Tool Resolution.

Tool Resolution

Init-time typo detection when you pass tool names to Agent(tools=[...])

Error Handling

Catch and act on ToolExecutionError and other structured errors

MCP

Connect model-context-protocol servers as tools

Allowed Tools

Restrict which tools an agent can call