Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.xpander.ai/llms.txt

Use this file to discover all available pages before exploring further.

Tool represents a single callable an agent can invoke: a connector operation, an OpenAPI endpoint, an MCP tool, or a local Python function registered with @register_tool. You normally get one from agent.tools.list or agent.tools.get_tool_by_id(...).
agent = await agents.aget("agent-123")
tool = agent.tools.get_tool_by_id("get_weather")

print(tool.id, tool.name, tool.description)
print(tool.parameters)        # raw JSON schema
print(tool.schema)            # Pydantic model class generated from parameters

Attributes

AttributeTypeDescription
idstrTool identifier (used as the function name when invoked by the LLM).
namestrDisplay name.
methodstrHTTP method for remote invocation ("POST", "GET", …).
pathstrEndpoint path.
descriptionstrHuman-readable description (used by the LLM to decide when to call).
parametersdictJSON schema for the input payload.
is_localboolTrue when the tool is a @register_tool Python function.
is_syncedboolFor local tools: True after the tool has been pushed to the platform’s graph.
is_standaloneboolTrue when loaded via aload_tool_by_id (no agent context).
should_add_to_graphboolWhether this tool should be added to agent execution graphs.
connector_idstr | NoneFor platform tools: the connector id.
operation_idstr | NoneFor platform tools: the operation id.
schema_overridesAgentGraphItemSchema | NonePer-agent input/output schema overrides.
fnCallable | NoneThe Python function for local tools. Excluded from serialization.
configurationConfigurationSDK configuration.

Computed properties

schema

tool.schema -> type[BaseModel]
A dynamically-generated Pydantic model class derived from tool.parameters. The model’s name is {ToolIdPascalCase}PayloadSchema. If the agent has schema overrides for this tool, they’re applied here.
WeatherSchema = tool.schema
WeatherSchema(city="NYC")          # validates input

payload_schema

tool.payload_schema -> type[BaseModel]
A wrapper schema with a single payload field whose type is tool.schema. Useful when a framework expects every tool call to be wrapped in {"payload": {...}}.
PayloadModel = tool.payload_schema
PayloadModel(payload={"city": "NYC"})

Methods

ainvoke / invoke

Invoke the tool. Validates the payload against tool.schema, executes locally (is_local=True) or remotely, and returns a ToolInvocationResult.
result = await tool.ainvoke(
    agent_id="agent-123",
    payload={"city": "Tokyo"},
)
print(result.result, result.is_success)
ParameterTypeRequiredDefaultDescription
agent_idstrYesAgent invoking the tool.
payloadAnyYesTool input. Validated against tool.schema.
agent_versionstrNoNonePin to a specific agent version.
payload_extensiondictNo{}Extra fields deep-merged into the payload (headers, auth, etc.).
configurationConfigurationNoTool’s configOverride SDK configuration.
task_idstrNoNoneAssociate with a task (for activity logging).
tool_call_idstrNoNoneCorrelation id matching the LLM’s tool-call id.
report_activityboolNoFalsePush ToolCallRequest / ToolCallResult events to the task activity log. Set this when invoking outside the framework’s tool hook (so events aren’t double-emitted).
Returns a ToolInvocationResult (see below). Sync sibling: tool.invoke(...). ainvoke runs the configured tool lifecycle hooks (@on_tool_before / @on_tool_after / @on_tool_error) around the call.

acall_remote_tool / call_remote_tool

Lower-level: makes the API call without local-tool fallback or hook execution. Used internally by ainvoke when is_local=False. Use directly only for advanced cases (preflight checks, custom invocation pipelines).
result = await tool.acall_remote_tool(
    agent_id="agent-123",
    payload={"city": "Tokyo"},
)

agraph_preflight_check / graph_preflight_check

Asks the platform to validate a hypothetical tool invocation without executing it. Used internally for graph routing.

get_invocation_function

tool.get_invocation_function(
    is_async: bool = False,
    configuration: Optional[Configuration] = None,
) -> Callable
Factory that returns a pre-configured invocation function bound to this tool’s connector + configuration. Use for standalone invocation (no agent context):
invoke = tool.get_invocation_function(is_async=True)
result = await invoke({"city": "NYC"})   # ToolInvocationResult
This skips agent-id and task-id binding: the underlying call hits the connector via connector_id_operation_id and returns the raw response wrapped in ToolInvocationResult. Use it after ToolsRepository.aload_tool_by_id(...) to call a single connector without an agent.

ToolInvocationResult

The shape returned by ainvoke and the standalone invocation function.
FieldTypeDescription
tool_idstrThe tool’s id.
tool_call_idstr | NoneThe correlation id, if passed.
task_idstr | NoneThe task id, if passed.
payloadAnyThe payload that was sent.
status_codeintHTTP status (200 by default).
resultAnyThe tool’s response.
is_successboolTrue on 2xx.
is_errorboolTrue on failure.
is_localboolTrue for local tools.
is_success and is_error are mutually exclusive in normal operation: check is_error first to branch on failure cases.

Examples

Inspect tool schema

tool = agent.tools.get_tool_by_id("get_weather")

# Pydantic schema (from parameters)
schema = tool.schema
print(schema.model_json_schema())

# Validate a payload before sending
schema.model_validate({"city": "NYC"})   # raises ValidationError on bad shape

Per-call configuration override

from xpander_sdk import Configuration

custom_config = Configuration(api_key="other-key", organization_id="other-org")

result = await tool.ainvoke(
    agent_id="agent-123",
    payload={"city": "Berlin"},
    configuration=custom_config,
)

Reporting activity for non-Agno callers

When invoking a tool outside an Agno-driven flow (e.g. from your own agent loop), set report_activity=True so the call shows up in the task’s activity log:
result = await tool.ainvoke(
    agent_id="agent-123",
    task_id=task.id,
    payload={...},
    report_activity=True,
)
Inside Agno-driven flows, leave it at False: the Agno hook reports the call automatically and you’d otherwise double-emit events.