Skip to content
24 changes: 24 additions & 0 deletions agent-os/client/agentos-client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,30 @@ except RemoteServerUnavailableError as e:
print(f"URL: {e.base_url}")
```

## Trace Search
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dont think this should be here, just the api endpoints reference we added previously is fine


Search traces using the FilterExpr DSL:

```python
from agno.client import AgentOSClient
from agno.os.routers.traces.schemas import TraceSearchGroupBy

client = AgentOSClient(base_url="http://localhost:7777")

result = await client.search_traces(
filter_expr={
"op": "AND",
"expressions": [
{"op": "EQ", "key": "status", "value": "OK"},
{"op": "CONTAINS", "key": "events", "value": "tool"},
],
},
group_by=TraceSearchGroupBy.RUN,
page=1,
limit=20,
)
```

## API Reference

For complete method documentation, parameters, and response types, see the [AgentOSClient Reference](/reference/clients/agentos-client).
Expand Down
32 changes: 22 additions & 10 deletions agent-os/interfaces/slack/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Use the Slack interface to serve Agents, Teams, or Workflows on Slack. It mounts

## Setup Steps

Follow the Slack setup guide in the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/06_agent_os/interfaces/slack/README.md).
Follow the Slack setup guide in the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/05_agent_os/interfaces/slack/README.md).

Required configuration:

Expand Down Expand Up @@ -43,7 +43,7 @@ if __name__ == "__main__":
agent_os.serve(app="basic:app", port=8000, reload=True)
```

A complete example is available at `cookbook/06_agent_os/interfaces/slack/basic.py`.
A complete example is available at `cookbook/05_agent_os/interfaces/slack/basic.py`.

## Core Components

Expand All @@ -56,17 +56,29 @@ Main entry point for Agno Slack applications.

### Initialization Parameters

| Parameter | Type | Default | Description |
| ------------------------ | ----------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------- |
| `agent` | `Optional[Agent]` | `None` | Agno `Agent` instance. |
| `team` | `Optional[Team]` | `None` | Agno `Team` instance. |
| `workflow` | `Optional[Workflow]` | `None` | Agno `Workflow` instance. |
| `prefix` | `str` | `"/slack"` | Custom FastAPI route prefix for the Slack interface. |
| `tags` | `Optional[List[str]]` | `None` | FastAPI route tags for API documentation. Defaults to `["Slack"]` if not provided. |
| `reply_to_mentions_only` | `bool` | `True` | When `True` (default), bot responds to @mentions in channels and all direct messages. When `False`, responds to all messages in channels. |
| Parameter | Type | Default | Description |
| ------------------------ | ---------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------- |
| `agent` | `Optional[Agent]` | `None` | Agno `Agent` instance. |
| `team` | `Optional[Team]` | `None` | Agno `Team` instance. |
| `workflow` | `Optional[Workflow]` | `None` | Agno `Workflow` instance. |
| `prefix` | `str` | `"/slack"` | Custom FastAPI route prefix for the Slack interface. |
| `tags` | `Optional[List[str]]` | `None` | FastAPI route tags for API documentation. Defaults to `["Slack"]` if not provided. |
| `reply_to_mentions_only` | `bool` | `True` | When `True`, respond to @mentions in channels and all direct messages. When `False`, respond to all channel messages too. |
| `token` | `Optional[str]` | `None` | Slack Bot User OAuth Token (`xoxb-...`). If omitted, the interface reads from environment configuration. |
| `signing_secret` | `Optional[str]` | `None` | Slack signing secret used to verify request signatures. |
| `streaming` | `bool` | `True` | Enable Slack `chat_stream` responses and event-driven streaming updates. |
| `loading_messages` | `Optional[List[str]]` | `None` | Optional rotating loading messages shown while processing streamed runs. |
| `task_display_mode` | `str` | `"plan"` | Task card display mode used by Slack streaming UI. |
| `loading_text` | `str` | `"Thinking..."` | Thread status text shown before streamed output starts. |
| `suggested_prompts` | `Optional[List[Dict[str, str]]]` | `None` | Suggested prompts sent when Slack starts an assistant thread. |
| `ssl` | `Optional[SSLContext]` | `None` | Custom SSL context for Slack SDK HTTP requests. |
| `buffer_size` | `int` | `100` | Stream buffer size for Slack `chat_stream`. |
| `max_file_size` | `int` | `1073741824` | Maximum uploaded/downloaded file size in bytes (default 1 GB). |

Provide `agent`, `team`, or `workflow`.

