FunctionTool for full control.
Quick Start
1
Simple Usage
2
Named Registration
Coming from Python’s
FunctionTool.run? In TypeScript the runtime entry point is the tool() factory — import { tool } from 'praisonai' then tool(myFn). FunctionTool is the underlying class and is not meant to be instantiated directly.Which One Do I Pick?
Three ways to build a tool, from least to most control.Level 1 — Pass a Plain Function
The easiest way — hand the Agent your function directly. The model returns named arguments; the agent maps them onto your function’s parameters, so order doesn’t matter.- Named arguments map to your declared parameter names — order-independent.
- Return values are JSON-serialized before going back to the model. Objects and
nullare safe — no manualJSON.stringify.
Without a
description, the tool advertises itself as Tool: <name> (e.g. Tool: getWeather). Give it a clear description when you want the model to pick the right tool reliably.Level 2 — Register by Name
Register a tool once on the global registry, then look it up anywhere — the sameregister_tool / get_tool names Python uses.
register_tool accepts anything Python accepts — a plain function, a FunctionTool, or a BaseTool-like object with run() / execute().
register_tool writes to the name-keyed registry (the analogue of praisonaiagents/tools/registry.py). If you previously imported register_tool / get_tool from 'praisonai' and passed them tool ids or built instances, you were using the factory registry by accident — see Factory Registry for the one-line migration.Level 3 — Full Control with FunctionTool
Wrap a function in aFunctionTool when you want to validate it, call it directly, or attach approval and retry behaviour.
tool({...}) if you don’t need a class instance — it returns the same FunctionTool:
.run() and .validate()
FunctionTool is not callable as a function. The Agent checks typeof tool === 'function' before the object branch, so a callable FunctionTool would bypass its own approval gate. It is kept intentionally non-callable — call .run() or .execute().Trust Levels
Mark where a tool came from when you register it.TOOL_TRUST_LEVELS is ['trusted', 'external'].
trustLevel throws immediately. Read it back with get_registry().getTrustLevel(name).
Dynamic Schema Overrides
Reshape a parameter’s schema at registration time — useful for injecting enums from runtime state.Multi Agents
Share tools across multiple Agents by passing the same functions:Best Practices
Give every tool a clear description
Give every tool a clear description
Without a
description, the tool advertises as Tool: <name> — the model has less to go on. A one-line description makes tool selection reliable.Validate before you register
Validate before you register
Call
.validate() on a FunctionTool before registration — it throws ToolValidationError listing every problem, so you catch a missing name or bad schema early.Mark external tools 'external'
Mark external tools 'external'
Set
trustLevel: 'external' for user-supplied code and 'trusted' for in-repo tools, so you can audit where a registered tool came from.Reuse the global registry for the common case
Reuse the global registry for the common case
Use
register_tool / get_tool for “I already have my tool”. Reach for the factory registry only when you build instances from user config.Related
Tools
Tool system overview
Factory Registry
Build tool instances from config
Tool Errors
Distinguish missing from broken
MCP Tools
External tool protocols

