Skip to main content
The Agents module is your gateway to agents stored on the platform. Use it to discover what agents exist, load a specific one, and from there create tasks, invoke tools, attach knowledge bases, and inspect sessions.

Constructor

Module methods

Agent instance methods

Once you’ve loaded an Agent, use its instance methods for the actual work: See the Agent class reference for attribute documentation.

Quick patterns

Find and load

Pin to a specific version

Versioning is opt-in. Without version, you get the latest.

Default agent via env var

This works because Agents.aget() falls back to Configuration.agent_id and then to XPANDER_AGENT_ID.

list

Agents.alist returns a list of summary objects (AgentsListItem) for every agent visible to the configured organization. Each item carries enough metadata for display (id, name, icon, status, instructions, access scope) and a .aload() shortcut to fetch the full Agent.

Parameters

None.

Returns list[AgentsListItem]

AgentsListItem is a lightweight summary: not the full Agent. Notable fields: To load the full agent (graph, tools, model config, …) call .aload() on the item, or pass item.id to agents.aget().

Examples

Filter active agents

Load all in parallel

For a large org this can be heavy: prefer loading only the agents you’ll actually use.

Sync version

Same return type; blocks until the list is fetched.

Errors

alist raises ModuleException on failure:

get

Agents.aget loads one agent’s complete configuration: instructions, model settings, the execution graph, all attached tools, knowledge-base links, and framework settings. Use this whenever you need to actually invoke an agent or inspect its config in code.

Parameters

¹ The method falls back to Configuration.agent_id and then XPANDER_AGENT_ID. If none of those are set, you’ll hit a 404 from the cloud.

Returns Agent

A full Agent instance. See Agent class reference for attributes (instructions, framework, graph, deployment_type, tools, knowledge_bases, agno_settings, etc.).

Examples

Latest version

Pinned version

The version corresponds to deployment snapshots in the Workbench. Pin a version in production to avoid surprises when someone edits the agent.

Use a default agent ID

This is the pattern used inside @on_task handlers: you don’t usually pass an agent ID explicitly because the runtime injects it.

Sync version

Same parameters; blocks until the agent is loaded.

What gets loaded

When you call aget, the SDK:
  1. Fetches the agent record (GET /agents/:id).
  2. Builds the AgentGraph from the graph items returned in the response.
  3. Initializes a ToolsRepository populated with the agent’s tools.
  4. If any local tools (Python @register_tool functions) need syncing to the platform’s graph, kicks off a background sync_local_tools task: non-blocking.
You can read agent.graph to inspect the tool/connector wiring, agent.tools.list for all tools, agent.knowledge_bases for KB links, and agent.mcp_servers for the configured MCP servers.

Errors

aget raises ModuleException on failure:

create_task

Agent.acreate_task creates a new task on the platform and returns a Task object you can save, stream, or stop. This is the primary way to invoke an agent from code.
The newly-created task is queued by the platform; the agent worker (either a managed cloud worker or your local @on_task handler) picks it up and executes it.

Parameters

Returns Task

The created Task. See Task class reference. The task starts in status Pending. It moves through ExecutingCompleted (or Error / Failed / Stopped) as the worker runs it.

Examples

With files

Structured output

Streaming

events_streaming=True is required to use task.aevents(). See task.events.

Continue a thread

The new task reuses the prior task’s memory thread, so the agent has full context.

Per-end-user

user_details.id scopes user-memory and connector auth (e.g. each end user’s Gmail OAuth token).

Add an MCP server just for this task

Per-task MCP servers stack on top of the agent’s persistent MCP configuration.

Pin a version

Sync version

Same parameters; blocks until the task is created. Don’t call from inside an event loop.

Errors

Raises ModuleException on failure:

invoke_tool

Agent.ainvoke_tool runs a single tool from the agent’s ToolsRepository and returns a ToolInvocationResult. Use it when you want to test a tool, or when you’re building an agent loop yourself and the framework’s tool dispatcher isn’t a good fit.

Parameters

Returns ToolInvocationResult

is_success and is_error are mutually exclusive in normal operation; check is_error first.

Examples

With payload_extension

payload_extension is deep-merged with payload, so nested objects compose naturally.

Local Python tools

Tools registered with @register_tool are invoked locally (the fn runs in-process) and pass through the same ToolInvocationResult interface:
See @register_tool for details.

Inside an @on_task handler

Passing task_id ensures the invocation appears in task.aget_activity_log().

Sync version

Notes

  • Payload validation: if payload doesn’t match tool.schema, the SDK raises ValueError (not ModuleException). Catch it separately if you’re invoking with untrusted input.
  • Lifecycle hooks (@on_tool_before / @on_tool_after / @on_tool_error) fire around the invocation.
  • For invocations outside an agent context, use tool.get_invocation_function() instead: it requires a connector_id and operation_id resolved via tools.aload_tool_by_id(...).