Use different `prefix`, `token`, and `signing_secret` values when mounting multiple Slack interface instances on one FastAPI app.

### Key Method

| Method | Parameters | Return Type | Description |
Expand Down
25 changes: 25 additions & 0 deletions agent-os/tracing/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,28 @@ app = agent_os.get_app()
**Best Practice**: Always use a dedicated `db` in production, even with a single agent. This keeps observability data separate and makes it easier to scale or migrate later.
</Tip>

## Advanced Trace Search

Use advanced filtering with `POST /traces/search`. The request body accepts the FilterExpr DSL and supports grouping:

| group_by | Returns |
| --- | --- |
| `run` | Individual traces |
| `session` | Aggregated session stats |

```json
{
"filter": {
"op": "AND",
"conditions": [
{"op": "EQ", "key": "status", "value": "OK"},
{"op": "CONTAINS", "key": "user_id", "value": "admin"}
]
},
"group_by": "run",
"page": 1,
"limit": 20
}
```

Fetch filterable fields and operators with `GET /traces/filter-schema`. Use this to build UI filters that match your database capabilities.
12 changes: 12 additions & 0 deletions agent-os/usage/client/run-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,18 @@ mode: wide
Make sure you have an AgentOS server running on port 7777. See [Creating Your First OS](/agent-os/run-your-os) for setup instructions.
</Step>

<Step title="Supported Image Types">
AgentOS accepts the following image MIME types for uploads:

| Type | MIME |
| --- | --- |
| PNG | `image/png` |
| JPEG | `image/jpeg`, `image/jpg` |
| WebP | `image/webp` |
| HEIC | `image/heic` |
| HEIF | `image/heif` |
</Step>

<Step title="Run the Client">
<CodeGroup>
```bash Mac
Expand Down
12 changes: 12 additions & 0 deletions agent-os/usage/client/run-teams.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ mode: wide
Make sure you have an AgentOS server running with teams configured. See [Creating Your First OS](/agent-os/run-your-os) for setup instructions.
</Step>

<Step title="Supported Image Types">
AgentOS accepts the following image MIME types for uploads:

| Type | MIME |
| --- | --- |
| PNG | `image/png` |
| JPEG | `image/jpeg`, `image/jpg` |
| WebP | `image/webp` |
| HEIC | `image/heic` |
| HEIF | `image/heif` |
</Step>

<Step title="Run the Client">
<CodeGroup>
```bash Mac
Expand Down
21 changes: 20 additions & 1 deletion agent-os/usage/hitl.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,31 @@ curl -X POST http://localhost:7777/agents/data_manager/runs \

# 2. Continue with approval (use the run_id and tool_call_id from response)
curl -X POST http://localhost:7777/agents/data_manager/runs/{run_id}/continue \
-F "tools=[{\"tool_call_id\": \"{tool_call_id}\", \"tool_name\": \"delete_records\", \"tool_args\": {\"table_name\": \"users\", \"count\": 50}}, \"confirmed\": true}]" \
-F 'tools=[{"tool_call_id":"{tool_call_id}","tool_name":"delete_records","tool_args":{"table_name":"users","count":50},"confirmed":true}]' \
-F "session_id=test_session" \
-F "user_id=test_user" \
-F "stream=false"

# 3. Continue after admin approval is resolved in DB
curl -X POST http://localhost:7777/agents/data_manager/runs/{run_id}/continue \
-F "tools=" \
-F "session_id=test_session" \
-F "user_id=test_user" \
-F "stream=false"
```

If an admin resolves a required approval in the database, you can continue with an empty `tools` value. Non-admin users receive `403` if a required approval is still pending.

## Approval Status API

Poll a single approval record:

```bash
GET /approvals/{approval_id}/status
```

When a run pauses, each tool that requires approval is stamped with `approval_id`. Store that ID and poll for status changes. Admins with the `approvals:write` scope can continue once the approval is resolved.

## Usage

<Steps>
Expand Down
15 changes: 7 additions & 8 deletions cookbook/tools/built-in.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ agent.print_response("Analyze AAPL's recent performance")
| SQL | `from agno.tools.sql import SQLTools` | Generic SQL |
| CSV | `from agno.tools.csv_toolkit import CsvTools` | CSV analysis |
| Pandas | `from agno.tools.pandas import PandasTools` | DataFrame operations |
| BigQuery | `from agno.tools.google_bigquery import BigQueryTools` | Google BigQuery |
| BigQuery | `from agno.tools.google import GoogleBigQueryTools` | Google BigQuery |
| Redshift | `from agno.tools.redshift import RedshiftTools` | AWS Redshift |

```python
Expand Down Expand Up @@ -119,7 +119,7 @@ agent.print_response("Scrape and summarize https://example.com/blog")
| X (Twitter) | `from agno.tools.x import XTools` | Twitter/X API |
| Reddit | `from agno.tools.reddit import RedditTools` | Reddit posts |
| Email | `from agno.tools.email import EmailTools` | Send emails |
| Gmail | `from agno.tools.gmail import GmailTools` | Gmail integration |
| Gmail | `from agno.tools.google import GmailTools` | Gmail integration |
| Twilio | `from agno.tools.twilio import TwilioTools` | SMS messaging |
| WhatsApp | `from agno.tools.whatsapp import WhatsAppTools` | WhatsApp messages |
| Telegram | `from agno.tools.telegram import TelegramTools` | Telegram bot |
Expand All @@ -137,9 +137,9 @@ agent.print_response("Send a message to #general saying 'Hello from AI!'")

