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
version, you get the latest.
Default agent via env var
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
Sync version
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
Use a default agent ID
@on_task handlers: you don’t usually pass an agent ID explicitly because the runtime injects it.
Sync version
What gets loaded
When you callaget, the SDK:
- Fetches the agent record (
GET /agents/:id). - Builds the
AgentGraphfrom the graph items returned in the response. - Initializes a
ToolsRepositorypopulated with the agent’s tools. - If any local tools (Python
@register_toolfunctions) need syncing to the platform’s graph, kicks off a backgroundsync_local_toolstask: non-blocking.
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.
@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 Executing → Completed (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
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
Pin a version
Sync version
Errors
RaisesModuleException 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:
@register_tool for details.
Inside an @on_task handler
task_id ensures the invocation appears in task.aget_activity_log().
Sync version
Notes
- Payload validation: if
payloaddoesn’t matchtool.schema, the SDK raisesValueError(notModuleException). 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 aconnector_idandoperation_idresolved viatools.aload_tool_by_id(...).
Knowledge bases
Agents can have knowledge bases linked to them in the Workbench. From code, you can attach more, load theKnowledgeBase 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():
[] 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
attach_knowledge_base, agent.aget_knowledge_bases() includes the new KB in the list.
Sessions
Agents using the Agno framework withagno_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’sdb.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, orNone 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 butagno_settings.session_storageisFalse.ImportError: Agno extras not installed (runpip 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
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.
