> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dari.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Protocols And Streaming

> Use OpenAI Chat Completions and Anthropic Messages with one normalized router.

`router.fetch()` accepts `POST` requests in either protocol and returns the same protocol in the response.

| Protocol                | Paths                                          |
| ----------------------- | ---------------------------------------------- |
| OpenAI Chat Completions | `/v1/chat/completions` and `/chat/completions` |
| Anthropic Messages      | `/v1/messages` and `/messages`                 |

Unknown paths return not-found errors. Known paths require `POST`.

## Pure request adapters

The `/protocols` subpath exposes adapters without HTTP dispatch:

```ts theme={null}
import { anthropicRequest, openAIChatRequest } from "@mupt-ai/dari-router/protocols";

const openAI = openAIChatRequest({
  model: "my-router",
  messages: [{ role: "user", content: "Hello" }],
});
const anthropic = anthropicRequest({
  model: "my-router",
  max_tokens: 256,
  messages: [{ role: "user", content: "Hello" }],
});
```

Both become a `RouterRequest`. Its `items` preserve messages, tool calls, tool results, reasoning, and hosted tool calls; tools, generation controls, reasoning, response format, metadata, cache key, and streaming remain separate fields. The incoming model is `requestedModel`; it does not force the policy's selection.

## Responses and routing metadata

The response includes a `dari_routing` object with the requested model, selected model, reasoning effort, and policy reason. Headers include `X-Router-Selected-Model` and, when available, `X-Router-Reasoning-Effort`. Streaming responses include routing metadata in their initial protocol event.

## Streaming

Set `stream: true`. Router Core translates normalized executor events into the caller's SSE format and primes the stream before committing headers, so failures before provider output are ordinary JSON errors. After commitment, failures become protocol stream errors. Cancellation aborts the policy/executor signal and closes the executor iterator.

OpenAI `stream_options` is accepted for compatibility; usage is emitted in the final usage chunk. Anthropic receives its normal message event sequence.

## Tools and images

The portable contract supports function tools, tool choice, tool results, images, and structured output. The executor must advertise the relevant capability. Hosted `web_search` items are provider-native and replayable; OpenAI can serialize them, while Anthropic Messages cannot represent them and fails closed if one reaches Anthropic output.

## Reasoning and continuation

Reasoning is normalized across providers. OpenAI responses use `reasoning_content` and `reasoning_details`; Anthropic responses use thinking blocks. Provider continuations are tagged with their source identity and are not replayed across incompatible providers. When readable reasoning has no provider continuation, the router wraps it in a portable `dari-ir-v1` envelope — a versioned, base64 JSON capsule that lets the next request carry prior reasoning without inventing provider-native signatures the provider could not parse.

The `/protocols` entry point exposes protocol and continuation types for custom adapters. Preserve continuation fields when forwarding a request; do not invent provider signatures.

## Errors

Framework errors are represented by `RouterFrameworkError` and serialized in the caller's protocol shape. Common boundaries are:

| Kind              | Meaning                                            |
| ----------------- | -------------------------------------------------- |
| `invalid_request` | Malformed request or no eligible model             |
| `configuration`   | Invalid router, model, executor, or protocol setup |
| `policy`          | Policy failure or invalid decision                 |
| `executor`        | Provider or output failure                         |
| `cancelled`       | Work aborted before response commitment            |

The framework implements a portable subset rather than every provider-specific feature. Unsupported fields are rejected instead of silently disappearing.
