Choose a kind
ExtensionKind fixes what your branch’s input schema may be:
WRAPPER— presents the wrapped tool’s input schema unchanged, apart from its own declared control kwargs. Stackable. Use it to add a cross-cutting behaviour (caching, metering, routing) without changing the tool’s inputs.TRANSFORMER— presents its own composed input schema, built withmakefun.create_function. Stackable, applied left to right. Use it when the branch takes different inputs (batching a tool over a list, chaining two tools).BACKEND— one strategy per tool; no input-schema rule.
Register through the handle
Decorate a factory with@tai42_app.extensions.extension, naming the kind and the extension name. The factory returns a new callable named <tool>_<extension>.
examples/extension/retry_wrapper.py
Declare a wrapper’s control kwargs
A wrapper may add control kwargs for itself. Declare them as areserved_params frozenset on the factory; the apply site subtracts each name from the branch’s derived schema before checking that the wrapper preserved the wrapped tool’s schema. The retry wrapper above adds one attempts control kwarg — its reserved_params names the kwarg the apply site excludes before the schema-preservation check.
A reserved param’s type must be schema-inline (a primitive or a plain container of primitives), and a reserved name that also appears on the wrapped tool’s signature is a hard error at apply time.
Load it
The host enables an extension module underextensions_modules, then a tool attaches it through its extensions map. See Apply an extension.
manifest.yml
Shipped implementations
tai42-toolbox—cache,proxy, andprometheus_metrics(wrappers);batch,chain, andoutput_schema(transformers).
See also
- Tools and extensions — the extension model and stacking rules.
- Apply an extension — attach one to a tool.
- Python SDK reference —
ExtensionKindand thetai42_app.extensionssurface. - Ecosystem catalog — every shipped extension.

