> ## 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.

# Models

> Declare candidates and let the router filter them by capability.

A model declaration is a candidate, not necessarily the model that will serve a request. Before calling your policy, the router filters out candidates that cannot satisfy the request.

## Models from Pi

`pi.model()` reads the Pi model catalog and supplies provider, API, reasoning, and capability metadata:

```ts theme={null}
import { createPiRuntime } from "@mupt-ai/dari-router";

const pi = await createPiRuntime({ apiKey: process.env.OPENAI_API_KEY! });

const models = [
  pi.model("openai/gpt-5.4-mini"),
  pi.model("openai/gpt-5.4", { defaultReasoningEffort: "high" }),
];
```

Use the model's full `provider/model-id` name. See [Pi Runtime](/framework/pi-runtime) for credentials and execution.

## Custom declarations

For a model outside Pi's catalog, declare the metadata your policy and executor need:

```ts theme={null}
import type { RouterModel } from "@mupt-ai/dari-router";

const model = {
  id: "acme/private-model",
  executor: "acme",
  provider: "acme",
  api: "private-rpc",
  reasoningEfforts: ["off", "high"],
  defaultReasoningEffort: "off",
  capabilities: {
    imageInput: true,
    toolUse: true,
    structuredOutput: true,
    streaming: true,
  },
} satisfies RouterModel;
```

The `satisfies RouterModel` annotation preserves the literal reasoning-level types in standalone declarations. Inline declarations are contextually typed.

The executor name selects the implementation in `createRouter({ executors })`. If a model omits `executor`, `createRouter` uses its default `executor` option. A model without either is a configuration error. Named executors take precedence over the default.

When omitted, `provider` defaults from the ID prefix, `api` defaults from the executor name, reasoning defaults to `off`, and capabilities default to false. Set metadata explicitly when those defaults are not true for your transport.

## Eligibility

The policy sees only candidates that support the request. Filtering covers image input, tools and tool history, structured output, streaming, and explicit reasoning effort. If no candidate remains, the request fails before the policy runs. A policy cannot select an ineligible candidate.

A request without a reasoning constraint may select any effort exposed by a candidate. A request with one is a hard constraint. Framework reasoning levels are `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, and `max`; executors map them to provider-specific controls.
