Standardized Agent Runtime — preset-based AI agent gateway with stable HTTP API
Project description
Standardized Agent Runtime (MVP)
Run a preset-based AI agent gateway and call it immediately via a stable HTTP contract. The north-star workflow is: run the service locally/VM → call POST /invoke with JSON → get consistent JSON back (with discoverable docs at GET /schema and Swagger at /docs).
Quickstart (pip)
All examples use port 4280.
pip install -e .
# Run a specific agent preset (presets are bundled in the package)
AGENT_PRESET=summarizer agent-toolbox
Or with host/port:
AGENT_PRESET=classifier PORT=4280 agent-toolbox
For other presets, set AGENT_PRESET to meeting_notes, extractor, classifier, or triage.
Quickstart (Make, from repo)
All examples use port 4280.
git clone <REPO_URL>
cd agent-toolbox
make install
# Run a specific agent preset locally
AGENT_PRESET=summarizer make run
For other presets, change the AGENT_PRESET value (for example meeting_notes, extractor, classifier, triage).
Docker (alternative)
make docker-up AGENT=summarizer
To stop containers:
make docker-down
Quickstart (local, manual)
All examples use port 4280.
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
python -m pip install -r requirements.txt
uvicorn app.main:app --host 0.0.0.0 --port 4280
Open Swagger UI at http://localhost:4280/docs.
Switch agent preset
Presets are bundled in the package under app/presets/*.yaml. Select one via AGENT_PRESET:
AGENT_PRESET=classifier PROVIDER=stub uvicorn app.main:app --host 0.0.0.0 --port 4280
Quickstart (Docker Compose)
docker compose up --build
To switch presets:
AGENT_PRESET=triage docker compose up --build
API surface (stable across presets)
GET /– service metadataGET /health– health infoGET /schema– active preset schemas (no provider calls)POST /invoke– core invocationPOST /stream– 501 Not Implemented in v1
curl examples
All examples assume the server is running at http://localhost:4280.
Health
curl http://localhost:4280/health
Schema
curl http://localhost:4280/schema
Invoke: summarizer
curl -X POST http://localhost:4280/invoke \
-H "Content-Type: application/json" \
-d '{"input": {"text": "Some long text to summarize."}}'
Invoke: classifier
curl -X POST http://localhost:4280/invoke \
-H "Content-Type: application/json" \
-d '{
"input": {
"items": [
{"id": "1", "content": "Reset my password"},
{"id": "2", "content": "Pricing question"}
],
"categories": ["support", "sales", "other"]
}
}'
Auth example (Clerk)
Mutating endpoints (like POST /agents/register) require a Clerk session token when Clerk is configured. Pass a Bearer token from your frontend session.
CLERK_JWKS_URL=https://<clerk-frontend-api>/.well-known/jwks.json \
CLERK_ISSUER=https://<clerk-frontend-api> \
uvicorn app.main:app --host 0.0.0.0 --port 4280
curl -X POST http://localhost:4280/invoke \
-H "Authorization: Bearer <clerk-session-token>" \
-H "Content-Type: application/json" \
-d '{"input": {"text": "hello"}}'
Legacy: setting AUTH_TOKEN enables a static bearer token for dev/tests.
Context and session memory
You can pass optional context on POST /invoke to use session memory. Presets that support memory (e.g. summarizer, triage) use a memory policy (last N events, max chars) when building the prompt.
Invoke with optional context
- Backward compatible:
{"input": {...}}only is valid; nocontextrequired. - With session:
{"input": {...}, "context": {"session_id": "<id>"}}uses stored events for that session (and adds this invoke to the session when the preset supports memory). - With inline memory:
{"input": {...}, "context": {"memory": [{"role": "user", "content": "..."}]}}passes recent context without a session. - Empty context:
{"input": {...}, "context": {}}is accepted and does not fail.
When a session is used, the success response includes meta.session_id and meta.memory_used_count.
Session Memory API
POST /sessions– Create a new session. Body optional. Returns 201 with{ "session_id": "<uuid>" }. The active preset id is used asagent_id.POST /sessions/{id}/events– Append events. Body:{ "events": [ { "role": "user", "content": "..." }, ... ] }. Returns 200 with{ "ok": true, "session_id": "<id>", "appended": N }.GET /sessions/{id}– Get session. Returns 200 with{ "session_id", "agent_id", "created_at", "events", "running_summary" }or 404 when the session does not exist.
Policy (last N events, max chars)
Presets that set supports_memory: true and memory_policy in YAML (e.g. summarizer, triage) apply:
- max_messages: only the last N events are included in the prompt.
- max_chars: total event content is truncated to this many characters.
Example: summarizer uses max_messages: 2, max_chars: 8000 so the prompt contains at most 2 stored events (and up to 8000 chars).
curl examples (session memory)
Create a session:
curl -X POST http://localhost:4280/sessions
# → 201 { "session_id": "..." }
Append an event (e.g. a note):
SESSION_ID="<paste session_id from above>"
curl -X POST "http://localhost:4280/sessions/${SESSION_ID}/events" \
-H "Content-Type: application/json" \
-d '{"events": [{"role": "user", "content": "Reminder: follow up on Q3 report"}]}'
# → 200 { "ok": true, "session_id": "...", "appended": 1 }
Invoke with session (success response includes meta.session_id and meta.memory_used_count):
curl -X POST http://localhost:4280/invoke \
-H "Content-Type: application/json" \
-d "{\"input\": {\"text\": \"Summarize my notes.\"}, \"context\": {\"session_id\": \"${SESSION_ID}\"}}"
Get session (events, agent_id, created_at):
curl "http://localhost:4280/sessions/${SESSION_ID}"
CORS (frontend Session tab)
Set CORS_ORIGINS so the frontend can call the gateway (e.g. Session tab). Example: CORS_ORIGINS=http://localhost:3000 or * for development.
Configuration (environment variables)
AGENT_PRESET: which preset to load (default:summarizer). Presets are YAML files bundled in the package (app/presets).PROVIDER: provider implementation (default:stub). Useopenrouterfor one API key and many models (recommended).AUTH_TOKEN: optional legacy bearer auth for dev/tests (Authorization: Bearer <token>).CLERK_JWKS_URL: Clerk JWKS URL for verifying session tokens (e.g.https://<clerk-frontend-api>/.well-known/jwks.json).CLERK_JWT_KEY: optional Clerk JWT public key (PEM). Use this instead of JWKS if you prefer.CLERK_ISSUER: expected token issuer (usuallyhttps://<clerk-frontend-api>).CLERK_AUDIENCE: optional audience to enforce in JWT verification.CLERK_AUTHORIZED_PARTIES: optional comma-separatedazpallowlist.OPENROUTER_API_KEY: required whenPROVIDER=openrouter. Get a key at openrouter.ai/keys.OPENROUTER_MODEL: optional model id (default:openai/gpt-4o-mini). See openrouter.ai/models.OPENAI_API_KEY/OPENAI_MODEL: optional, for direct OpenAI whenPROVIDER=openai.DATABASE_URL: Postgres connection string (Supabase). When set, Postgres is used for registry + sessions.DB_PATH: path to SQLite DB whenDATABASE_URLis not set (default:./data/gateway.db).SESSION_DB_PATH: legacy alias forDB_PATH(still supported).CORS_ORIGINS: comma-separated origins for CORS (default:*). Use e.g.http://localhost:3000for the frontend Session tab.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: Clerk publishable key for the frontend.CLERK_SECRET_KEY: Clerk secret key for the frontend server.NEXT_PUBLIC_CLERK_JWT_TEMPLATE: optional Clerk JWT template name used when requesting tokens from the frontend.
Providers
- StubProvider (default): deterministic JSON output, runs with no API keys.
- OpenRouterProvider (recommended): one API key for many models (OpenAI, Claude, Gemini, etc.). Set
PROVIDER=openrouterandOPENROUTER_API_KEY. - OpenAIProvider (optional): direct OpenAI; set
PROVIDER=openaiandOPENAI_API_KEY.
Architecture (request flow)
POST /invoke follows this pipeline:
- auth (mutating endpoints only; Clerk session token when configured) →\
- input validation (jsonschema) →\
- engine/router selects primitive (
transform/extract/classify) →\ - provider call →\
- output validation (jsonschema) →\
- one repair attempt (if invalid) → response
In v1, POST /stream returns 501 Not Implemented with a standard error envelope.
Docker (direct)
docker build -t agent-gateway .
docker run --rm -p 4280:4280 \
-e AGENT_PRESET=summarizer \
-e PROVIDER=stub \
agent-gateway
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_toolbox-0.1.0.tar.gz.
File metadata
- Download URL: agent_toolbox-0.1.0.tar.gz
- Upload date:
- Size: 43.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5beda5b4e424c9d015ddcc8151751092b2fd40dcf34874bbbf4d7295abef3b81
|
|
| MD5 |
870cb8cef1d0e275ac5af4ec456f3a26
|
|
| BLAKE2b-256 |
382cc797cbe31651a60fdbd36969ca8c988d2aafae059dc6a0c0cec31241e729
|
File details
Details for the file agent_toolbox-0.1.0-py3-none-any.whl.
File metadata
- Download URL: agent_toolbox-0.1.0-py3-none-any.whl
- Upload date:
- Size: 37.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
660a3659f3a67643457f6c14333ad781d4d14d6e17731c3466fcf8e9eb66179e
|
|
| MD5 |
ab6a1ef2ba68133d51515a6a54ffe5e9
|
|
| BLAKE2b-256 |
155d3be9053691c3ff71ce828184c15c8311627532de2a96d0ca8f5cf6e1e3f7
|