Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ set(ARBITER_SOURCES
src/constitution.cpp
src/orchestrator.cpp
src/advisor_gate.cpp
src/advisor.cpp
src/api_server.cpp
src/sandbox.cpp
src/idempotency_cache.cpp
Expand Down
89 changes: 89 additions & 0 deletions docs/api/events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# `POST /v1/events`

**Auth:** tenant — _Status:_ experimental

Turns a structured hardware or software event into a full Arbiter run. The runtime routes the event to an agent, supplies that agent with its normal memory and tools, and streams the resulting reasoning and actions as Server-Sent Events.

Use this endpoint for application webhooks, infrastructure alerts, sensor readings, edge-device signals, robotics bridges, and other systems that produce events rather than conversational prompts.

## Request

### Body

| Field | Type | Required | Description |
|---|---|---|---|
| `type` | string | yes | Event type used for agent routing, such as `sensor.temperature.threshold` or `deployment.failed`. |
| `source` | string | no | Human-readable source identifier, such as `edge/rack-04` or `github/acme/api`. |
| `payload` | any JSON value | no | Event-specific data supplied to the selected agent. |
| `agent` | string | no | Explicit agent id. When present, bypasses type-based routing. |

### Headers

| Header | Required | Purpose |
|---|---|---|
| `Authorization` | yes | `Bearer <tenant token>`. See [authentication](../concepts/authentication.md). |
| `Content-Type` | yes | `application/json`. |

```bash
curl -N http://127.0.0.1:8080/v1/events \
-H "Authorization: Bearer $ARBITER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "sensor.temperature.threshold",
"source": "edge/rack-04",
"payload": { "celsius": 84.6 }
}'
```

## Routing

File-backed agents opt into events with `event_types` in their constitution. Each entry is a glob matched against the event type. Arbiter scans the JSON definitions in its configured agents directory; tenant agents created through `POST /v1/agents` are not part of automatic event routing in this experimental version. If no file-backed agent matches, Arbiter routes the event to `index`.

```json
{
"name": "facilities",
"model": "ollama/qwen3.6",
"event_types": [
"sensor.*",
"facility.alert.*"
],
"capabilities": ["exec"]
}
```

An explicit `agent` in the request body takes precedence over `event_types` routing.

Keep routing patterns distinct. If multiple agents match an event in this experimental implementation, the first matching agent definition is selected.

## What the agent receives

Arbiter presents the event to the selected agent as a normal turn:

```text
Event: sensor.temperature.threshold
Source: edge/rack-04
Payload: {"celsius":84.6}
```

The selected agent can use the same memory, delegation, MCP, artifact, search, and permitted execution capabilities available to a direct orchestration request.

Event payloads are input data, but they are visible to the model. Treat event sources as untrusted, grant each routed agent only the capabilities it requires, and leave host execution disabled for externally sourced events. Prefer the tenant sandbox when an agent must execute commands.

## Response

The response is `text/event-stream` and follows the same lifecycle as [`POST /v1/orchestrate`](orchestrate.md): `request_received`, agent and tool activity, advisor decisions, and a terminal `done` event.

## Failure modes

| Status | When | Body |
|---|---|---|
| 400 | Body is not a JSON object, JSON is invalid, or `type` is missing. | `{"error":"..."}` |
| 401 | Bearer token is missing or invalid, or the tenant is disabled. | `{"error":"..."}` |
| 200 + `done.ok = false` | The routed run fails after the SSE stream opens. | SSE `error` followed by `done`. |

## See also

- [`POST /v1/orchestrate`](orchestrate.md) — direct request ingestion.
- [Agent data model](../concepts/data-model.md) — agent constitution fields.
- [SSE event catalog](../concepts/sse-events.md) — streamed event shapes.
- [Authentication](../concepts/authentication.md) — tenant bearer tokens.
3 changes: 2 additions & 1 deletion docs/api/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Arbiter HTTP API

Arbiter exposes its multi-agent orchestrator as an HTTP + Server-Sent Events API. One `POST /v1/orchestrate` drives the full agentic loop — master agent turns, delegated and parallel sub-agent calls, tool invocations, generated files — and streams the whole thing back as SSE events.
Arbiter exposes its reasoning runtime as an HTTP + Server-Sent Events API. Send a direct request with `POST /v1/orchestrate`, or ingest a structured hardware or software event with `POST /v1/events`. Both drive the full agentic loop — routing, durable context, delegated and parallel sub-agent calls, tool invocations, and generated files — and stream the whole execution back as SSE events.

Billing — eligibility checks, rate cards, caps, invoicing — is delegated to an external billing service when `ARBITER_BILLING_URL` is set. The runtime exchanges every bearer for a workspace_id via `POST /v1/runtime/auth/validate`, pre-flights against `POST /v1/runtime/quota/check`, and posts post-turn telemetry to `POST /v1/runtime/usage/record`. Operators wanting a commercial deployment must implement that protocol against a service of their choosing — arbiter ships no reference implementation under this repository. With the env var unset, the runtime acts as a thin pass-through using the operator-supplied provider keys, with no eligibility checks.

Expand Down Expand Up @@ -34,6 +34,7 @@ Each endpoint page below uses the same template: **Function**, **Request**, **Re
- [`GET /v1/health`](health.md)
- [`GET /v1/metrics`](metrics.md)
- [`GET /v1/models`](models.md)
- [`POST /v1/events`](events.md)
- [`POST /v1/orchestrate`](orchestrate.md)
- [`POST /v1/requests/:id/cancel`](requests-cancel.md)
- [`GET /v1/requests`](requests/list.md)
Expand Down
Loading
Loading