# Overview
OpenResponses is a production-grade Elixir implementation of the [Open Responses specification](https://openresponses.dev) — a provider-agnostic API for interacting with large language models.
## What it does
At its simplest: you send a request, you get a response. Behind the scenes, OpenResponses manages the agentic loop, routes to the right provider, streams events back to your client, dispatches tool calls, and tracks conversation history — all without you writing any of that infrastructure.
```
POST /v1/responses
{
"model": "gpt-4o",
"input": [{"role": "user", "content": "What's the weather in London?"}],
"tools": [{"type": "function", "name": "get_weather", "parameters": {...}}]
}
```
Your client receives a stream of Server-Sent Events, or a single JSON response — your choice.
## Why Elixir?
The Open Responses spec describes a system that maps directly onto what the BEAM was built for:
| Spec requirement | BEAM advantage |
|---|---|
| Agentic loop with tool dispatch | One GenServer per request — crash isolation, OTP supervision |
| Semantic SSE streaming | Phoenix handles chunked HTTP natively; PubSub fans out to multiple consumers |
| Multi-provider concurrency | Thousands of simultaneous loops on a single node without threads |
| State machine on responses | AshStateMachine enforces valid transitions at compile time |
| Extensible provider routing | Pattern-match on model names in config — no code changes |
## Supported providers
| Provider | Model pattern | Notes |
|---|---|---|
| OpenAI | `gpt-*` | Near pass-through |
| Anthropic | `claude-*` | Full event translation |
| Google Gemini | `gemini-*` | `contents`/`parts` format |
| Ollama | `llama*`, `mistral*`, `phi*`, `qwen*` | Local models, no API key |
| z.ai | Any | Use Anthropic adapter with custom `base_url` |
| Custom | Anything | Implement `OpenResponses.Adapter` |
## Architecture in one diagram
```
Client
│
▼
POST /v1/responses
│
▼
ResponseController
│ creates Response (Ash / ETS)
▼
LoopSupervisor.start_loop/1
│
▼
Loop (GenServer, one per request)
│ resolves adapter from model name
│ applies middleware before_sample
│ calls adapter.stream/2
│ processes events
│ dispatches tool calls
│ applies middleware after_sample
│ transitions state machine
│ caches completed response
│
├──── broadcasts events via PubSub ────► SSE chunks to client
│
└──── stores in ResponseCache ────► available for previous_response_id
```
## Next steps
- [Installation](installation.html) — add OpenResponses to your Phoenix app
- [Getting Started](getting_started.html) — make your first request
- [Providers](providers.html) — configure API keys and routing