Metadata-Version: 2.4
Name: agents-gateway
Version: 0.2.7
Summary: A FastAPI extension for building API-first AI agent services
Project-URL: Homepage, https://honesdev.com/agents-gateway
Project-URL: Repository, https://github.com/vince-nyanga/agents-gateway
Project-URL: Documentation, https://vince-nyanga.github.io/agents-gateway/
Project-URL: Issues, https://github.com/vince-nyanga/agents-gateway/issues
Project-URL: Changelog, https://github.com/vince-nyanga/agents-gateway/releases
Author-email: Vincent Nyanga <vince.nyanga@protonmail.ch>
Maintainer-email: Vincent Nyanga <vince.nyanga@protonmail.ch>
License-Expression: MIT
License-File: LICENSE
Keywords: agents,ai,api,automation,chatbot,fastapi,gateway,llm
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: AsyncIO
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: apscheduler<4,>=3.10
Requires-Dist: cryptography>=42.0
Requires-Dist: datamodel-code-generator>=0.26
Requires-Dist: fastapi>=0.110
Requires-Dist: greenlet>=3.3.1
Requires-Dist: httpx>=0.27
Requires-Dist: jsonschema>=4.21
Requires-Dist: litellm>=1.40
Requires-Dist: mcp>=1.20
Requires-Dist: opentelemetry-api>=1.24
Requires-Dist: opentelemetry-sdk>=1.24
Requires-Dist: opentelemetry-semantic-conventions>=0.45b
Requires-Dist: pydantic-settings>=2.2
Requires-Dist: pydantic>=2.7
Requires-Dist: python-dotenv>=1.0
Requires-Dist: python-frontmatter>=1.1
Requires-Dist: pyyaml>=6.0
Requires-Dist: sqlalchemy>=2.0
Requires-Dist: typer>=0.12
Requires-Dist: uvicorn[standard]>=0.29
Requires-Dist: watchfiles>=0.21
Provides-Extra: all
Requires-Dist: aio-pika>=9.0; extra == 'all'
Requires-Dist: aiosqlite>=0.20; extra == 'all'
Requires-Dist: alembic>=1.13; extra == 'all'
Requires-Dist: asyncpg>=0.29; extra == 'all'
Requires-Dist: itsdangerous>=2.2; extra == 'all'
Requires-Dist: jinja2>=3.1; extra == 'all'
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.24; extra == 'all'
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.24; extra == 'all'
Requires-Dist: pyjwt[crypto]>=2.8; extra == 'all'
Requires-Dist: python-multipart>=0.0.9; extra == 'all'
Requires-Dist: redis>=5.0; extra == 'all'
Requires-Dist: slack-bolt>=1.18; extra == 'all'
Requires-Dist: slowapi>=0.1.9; extra == 'all'
Provides-Extra: dashboard
Requires-Dist: itsdangerous>=2.2; extra == 'dashboard'
Requires-Dist: jinja2>=3.1; extra == 'dashboard'
Requires-Dist: python-multipart>=0.0.9; extra == 'dashboard'
Provides-Extra: dev
Requires-Dist: aio-pika>=9.0; extra == 'dev'
Requires-Dist: aiosqlite>=0.20; extra == 'dev'
Requires-Dist: alembic>=1.13; extra == 'dev'
Requires-Dist: asyncpg>=0.29; extra == 'dev'
Requires-Dist: httpx; extra == 'dev'
Requires-Dist: itsdangerous>=2.2; extra == 'dev'
Requires-Dist: jinja2>=3.1; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: psycopg2-binary>=2.9; extra == 'dev'
Requires-Dist: pyjwt[crypto]>=2.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: python-multipart>=0.0.9; extra == 'dev'
Requires-Dist: redis>=5.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Requires-Dist: slack-bolt>=1.18; extra == 'dev'
Requires-Dist: slowapi>=0.1.9; extra == 'dev'
Requires-Dist: testcontainers[postgres,rabbitmq,redis]>=4.0; extra == 'dev'
Requires-Dist: types-jsonschema>=4.21; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Provides-Extra: gcp
Requires-Dist: google-auth>=2.20; extra == 'gcp'
Provides-Extra: oauth2
Requires-Dist: pyjwt[crypto]>=2.8; extra == 'oauth2'
Provides-Extra: otlp
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.24; extra == 'otlp'
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.24; extra == 'otlp'
Provides-Extra: postgres
Requires-Dist: alembic>=1.13; extra == 'postgres'
Requires-Dist: asyncpg>=0.29; extra == 'postgres'
Provides-Extra: postgresql
Requires-Dist: alembic>=1.13; extra == 'postgresql'
Requires-Dist: asyncpg>=0.29; extra == 'postgresql'
Provides-Extra: rabbitmq
Requires-Dist: aio-pika>=9.0; extra == 'rabbitmq'
Provides-Extra: rate-limiting
Requires-Dist: slowapi>=0.1.9; extra == 'rate-limiting'
Provides-Extra: redis
Requires-Dist: redis>=5.0; extra == 'redis'
Provides-Extra: slack
Requires-Dist: slack-bolt>=1.18; extra == 'slack'
Provides-Extra: sqlite
Requires-Dist: aiosqlite>=0.20; extra == 'sqlite'
Requires-Dist: alembic>=1.13; extra == 'sqlite'
Provides-Extra: webhooks
Requires-Dist: jinja2>=3.1; extra == 'webhooks'
Description-Content-Type: text/markdown

  Agent Gateway

# Agent Gateway

