Tool Discovery
Beyond registering tools one-by-one with context.register_tool(...) (see
tool steps), CARL 0.3.0 can discover tools in bulk.
The @carl_tool decorator
Section titled “The @carl_tool decorator”Mark functions as discoverable, optionally tagging them:
from mmar_carl import carl_tool
@carl_tooldef search(query: str) -> str: ...
@carl_tool(tags=["information", "external"])def fetch_data(url: str) -> dict: ...Register from disk
Section titled “Register from disk”Load every @carl_tool in files matching a glob in one call:
names = context.register_tools_from_path( "tools/*.py", tag_filter=["information"], # optional: only tools carrying these tags name_prefix="ext_", # optional: namespace the registered names)Discover at runtime as a step
Section titled “Discover at runtime as a step”ToolDiscoveryStepDescription discovers + registers tools mid-chain from a
tool source:
from mmar_carl import ( ToolDiscoveryStepDescription, ToolDiscoveryStepConfig, ModuleToolSource,)
ToolDiscoveryStepDescription( number=1, title="Discover tools", config=ToolDiscoveryStepConfig( source=ModuleToolSource(module="my_pkg.tools", tag="search", name_prefix="x_"), output_memory_key="discovered_tools", ),)Tool sources
Section titled “Tool sources”| Source | Discovers from |
|---|---|
ModuleToolSource(module, name_prefix="", tag="", strip_prefix=…) | A Python module path — scans it for @carl_tool functions. |
CallableToolSource(factory) | A factory() -> {name: callable} you provide. |
DictToolSource(tools) | An explicit {name: callable} dict. |
ToolDiscoveryStepConfig also takes tool_timeout. Discovered tool names are
written to output_memory_key so later steps can see what’s available.
See also
Section titled “See also”- Tool steps — calling registered tools.
ToolDefinition(exported) composes tools programmatically.