Knowledge bases

Agents can have knowledge bases linked to them in the Workbench. From code, you can attach more, load the KnowledgeBase objects, or build a retriever callable for use as a framework retriever.

aget_knowledge_bases

Load every KnowledgeBase linked to the agent, in parallel.

Returns list[KnowledgeBase]

A list of full KnowledgeBase objects. See KnowledgeBase for the methods you can call on each.

Sync version

attach_knowledge_base

Link a knowledge base to the agent on the in-memory instance. Pass either a KnowledgeBase object or a knowledge-base ID.

Parameters

You must pass at least one of the two. If both are passed, knowledge_base.id is used.
attach_knowledge_base only updates the agent in memory. To persist the link, save the agent through the platform (e.g. via the API or the Workbench UI). The runtime instance will use the link for the current session, but it won’t survive a re-load.

knowledge_bases_retriever

Returns a search(query, agent=None, num_documents=5) callable that searches every linked KB and returns top-N results sorted by score. This is the form Agno expects as a custom retriever.

Returned callable signature

Each result is a dict from KnowledgeBaseSearchResult.model_dump():
The retriever swallows errors and returns [] if the search fails: useful for embedding into framework pipelines that shouldn’t crash on retrieval errors.

Patterns

Wire as the Agno knowledge

Backend.aget_args already wires the retriever for you: you don’t usually need to call knowledge_bases_retriever() directly. Use it only when bypassing the Backend dispatcher.

Add a KB on the fly

After attach_knowledge_base, agent.aget_knowledge_bases() includes the new KB in the list.

Sessions

Agents using the Agno framework with agno_settings.session_storage = True persist their session history to a Postgres database managed by the platform. The SDK exposes that database via Agent.aget_db() plus a small set of helpers for session CRUD.
Sessions are only available for Agno agents with session storage enabled. Calling these methods on other agents raises NotImplementedError (wrong framework) or LookupError (storage disabled). The Agno extras must be installed: pip install xpander-sdk[agno].

aget_db

Returns the Agno Postgres client backing the agent’s session storage.

Parameters

Returns

agno.db.postgres.AsyncPostgresDb (or PostgresDb if async_db=False). The client is namespaced to the agent’s schema, so different agents don’t share a session table. The connection URI is fetched (and cached) via agent.aget_connection_string() on the first call.

Sync version

aget_user_sessions

Load all sessions for a given end-user.

Parameters

Returns

A list of session records. The exact type comes from Agno’s db.get_sessions(...): fields include session_id, user_id, agent_id (or team_id for Team mode), and timestamps. The query caps results at 50 sessions per call. For Team agents (agent.is_a_team == True), this returns SessionType.TEAM records; otherwise SessionType.AGENT.

Sync version

aget_session

Load a single session by ID.

Parameters

Returns

The session record, or None if it doesn’t exist.

Sync version

adelete_session

Delete a session.

Parameters

Sync version

Errors

All session methods raise:
  • NotImplementedError: agent isn’t using Agno.
  • LookupError: Agno is configured but agno_settings.session_storage is False.
  • ImportError: Agno extras not installed (run pip install xpander-sdk[agno]).
  • ValueError: connection URI couldn’t be resolved.

Patterns

Inspect recent sessions for a user

Wipe all sessions for a user

aget_user_sessions returns at most 50 records per call, so loop until empty for users with many sessions.

Drop into the Agno DB directly

Use this when the four convenience methods don’t cover what you need; the Agno DB client has a richer API.

Agent class

Agent is the rich object returned by Agents.aget() and AgentsListItem.aload(). It carries the agent’s full stored configuration, plus methods for creating tasks, invoking tools, and managing sessions.

Class methods

Agent.aload(agent_id, configuration=None, version=None) -> Agent

Load an agent by ID. This is what Agents.aget() calls internally. Use the module-level agents.aget(...) in normal code; Agent.aload(...) is for places where you have a Configuration but no Agents instance.
The sync sibling is Agent.load(...).

Attributes

Computed properties

Instance methods

Streaming spec

agent.aget_streaming_spec() -> StreamingSpecResponse: returns the deployed agent’s streaming URL and an API key for the container’s /invoke endpoint. Useful when you want to bypass the SSE channel and POST directly to a deployed worker.
StreamingSpecResponse has two fields: url (str | None) and api_key (str | None). Both can be None if the agent isn’t deployed yet.

Connection string

agent.aget_connection_string() -> DatabaseConnectionString: returns DB connection details for agents using session storage. The result is cached on the instance after the first call.
DatabaseConnectionString has id, name, organization_id, and connection_uri.uri (a Postgres-compatible URI).

sync_local_tools

await agent.sync_local_tools(tools=[...]): pushes locally-decorated @register_tool(add_to_graph=True) tools to the platform’s graph. Called automatically when Agent.aload detects unsynced tools, so you rarely need to invoke it directly.