| Tool | Import | Description |
|------|--------|-------------|
| Google Calendar | `from agno.tools.googlecalendar import GoogleCalendarTools` | Calendar events |
| Google Sheets | `from agno.tools.googlesheets import GoogleSheetsTools` | Spreadsheets |
| Google Drive | `from agno.tools.google_drive import GoogleDriveTools` | File storage |
| Google Calendar | `from agno.tools.google import GoogleCalendarTools` | Calendar events |
| Google Sheets | `from agno.tools.google import GoogleSheetsTools` | Spreadsheets |
| Google Drive | `from agno.tools.google import GoogleDriveTools` | File storage |
| Notion | `from agno.tools.notion import NotionTools` | Notion pages |
| Todoist | `from agno.tools.todoist import TodoistTools` | Task management |
| Trello | `from agno.tools.trello import TrelloTools` | Kanban boards |
Expand All @@ -152,7 +152,7 @@ agent.print_response("Send a message to #general saying 'Hello from AI!'")

```python
from agno.agent import Agent
from agno.tools.googlecalendar import GoogleCalendarTools
from agno.tools.google import GoogleCalendarTools

agent = Agent(tools=[GoogleCalendarTools()])
agent.print_response("What meetings do I have tomorrow?")
Expand Down Expand Up @@ -212,7 +212,7 @@ agent.print_response("Generate an image of a futuristic city at sunset")
| Calculator | `from agno.tools.calculator import CalculatorTools` | Math operations |
| Sleep | `from agno.tools.sleep import SleepTools` | Add delays |
| Weather | `from agno.tools.openweather import OpenWeatherTools` | Weather data |
| Maps | `from agno.tools.google_maps import GoogleMapsTools` | Location services |
| Maps | `from agno.tools.google import GoogleMapTools` | Location services |
| Visualization | `from agno.tools.visualization import VisualizationTools` | Charts and plots |
| WebBrowser | `from agno.tools.webbrowser import WebBrowserTools` | Browser automation |

Expand All @@ -231,4 +231,3 @@ python 02_agents/finance/yfinance_agent.py
# Web scraping
python 02_agents/web/firecrawl_agent.py
```

1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -5825,6 +5825,7 @@
"examples/models/openai/responses/memory",
"examples/models/openai/responses/pdf-input-local",
"examples/models/openai/responses/pdf-input-url",
"examples/models/openai/responses/file-input-direct",
"examples/models/openai/responses/reasoning-o3-mini",
"examples/models/openai/responses/structured-output",
"examples/models/openai/responses/structured-output-with-tools",
Expand Down
7 changes: 7 additions & 0 deletions examples/knowledge/cloud/cloud-agentos.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ github_docs = GitHubConfig(
name="My Repository",
repo="private/repo",
token=getenv("GITHUB_TOKEN"), # Fine-grained PAT with Contents: read
# GitHub App auth requires PyJWT with cryptography and a PEM private key
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@willemcdejongh for any more updates in doc needed for this?

app_id=getenv("GITHUB_APP_ID"),
installation_id=getenv("GITHUB_INSTALLATION_ID"),
private_key=getenv("GITHUB_PRIVATE_KEY"),
branch="main",
)

Expand Down Expand Up @@ -147,6 +151,9 @@ source .venvs/demo/bin/activate

# Export relevant API keys
export SHAREPOINT_TENANT_ID="***"
export GITHUB_APP_ID="***"
export GITHUB_INSTALLATION_ID="***"
export GITHUB_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"

