AgentOSClient
Python client for interacting with AgentOS API endpoints
The AgentOSClient provides a convenient interface for interacting with a running AgentOS instance. This page covers selected operations, including running agents, teams, and workflows, managing sessions and memories, and searching knowledge bases.
Basic Usage
Install uv pip install 'agno[os]'. Start the remote execution quickstart server, which exposes assistant-agent on port 7778. The server needs its documented model key.
import asyncio
from agno.client import AgentOSClient
async def main():
client = AgentOSClient(base_url="http://localhost:7778")
config = await client.aget_config()
print(f"Connected to: {config.name or config.os_id}")
print(f"Available agents: {[a.id for a in config.agents]}")
asyncio.run(main())Later snippets are fragments inside an async function with client configured. Agent calls use the quickstart's assistant-agent. Replace illustrative Team, Workflow, run, session, and resource IDs with actual IDs from your server. Team/Workflow examples require those entities to be registered. For persistence-backed operations, use a database-configured server; for content operations, configure knowledge. Traces require tracing and stored spans; metrics require stored sessions. Pass authentication headers on each request when the server requires them.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
base_url | str | Required | Base URL of the AgentOS instance (e.g., "http://localhost:7777") |
timeout | float | 60.0 | Request timeout in seconds |
Methods
Discovery & Configuration
aget_config
Get AgentOS configuration and metadata asynchronously.
config = await client.aget_config()Returns: ConfigResponse containing:
os_id: Unique identifier for the OS instancename: Name of the OS instanceagents: List of registered agentsteams: List of registered teamsworkflows: List of registered workflowsinterfaces: List of available interfaces
get_config
Synchronous version of aget_config.
config = client.get_config()list_agents
List all agents configured in the AgentOS instance.
agents = await client.list_agents()
for agent in agents:
print(f"{agent.id}: {agent.name}")Returns: List[AgentSummaryResponse]
aget_agent
Get detailed configuration for a specific agent.
agent = await client.aget_agent(agent_id="assistant-agent")
print(f"Name: {agent.name}")
print(f"Model: {agent.model}")
print(f"Tools: {agent.tools}")Parameters:
agent_id(str): ID of the agent to retrieve
Returns: AgentResponse
list_teams
List all teams configured in the AgentOS instance.
teams = await client.list_teams()Returns: List[TeamSummaryResponse]
aget_team
Get detailed configuration for a specific team.
team = await client.aget_team(team_id="my-team")Parameters:
team_id(str): ID of the team to retrieve
Returns: TeamResponse
list_workflows
List all workflows configured in the AgentOS instance.
workflows = await client.list_workflows()Returns: List[WorkflowSummaryResponse]
aget_workflow
Get detailed configuration for a specific workflow.
workflow = await client.aget_workflow(workflow_id="my-workflow")Parameters:
workflow_id(str): ID of the workflow to retrieve
Returns: WorkflowResponse
Running Agents
run_agent
Execute an agent run (non-streaming).
result = await client.run_agent(
agent_id="assistant-agent",
message="What is 2 + 2?",
session_id="session-123",
user_id="user-456",
)
print(f"Response: {result.content}")
if result.metrics:
print(f"Tokens: {result.metrics.total_tokens}")Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
agent_id | str | Required | ID of the agent to run |
message | str | Required | The message/prompt for the agent |
session_id | Optional[str] | None | Session ID for context persistence |
user_id | Optional[str] | None | User ID for the run |
images | Optional[Sequence[Image]] | None | Images to include |
audio | Optional[Sequence[Audio]] | None | Audio to include |
videos | Optional[Sequence[Video]] | None | Videos to include |
files | Optional[Sequence[File]] | None | Files to include |
headers | Optional[Dict[str, str]] | None | HTTP headers to include in the request |
session_state | Optional[Dict] | None | Session state dictionary (passed via **kwargs) |
dependencies | Optional[Dict] | None | Dependencies dictionary (passed via **kwargs) |
metadata | Optional[Dict] | None | Metadata dictionary (passed via **kwargs) |
knowledge_filters | Optional[Dict] | None | Filters for knowledge search (passed via **kwargs) |
output_schema | Optional[Dict] | None | JSON schema for structured output (passed via **kwargs) |
Returns: RunOutput
run_agent_stream
Stream an agent run response.
from agno.run.agent import RunContentEvent, RunCompletedEvent
async for event in client.run_agent_stream(
agent_id="assistant-agent",
message="Tell me a story",
):
if isinstance(event, RunContentEvent):
print(event.content, end="", flush=True)
elif isinstance(event, RunCompletedEvent):
print(f"\nRun ID: {event.run_id}")Parameters: Same as run_agent
Yields: RunOutputEvent (one of RunStartedEvent, RunContentEvent, ToolCallStartedEvent, ToolCallCompletedEvent, RunCompletedEvent, etc.)
continue_agent_run
Continue a stored agent run with updated tool executions. The server also supports eligible non-paused continuation. For local AgentOS agents, supply the original session_id and configure a server-side database.
This confirmation-only fragment assumes paused is the actual paused response from an agent with confirmation tools. Keep its tool executions and IDs:
from agno.run.base import RunStatus
assert paused.status == RunStatus.paused
assert paused.run_id and paused.session_id and paused.requirements
for requirement in paused.requirements:
if not requirement.needs_confirmation:
raise ValueError("Resolve this requirement using its input or execution handler")
print(requirement.tool_execution)
if input("Confirm this tool call? [y/N] ").lower() == "y":
requirement.confirm()
else:
requirement.reject()
result = await client.continue_agent_run(
agent_id=paused.agent_id,
run_id=paused.run_id,
session_id=paused.session_id,
tools=[req.tool_execution for req in paused.requirements if req.tool_execution],
)The requirement methods also support user input, feedback, and external execution. This client method sends the updated ToolExecution objects through tools; it does not accept a requirements argument.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
agent_id | str | Required | ID of the agent |
run_id | str | Required | ID of the run to continue |
tools | List[ToolExecution] | Required | Tool execution results |
session_id | Optional[str] | None | Original stored session ID; required by the local AgentOS continuation route |
user_id | Optional[str] | None | User ID |
headers | Optional[Dict[str, str]] | None | HTTP headers to include in the request |
Returns: RunOutput
cancel_agent_run
Request cancellation. The method returns None after an accepted HTTP response; inspect later run status/events to confirm cancellation. See scoped cancellation when the caller is isolated.
await client.cancel_agent_run(agent_id="assistant-agent", run_id="run-123")Running Teams
run_team
Execute a team run (non-streaming).
result = await client.run_team(
team_id="research-team",
message="Research the latest AI trends",
user_id="user-123",
)
print(f"Response: {result.content}")Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
team_id | str | Required | ID of the team to run |
message | str | Required | The message/prompt for the team |
session_id | Optional[str] | None | Session ID for context persistence |
user_id | Optional[str] | None | User ID for the run |
images | Optional[Sequence[Image]] | None | Images to include |
audio | Optional[Sequence[Audio]] | None | Audio to include |
videos | Optional[Sequence[Video]] | None | Videos to include |
files | Optional[Sequence[File]] | None | Files to include |
headers | Optional[Dict[str, str]] | None | HTTP headers to include in the request |
Returns: TeamRunOutput
Paused runs return status="PAUSED" and requirements on the TeamRunOutput.
run_team_stream
Stream a team run response.
from agno.run.team import RunContentEvent
async for event in client.run_team_stream(
team_id="research-team",
message="Analyze this topic",
):
if isinstance(event, RunContentEvent):
print(event.content, end="", flush=True)Yields: TeamRunOutputEvent
continue_team_run and continue_team_run_stream
Both take team_id, run_id, requirements, optional session_id, user_id, headers, and **kwargs. Pass the original paused Team response's IDs and resolved RunRequirement objects. Retain member context on each requirement so results route to the correct member. A database and stored session are required.
continue_team_run returns TeamRunOutput; continue_team_run_stream yields TeamRunOutputEvent. See Team human-in-the-loop for requirement resolution.
cancel_team_run
Request cancellation; returns None after acceptance. The scoped cancellation limitation also applies.
await client.cancel_team_run(team_id="my-team", run_id="run-123")Running Workflows
run_workflow
Execute a workflow run (non-streaming).
result = await client.run_workflow(
workflow_id="qa-workflow",
message="What are the benefits of Python?",
user_id="user-123",
)
print(f"Response: {result.content}")
print(f"Status: {result.status}")Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
workflow_id | str | Required | ID of the workflow to run |
message | str | Required | The message/prompt for the workflow |
session_id | Optional[str] | None | Session ID for context persistence |
user_id | Optional[str] | None | User ID for the run |
images | Optional[Sequence[Image]] | None | Images to include |
audio | Optional[Sequence[Audio]] | None | Audio to include |
videos | Optional[Sequence[Video]] | None | Videos to include |
files | Optional[Sequence[File]] | None | Files to include |
headers | Optional[Dict[str, str]] | None | HTTP headers to include in the request |
Returns: WorkflowRunOutput
run_workflow_stream
Stream a workflow run response.
from agno.run.workflow import (
WorkflowCompletedEvent,
WorkflowErrorEvent,
WorkflowCancelledEvent,
WorkflowPausedEvent,
)
async for event in client.run_workflow_stream(
workflow_id="qa-workflow",
message="Explain machine learning",
):
if isinstance(event, WorkflowCompletedEvent):
print(event.content)
elif isinstance(event, WorkflowErrorEvent):
print(f"Workflow failed: {event.error}")
elif isinstance(event, WorkflowCancelledEvent):
print(f"Workflow cancelled: {event.reason}")
elif isinstance(event, WorkflowPausedEvent):
print(f"Workflow paused: {event.run_id}")The example prints the final workflow result once. Callable steps need not emit RunContent events; agent/team step deltas may be handled separately for incremental rendering.
Yields: WorkflowRunOutputEvent
continue_workflow_run and continue_workflow_run_stream
Both take workflow_id, run_id, requirements, optional session_id, user_id, headers, and **kwargs. Supply the stored Workflow response's IDs and resolved StepRequirement objects or dictionaries from its step_requirements. The client serializes requirements as the step_requirements form field. Preserve nested executor requirements and step identities; see Workflow HITL for resolution.
continue_workflow_run returns WorkflowRunOutput; continue_workflow_run_stream yields WorkflowRunOutputEvent. Use a database-backed workflow and the original stored session.
cancel_workflow_run
Request cancellation; returns None after acceptance. The scoped cancellation limitation also applies.
await client.cancel_workflow_run(workflow_id="my-workflow", run_id="run-123")Memory Operations
create_memory
Create a new user memory.
memory = await client.create_memory(
memory="User prefers dark mode",
user_id="user-123",
topics=["preferences", "ui"],
)
print(f"Created: {memory.memory_id}")Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
memory | str | Required | The memory content to store |
user_id | str | Required | User ID to associate with the memory |
topics | Optional[List[str]] | None | Topics to categorize the memory |
db_id | Optional[str] | None | Database ID to use |
table | Optional[str] | None | Table name to use |
headers | Optional[Dict[str, str]] | None | HTTP headers to include in the request |
Returns: UserMemorySchema
list_memories
List user memories with filtering and pagination.
memories = await client.list_memories(
user_id="user-123",
topics=["preferences"],
limit=10,
)
for mem in memories.data:
print(f"{mem.memory_id}: {mem.memory}")Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
user_id | Optional[str] | None | Filter by user ID |
agent_id | Optional[str] | None | Filter by agent ID |
team_id | Optional[str] | None | Filter by team ID |
topics | Optional[List[str]] | None | Filter by topics |
search_content | Optional[str] | None | Search within memory content |
limit | int | 20 | Number of memories per page |
page | int | 1 | Page number |
sort_by | str | "updated_at" | Field to sort by |
sort_order | str | "desc" | Sort order (asc or desc) |
db_id | Optional[str] | None | Database ID to use |
table | Optional[str] | None | Table name to use |
headers | Optional[Dict[str, str]] | None | HTTP headers to include in the request |
Returns: PaginatedResponse[UserMemorySchema]
get_memory
Get a specific memory by ID.
memory = await client.get_memory(memory_id="mem-123", user_id="user-123")Returns: UserMemorySchema
update_memory
Update an existing memory.
updated = await client.update_memory(
memory_id="mem-123",
memory="User strongly prefers dark mode",
user_id="user-123",
topics=["preferences", "ui", "accessibility"],
)Returns: UserMemorySchema
delete_memory
Delete a specific memory.
await client.delete_memory(memory_id="mem-123", user_id="user-123")Session Operations
create_session
Create a new session.
from agno.db.base import SessionType
session = await client.create_session(
session_type=SessionType.AGENT,
agent_id="assistant-agent",
user_id="user-123",
session_name="My Chat Session",
)
print(f"Session ID: {session.session_id}")Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
session_type | SessionType | SessionType.AGENT | Type of session (AGENT, TEAM, WORKFLOW) |
session_id | Optional[str] | None | Optional session ID (auto-generated if not provided) |
user_id | Optional[str] | None | User ID to associate with the session |
session_name | Optional[str] | None | Human-readable session name |
session_state | Optional[Dict[str, Any]] | None | Initial session state |
metadata | Optional[Dict[str, Any]] | None | Session metadata |
agent_id | Optional[str] | None | Agent ID (for agent sessions) |
team_id | Optional[str] | None | Team ID (for team sessions) |
workflow_id | Optional[str] | None | Workflow ID (for workflow sessions) |
db_id | Optional[str] | None | Database ID to use |
headers | Optional[Dict[str, str]] | None | HTTP headers to include in the request |
Returns: AgentSessionDetailSchema, TeamSessionDetailSchema, or WorkflowSessionDetailSchema
get_sessions
List sessions with filtering and pagination.
sessions = await client.get_sessions(
user_id="user-123",
session_type=SessionType.AGENT,
limit=20,
)
for session in sessions.data:
print(f"{session.session_id}: {session.session_name}")Returns: PaginatedResponse[SessionSchema]
get_session
Get a specific session by ID.
session = await client.get_session(
session_id="session-123",
session_type=SessionType.AGENT,
)Returns: AgentSessionDetailSchema, TeamSessionDetailSchema, or WorkflowSessionDetailSchema
get_session_runs
Get all runs for a specific session.
runs = await client.get_session_runs(session_id="session-123")
for run in runs:
print(f"{run.run_id}: {str(run.content)[:50]}...")Returns: List[RunSchema | TeamRunSchema | WorkflowRunSchema]
rename_session
Rename a session.
session = await client.rename_session(
session_id="session-123",
session_name="My Updated Session Name",
)Returns: Session detail schema
delete_session
Delete a specific session.
await client.delete_session(session_id="session-123")Knowledge Operations
upload_knowledge_content
Upload content to the knowledge base.
from agno.media import File
content = await client.upload_knowledge_content(
name="My Document",
description="Important documentation",
file=File(content=b"Agno builds agents, teams, and workflows.", filename="doc.txt", mime_type="text/plain"),
)
print(f"Content ID: {content.id}")Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
name | Optional[str] | None | Content name |
description | Optional[str] | None | Content description |
url | Optional[str] | None | URL to fetch content from |
metadata | Optional[Dict[str, Any]] | None | Metadata dictionary for the content |
file | Optional[Union[File, UploadFile]] | None | File object to upload; accepts a FastAPI UploadFile |
text_content | Optional[str] | None | Raw text content |
reader_id | Optional[str] | None | Reader to use for processing |
chunker | Optional[str] | None | Chunking strategy |
chunk_size | Optional[int] | None | Chunk size for processing |
chunk_overlap | Optional[int] | None | Chunk overlap for processing |
db_id | Optional[str] | None | Database ID to use |
knowledge_id | Optional[str] | None | Knowledge instance ID for content isolation |
headers | Optional[Dict[str, str]] | None | HTTP headers to include in the request |
Returns: ContentResponseSchema
search_knowledge
Search the knowledge base.
results = await client.search_knowledge(
query="What is Agno?",
limit=5,
)
for result in results.data:
print(f"Score: {result.reranking_score}")
print(f"Content: {result.content[:100]}...")Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
query | str | Required | Search query string |
max_results | Optional[int] | None | Maximum results to return |
filters | Optional[Dict] | None | Filters to apply |
search_type | Optional[str] | None | Search type (vector, keyword, hybrid) |
vector_db_ids | Optional[List[str]] | None | Vector DB IDs to search |
limit | int | 20 | Number of results per page |
page | int | 1 | Page number |
db_id | Optional[str] | None | Database ID to use |
knowledge_id | Optional[str] | None | Knowledge instance ID for content isolation |
headers | Optional[Dict[str, str]] | None | HTTP headers to include in the request |
Returns: PaginatedResponse[VectorSearchResult]
list_knowledge_content
List all content in the knowledge base.
content = await client.list_knowledge_content(limit=20)
for item in content.data:
print(f"{item.id}: {item.name}")Returns: PaginatedResponse[ContentResponseSchema]
get_knowledge_config
Get knowledge base configuration.
config = await client.get_knowledge_config()
print(f"Readers: {config.readers}")
print(f"Chunkers: {config.chunkers}")Returns: KnowledgeConfigResponse
Trace Operations
get_traces
List execution traces with filtering and pagination.
traces = await client.get_traces(
agent_id="assistant-agent",
limit=20,
)
for trace in traces.data:
print(f"{trace.trace_id}: {trace.status}")Returns: PaginatedResponse[TraceSummary]
get_trace
Get detailed trace information.
trace = await client.get_trace(trace_id="trace-123")
print(f"Duration: {trace.duration}")
print(f"Spans: {len(trace.tree)}")Returns: TraceDetail or TraceNode (if span_id provided)
Metrics Operations
get_metrics
Retrieve AgentOS metrics and analytics data.
from datetime import date
metrics = await client.get_metrics(
starting_date=date(2024, 1, 1),
ending_date=date(2024, 1, 31),
)Returns: MetricsResponse
refresh_metrics
Manually trigger recalculation of system metrics.
metrics = await client.refresh_metrics()Returns: List[DayAggregatedMetrics]
Error Handling
The client raises RemoteServerUnavailableError when the remote server is unavailable:
from agno.exceptions import RemoteServerUnavailableError
try:
config = await client.aget_config()
except RemoteServerUnavailableError as e:
print(f"Server unavailable: {e.message}")
print(f"Base URL: {e.base_url}")For HTTP errors (4xx, 5xx), the client raises httpx.HTTPStatusError.
Authentication
To include authentication headers in requests, pass the headers parameter to any method:
headers = {"Authorization": "Bearer your-token"}
config = await client.aget_config(headers=headers)Scoped cancellation
The three cancel_*_run methods have no session_id parameter. Current AgentOS cancellation routes require the owned session ID for scoped callers: JWT users with isolation enabled and all non-admin service accounts. Use direct HTTP for this case.
This async fragment assumes saved_run_id and saved_session_id came from the active run, and AGENTOS_TOKEN is its owner's credential. Select the matching entity route (agents, teams, or workflows):
import os
import httpx
async with httpx.AsyncClient(base_url="http://localhost:7778") as http:
response = await http.post(
f"/agents/assistant-agent/runs/{saved_run_id}/cancel",
params={"session_id": saved_session_id},
headers={"Authorization": f"Bearer {os.environ['AGENTOS_TOKEN']}"},
)
response.raise_for_status()
print("Cancellation request accepted")An accepted request records cancellation intent. Confirm the terminal state through the stream or a later read of the stored run.