ToolInfo model + the AppTools tool/toolkit registration sub-protocol.
Vendor return types (fastmcp Tool, langchain StructuredTool) are TYPE_CHECKING-only.
AppTools is the app.tools namespace of the assembled facade (tai42_contract.app).
DEFAULT_RETRYABLE_KINDS
tai42_contract.tools.retry.DEFAULT_RETRYABLE_KINDS
MAX_ATTEMPTS_CEILING
tai42_contract.tools.retry.MAX_ATTEMPTS_CEILING
NEVER_RETRYABLE_KINDS
tai42_contract.tools.retry.NEVER_RETRYABLE_KINDS
AppTools
tai42_contract.tools.AppTools
Members
tool_title
tai42_contract.tools.AppTools.tool_title
func.
Parameters
get_tool
tai42_contract.tools.AppTools.get_tool
key.
Parameters
get_tools
tai42_contract.tools.AppTools.get_tools
get_client_tools
tai42_contract.tools.AppTools.get_client_tools
names when given.
Parameters
run_tool
tai42_contract.tools.AppTools.run_tool
key with arguments and return its result.
offload_sync runs a synchronous tool body off the event loop in a worker thread.
continues_chain is an in-process seam keyword ONLY (no request model, MCP
argument, or tool argument sets it): when given, the dispatch’s call frame SETS
the ambient call chain to it rather than pushing key, so a continuation
runner restores a parked run’s chain on the one dispatch that resumes it.
extras is likewise an in-process seam keyword ONLY (no request model, MCP
argument, or tool argument sets it): the mapping a door carries into the run it
starts. It is set on the dispatch’s call frame — ambient and read-only for THAT
frame, so the started tool reads it through extras and every nested frame
starts empty. A visit checks the keys against the target’s declaration before the
run; None binds an empty mapping.
Parameters
extras
tai42_contract.tools.AppTools.extras
extras mapping the current run was started with (empty when none).
A door carries author-configured extras into a run; a tool reads the keys it declared
(@app.tools.tool(extras_keys=...)) here. The mapping is read-only and scoped to the
started target’s own frame — every nested dispatch reads an empty mapping, so nothing leaks
down. No request model, MCP argument, or tool argument can set it.
declared_extras
tai42_contract.tools.AppTools.declared_extras
extras keys tool name is declared to read (empty when it declares none).
A preset inherits its base tool’s declared keys. The visit checks a door’s extras against
this set before starting the target and refuses an undeclared key.
Parameters
remove_tool
tai42_contract.tools.AppTools.remove_tool
name.
Parameters
register_tool_info
tai42_contract.tools.AppTools.register_tool_info
name’s extension combos, attaching each combo stack to the base.
Parameters
unregister_tool_info
tai42_contract.tools.AppTools.unregister_tool_info
name.
Parameters
unregister_tool_base
tai42_contract.tools.AppTools.unregister_tool_base
tool_name and return the names removed.
Parameters
tool_refs_extractor
tai42_contract.tools.AppTools.tool_refs_extractor
name registered, or None when it declared none.
Parameters
register_rename_referee
tai42_contract.tools.AppTools.register_rename_referee
ToolRenameReferee consulted before a tool rename.
A plugin holding tool-name references calls this through the tai42_app
handle when its module loads. Every registered referee is asked for the
old name on a rename; any non-empty answer blocks the rename and its
descriptions name the holders. Registering the same provider object twice
raises loudly — a double registration is a plugin bug, never a silent
duplicate consult.
Parameters
register_delete_referee
tai42_contract.tools.AppTools.register_delete_referee
ToolDeleteReferee consulted before a preset delete.
A plugin holding resources keyed on a preset/tool name (e.g. per-node state
bindings that reference a preset) calls this through the tai42_app handle when
its module loads. Every registered referee is asked for the name on a delete; a
referee cascades its own cleanup and returns empty to allow, or returns non-empty
descriptions to VETO — any non-empty answer blocks the delete and names the
holders. Registering the same provider object twice raises loudly — a double
registration is a plugin bug, never a silent duplicate consult.
Parameters
register_detach_referee
tai42_contract.tools.AppTools.register_detach_referee
StateTemplateDetachReferee consulted before a state-template detach.
A holder of door bindings that name templates (e.g. per-node state bindings, or the
platform’s own preset/route/hook/schedule bindings) calls this through the
tai42_app handle when its module loads. Every registered referee is asked for the
(state, template) on a detach; any non-empty answer blocks the detach and its
descriptions name the referencing bindings. Registering the same provider object
twice raises loudly — a double registration is a bug, never a silent duplicate
consult.
Parameters
register_tier
tai42_contract.tools.AppTools.register_tier
base_tool’s registration tier (a RouteAction).
The authorization character enforced everywhere the tier is consulted.
A fenced or secret tier gates BOTH authoring a preset over the base tool
(admin-only) AND running the tool: a fenced/secret tool runs only for an
administrator, at every execution door, and a preset authored over it inherits
that fence at run time. read/write carry no execution gate. This is the
programmatic form of @app.tools.tool(tier=...); both write the one shared
registry (also read on the authoring side as app.presets.registration_tier).
One declaration per base tool; a duplicate raises loudly.
Parameters
tier
tai42_contract.tools.AppTools.tier
base_tool declared, or None when it declared none.
None means no execution fence; authoring keeps the presets’ default write action.
Parameters
RunDelivery
tai42_contract.tools.call_frame.RunDelivery
run_delivery_id is the uuid4 minted once at the outermost run start,
shared by every nested dispatch, sibling branch, and re-park of the run so
its single terminal delivers once. delivery is the (tool, context)
the starting door bound as the run’s completion address, or None when the
door has no receiver.
Attributes
StateTemplateDetachReferee
tai42_contract.tools.StateTemplateDetachReferee
ToolDeleteReferee
tai42_contract.tools.ToolDeleteReferee
ToolInfo
tai42_contract.tools.ToolInfo
name is the registered key; base is the underlying tool it was
bound from (a branch tool names itself, e.g. name_chain).
Attributes
ToolInvocation
tai42_contract.tools.invocation.ToolInvocation
tool_name is the invoked tool’s registered name. Frozen — a deposited invocation is a
fact of the active execution, never mutated in place.
state_binding is the OPTIONAL door-layer binding a door deposits when it
initiates a run (a channel route, a schedule fire, a hook, or none for a bare
run-tool call): it rides the ambient context to the shared dispatch chokepoint,
which carries it forward across its own re-deposit and merges it with the
dispatched preset’s own binding before applying it around the run. The contract
interprets nothing about it — a logic-free carrier.
Attributes
ToolRefsExtractor
tai42_contract.tools.ToolRefsExtractor
ToolRenameReferee
tai42_contract.tools.ToolRenameReferee
ToolRetryBackoff
tai42_contract.tools.retry.ToolRetryBackoff
n waits min(cap_seconds, initial_seconds * multiplier**(n-1)) before attempt
n+1. A server-provided retry_after on the failed attempt’s error WIDENS the wait when
it asks for longer (the medium’s own ask wins, even past the cap — the cap bounds the
platform’s growth, not the server’s explicit request).
Attributes
ToolRetryPolicy
tai42_contract.tools.retry.ToolRetryPolicy
max_attempts is the TOTAL attempt budget, first attempt included
(1 = no retry, just per-attempt monitoring). idempotent is the
author’s explicit claim that re-firing the body is safe — REQUIRED, and a
retrying policy (max_attempts > 1) without it is rejected (the
double-send guard).
retryable is the classification door — an explicit allowlist, never a
blanket:
True— retry theDEFAULT_RETRYABLE_KINDS;- a tuple of
ErrorKind— retry exactly those kinds (NEVER_RETRYABLE_KINDSare rejected at declaration); False— no kind-based retry at all.
retryable verdict (the
ChannelDeliveryError shape) wins in BOTH directions: True admits it
even off-list, False vetoes it even on-list — the raiser knows its
failure better than any kind bucket. An error with neither a verdict nor an
allowlisted kind is never retried.
Attributes
current_call_chain
tai42_contract.tools.call_frame.current_call_chain
current_extras
tai42_contract.tools.call_frame.current_extras
current_tool_invocation
tai42_contract.tools.invocation.current_tool_invocation
None when no tool is executing.
get_run_delivery
tai42_contract.tools.call_frame.get_run_delivery
None when receiver-less or unbound.
get_run_delivery_id
tai42_contract.tools.call_frame.get_run_delivery_id
None outside a bound run.
reset_current_tool_invocation
tai42_contract.tools.invocation.reset_current_tool_invocation
token.
token is the return value of the matching set_current_tool_invocation call.
Parameters
run_delivery
tai42_contract.tools.call_frame.run_delivery
completion_id and a re-park inside stores the same pair. The
chokepoint binds the interaction’s stored RunDelivery here BEFORE the drive, so the
resume’s outermost tool_call_frame finds one already ambient and does NOT re-mint.
None binds nothing (a run that stored no delivery context). ContextVar token discipline:
reset in the finally.
Parameters
set_current_tool_invocation
tai42_contract.tools.invocation.set_current_tool_invocation
invocation as the in-flight tool for the current context.
Pass the returned token to reset_current_tool_invocation to restore the previous
value. Nested deposits (a tool invoking another) re-set for the inner call and restore the
outer value on reset — ContextVar token discipline.
Parameters
tool_call_frame
tai42_contract.tools.call_frame.tool_call_frame
finally.
Parameters

