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.

Backend.aget_args returns a dictionary of framework-ready keyword arguments for a stored agent. Spread the result directly into an Agno (or other supported framework’s) constructor: the dict already contains the model, system prompt, tools, memory settings, knowledge-base retrievers, and guardrails configured in the Workbench.
from xpander_sdk import Backend
from agno.agent import Agent as AgnoAgent

backend = Backend()
args = await backend.aget_args(agent_id="agent-123")

agno_agent = AgnoAgent(**args)
result = await agno_agent.arun(input="Hello!")
This is the primary integration point for code-based agents. Call it once per task (typically inside @on_task) so the framework agent reflects the latest stored configuration.

Parameters

ParameterTypeRequiredDefaultDescription
agent_idstrNo¹XPANDER_AGENT_ID env varAgent ID. Required if agent is not provided.
agentAgentNo¹NoneA pre-loaded Agent instance. Takes precedence over agent_id.
agent_versionintNoNoneSpecific version to load. Latest if omitted.
taskTaskNoNoneThe current task. When provided, args include task-specific context (input, files, output schema).
overridedict[str, Any]NoNoneFinal overrides merged into the resolved kwargs.
toolslist[Callable]NoNoneExtra Python callables added to the agent’s tool list.
is_asyncboolNoTrue(async only) Whether you’ll run the framework agent in an async context. Affects how local tools are wrapped.
auth_events_callbackCallableNoNonePer-call callback for MCP/OAuth authentication events. See Authentication events.
¹ Either agent_id or agent must be resolvable. If neither is passed, the method falls back to XPANDER_AGENT_ID.

Returns dict[str, Any]

A dictionary of framework-ready kwargs. The exact keys depend on the agent’s framework (currently always Agno):
{
    "name": "Sales Assistant",
    "agent_id": "agent-123",
    "model": <agno Model instance>,
    "instructions": "...",
    "tools": [<callable>, <callable>, ...],
    "knowledge": <agno Knowledge instance | None>,
    "memory_manager": <agno MemoryManager | None>,
    "db": <agno PostgresDb | None>,
    "guardrails": [...],
    "user_id": "...",
    "session_id": "...",
    # ...framework-specific keys
}
You don’t need to read these: pass them straight to the framework’s constructor.

Examples

Inside @on_task

from xpander_sdk import Backend, on_task
from xpander_sdk.modules.tasks.sub_modules.task import Task
from agno.agent import Agent as AgnoAgent

backend = Backend()

@on_task
async def handler(task: Task) -> Task:
    args = await backend.aget_args(
        agent_id=task.agent_id,
        agent_version=task.agent_version,
        task=task,
    )
    agno_agent = AgnoAgent(**args)

    result = await agno_agent.arun(
        input=task.to_message(),
        files=task.get_files(),
        images=task.get_images(),
    )
    task.result = result.content
    return task
Passing task=task enriches the args with task-specific context (session id, user id, output schema), so memory and structured output work transparently.

Pre-loaded agent (avoid re-fetching)

from xpander_sdk import Agents, Backend

agents = Agents()
backend = Backend()

agent = await agents.aget("agent-123")  # fetched once, reused

# Many tasks for the same agent: pass `agent` instead of `agent_id`
for prompt in prompts:
    args = await backend.aget_args(agent=agent, override={"name": "batch-worker"})
    ...
agent takes precedence over agent_id. This avoids a fresh GET /agents/:id call each time you build framework args.

Override resolved kwargs

args = await backend.aget_args(
    agent_id="agent-123",
    override={
        "show_tool_calls": True,
        "markdown": False,
    },
)
override is shallow-merged after the framework dispatcher builds its kwargs, so anything you set wins.

Add extra tools

def lookup_internal_id(employee_email: str) -> str:
    """Look up an employee's internal ID from email."""
    ...

args = await backend.aget_args(
    agent_id="agent-123",
    tools=[lookup_internal_id],
)
The callable is appended to the agent’s tool list for this run only: it isn’t persisted to the platform. For permanent tools, register with @register_tool instead.

Authentication events

When an agent uses MCP servers or connectors that require OAuth, the framework emits auth_event updates while the user authenticates. Register a callback to handle the OAuth URL or token-ready signals:

Per-call callback

from xpander_sdk import Backend
from xpander_sdk.modules.agents.sub_modules.agent import Agent
from xpander_sdk.modules.tasks.sub_modules.task import Task, TaskUpdateEvent

async def on_auth(agent: Agent, task: Task, event: TaskUpdateEvent):
    print(f"Auth required: {event.data}")
    # Show event.data['url'] to the user, or kick off your OAuth flow

backend = Backend()
args = await backend.aget_args(
    agent_id="agent-123",
    auth_events_callback=on_auth,
)

Globally with @on_auth_event

from xpander_sdk import on_auth_event

@on_auth_event
async def handle_auth(agent, task, event):
    print(f"[GLOBAL] {agent.name}: {event.data}")

# No need to pass it: the decorator auto-registers
args = await backend.aget_args(agent_id="agent-123")
You can combine both: decorated handlers are always invoked, and auth_events_callback adds a one-off handler on top. See @on_auth_event for details.

Sync version

args = backend.get_args(agent_id="agent-123")
Same parameters minus is_async (sync wrapper hard-codes it to False so local tools are wrapped synchronously). Don’t call from inside a running event loop.