[![PyPI version](https://img.shields.io/pypi/v/agents-gateway)](https://pypi.org/project/agents-gateway/)
[![Python](https://img.shields.io/pypi/pyversions/agents-gateway)](https://pypi.org/project/agents-gateway/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![CI](https://github.com/vince-nyanga/agents-gateway/actions/workflows/ci.yml/badge.svg)](https://github.com/vince-nyanga/agents-gateway/actions/workflows/ci.yml)

A FastAPI extension for building API-first AI agent services. Define agents, tools, and skills as markdown files, then serve them as a production-ready API with authentication, persistence, scheduling, notifications, and more.

## Quick Start

```bash
pip install agents-gateway[all]

# Scaffold a new project
agents-gateway init myproject
cd myproject

# Start the server
agents-gateway serve
```

Your agent API is now running at `http://localhost:8000` with interactive docs at `/docs`.

## Define an Agent

Create a markdown file at `workspace/agents/assistant/AGENT.md`:

```markdown
---
description: A helpful assistant that answers questions
skills:
  - general-tools
memory:
  enabled: true
---

You are a helpful assistant. Answer questions clearly and concisely.
```

That's it — the agent is now available via the API.

## Add a Tool

### File-based tool

Create `workspace/tools/http-example/TOOL.md`:

```markdown
---
name: http-example
description: Make an HTTP GET request and return the response
parameters:
  url:
    type: string
    description: The URL to fetch
    required: true
---
```

Add a handler in `workspace/tools/http-example/handler.py`:

```python
import httpx

async def handler(url: str) -> str:
    async with httpx.AsyncClient() as client:
        resp = await client.get(url)
        return resp.text
```

### Code-based tool

Register tools directly in Python:

```python
from agent_gateway import Gateway

gw = Gateway(workspace="./workspace")

@gw.tool(agent="assistant")
def add_numbers(a: float, b: float) -> float:
    """Add two numbers together."""
    return a + b
```

## Use the API

```bash
# Invoke an agent (single-turn)
curl -X POST http://localhost:8000/v1/agents/assistant/invoke \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $API_KEY" \
  -d '{"message": "What is 2 + 3?"}'

# Chat with an agent (multi-turn)
curl -X POST http://localhost:8000/v1/agents/assistant/chat \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $API_KEY" \
  -d '{"message": "Hello!"}'
```

## Features

- **Markdown-defined agents** — Define agents, tools, and skills as markdown files with YAML frontmatter
- **Multi-LLM support** — Use any model supported by [LiteLLM](https://docs.litellm.ai/) (OpenAI, Gemini, Anthropic, Ollama, etc.)
- **Built-in authentication** — API key and OAuth2/JWT auth out of the box
- **Persistence** — SQLite or PostgreSQL storage for conversations, executions, and audit logs
- **Dashboard** — Built-in web dashboard for monitoring agents, executions, and conversations
- **Scheduling** — Cron-based agent scheduling via APScheduler
- **Notifications** — Slack and webhook notification backends with per-agent rules
- **Async execution** — Queue-based async processing with Redis or RabbitMQ
- **Telemetry** — OpenTelemetry instrumentation with console or OTLP export
- **Structured output** — Pydantic model or JSON Schema output validation
- **Agent memory** — Automatic memory extraction and recall across conversations
- **Streaming** — Server-sent events (SSE) for real-time chat responses
- **Input/output schemas** — JSON Schema validation for agent inputs and outputs
- **CLI** — Project scaffolding, agent listing, and dev server via `agents-gateway` CLI
- **Lifecycle hooks** — `before_invoke`, `after_invoke`, `on_error` hooks for custom logic
- **Sub-app mounting** — Mount into an existing FastAPI app with `gw.mount_to(app, path="/ai")` — full feature parity

## Sub-App Mounting

Mount the gateway into an existing FastAPI app with full feature parity — dashboard, auth, OAuth2, static assets, and all background subsystems work identically:

```python
from fastapi import FastAPI
from agent_gateway import Gateway

app = FastAPI(title="My App")
gw = Gateway(workspace="./workspace")

gw.use_api_keys([{"name": "dev", "key": "secret", "scopes": ["*"]}])
gw.use_dashboard(auth_username="user", auth_password="pass",
                 admin_username="admin", admin_password="admin")

gw.mount_to(app, path="/ai")

# Your routes at /
# Gateway API at /ai/v1/...
# Dashboard at /ai/dashboard/
```

See the [mounting guide](https://vince-nyanga.github.io/agents-gateway/guides/mounting/) for details.

## Configuration

Configure your gateway with `workspace/gateway.yaml`:

```yaml
server:
  port: 8000

model:
  default: "gemini/gemini-2.0-flash"
  temperature: 0.1

memory:
  enabled: true
```

Or configure programmatically:

```python
from agent_gateway import Gateway

gw = Gateway(
    workspace="./workspace",
    title="My Agent Service",
)

# Fluent API for backends
gw.use_api_key_auth(api_key="your-key")
gw.use_sqlite("sqlite+aiosqlite:///data.db")
gw.use_slack_notifications(bot_token="xoxb-...", default_channel="#alerts")
```

## Installation Extras

Install only what you need:

```bash
pip install agents-gateway[sqlite]       # SQLite persistence
pip install agents-gateway[postgres]     # PostgreSQL persistence
pip install agents-gateway[redis]        # Redis queue backend
pip install agents-gateway[rabbitmq]     # RabbitMQ queue backend
pip install agents-gateway[oauth2]       # OAuth2/JWT authentication
pip install agents-gateway[slack]        # Slack notifications
pip install agents-gateway[dashboard]    # Web dashboard
pip install agents-gateway[otlp]        # OTLP telemetry export
pip install agents-gateway[all]          # Everything
```

## Documentation

Full documentation is available at [vince-nyanga.github.io/agents-gateway](https://vince-nyanga.github.io/agents-gateway/).

## License

MIT