python cloud_agentos.py
```
12 changes: 9 additions & 3 deletions examples/knowledge/cloud/github.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
title: "GitHub Content Source for Knowledge"
description: "Load files and folders from GitHub repositories into your Knowledge base."
---
Load files and folders from GitHub repositories into your Knowledge base. Supports both public and private repositories using fine-grained personal access tokens.
Load files and folders from GitHub repositories into your Knowledge base. Supports public repos, fine-grained PATs, and GitHub App authentication.

Check warning on line 5 in examples/knowledge/cloud/github.mdx

View check run for this annotation

Mintlify / Mintlify Validation (agno-v2) - vale-spellcheck

examples/knowledge/cloud/github.mdx#L5

Did you really mean 'repos'?

```python
"""
GitHub Content Source for Knowledge
====================================

Load files and folders from GitHub repositories into your Knowledge base.
Supports both public and private repositories using fine-grained personal access tokens.
Supports both public and private repositories using fine-grained personal access tokens or GitHub App auth.

Features:
- Load single files or entire folders recursively
Expand All @@ -20,9 +20,11 @@

Requirements:
- For private repos: GitHub fine-grained PAT with "Contents: read" permission
- For GitHub App auth: PyJWT with cryptography and a PEM private key
- `private_key` must start with `-----BEGIN RSA PRIVATE KEY-----` or `-----BEGIN PRIVATE KEY-----`

Usage:
1. Configure GitHubConfig with repo and optional token
1. Configure GitHubConfig with repo and optional token or GitHub App credentials
2. Register the config on Knowledge via content_sources
3. Use .file() or .folder() to create content references
4. Insert into knowledge with knowledge.insert()
Expand All @@ -39,11 +41,15 @@

# Configure GitHub content source
# For private repos, set GITHUB_TOKEN env var to a fine-grained PAT with "Contents: read"
# For GitHub App auth, set GITHUB_APP_ID, GITHUB_INSTALLATION_ID, GITHUB_PRIVATE_KEY
github_config = GitHubConfig(
id="my-repo",
name="My Repository",
repo="private/repo", # Format: owner/repo
token=getenv("GITHUB_TOKEN"), # Optional for public repos
app_id=getenv("GITHUB_APP_ID"),
installation_id=getenv("GITHUB_INSTALLATION_ID"),
private_key=getenv("GITHUB_PRIVATE_KEY"),
branch="main", # Default branch
)

Expand Down
70 changes: 70 additions & 0 deletions examples/models/openai/responses/file-input-direct.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
title: "OpenAI Responses Direct File Input"
description: "Cookbook example for `openai/responses/file_input_direct.py`."

Check warning on line 3 in examples/models/openai/responses/file-input-direct.mdx

View check run for this annotation

Mintlify / Mintlify Validation (agno-v2) - vale-spellcheck

examples/models/openai/responses/file-input-direct.mdx#L3

Did you really mean 'file_input_direct'?
---
```python
"""
Openai File Input Direct
========================

Cookbook example for `openai/responses/file_input_direct.py`.
"""

from pathlib import Path

from agno.agent import Agent
from agno.media import File
from agno.models.openai.responses import OpenAIResponses
from agno.utils.media import download_file

# ---------------------------------------------------------------------------
# Create Agent
# ---------------------------------------------------------------------------

agent = Agent(
model=OpenAIResponses(id="gpt-4o"),
markdown=True,
)

# ---------------------------------------------------------------------------
# Run Agent
# ---------------------------------------------------------------------------
if __name__ == "__main__":
# File via URL
agent.print_response(
"Summarize the key contribution of this paper in 2-3 sentences.",
files=[File(url="https://arxiv.org/pdf/1706.03762")],
)

# File via local filepath
pdf_path = Path(__file__).parent.joinpath("ThaiRecipes.pdf")
download_file(
"https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf", str(pdf_path)
)

agent.print_response(
"List the first 3 recipes from this cookbook.",
files=[File(filepath=pdf_path, mime_type="application/pdf")],
)

# File via raw bytes
csv_content = b"name,role,team\nAlice,Engineer,Platform\nBob,Designer,Product\nCharlie,PM,Growth"

agent.print_response(
"Describe the team structure from this CSV.",
files=[File(content=csv_content, filename="team.csv", mime_type="text/csv")],
)
```

## Run the Example
```bash
# Clone and setup repo
git clone https://github.com/agno-agi/agno.git
cd agno/cookbook/90_models/openai/responses

# Create and activate virtual environment
./scripts/demo_setup.sh
source .venvs/demo/bin/activate

python file_input_direct.py
```
Loading