keel
Model

Overview

Give an agent an ordered model chain with explicit capabilities, limits, and failure behavior.

Model chain
Tier 1
First choice
Tier 2
Next eligible fallback
Tier n
Next eligible fallback
Inside every tier: an adapter contract
generate(context)
→ StepResult
windowTokens
maxOutputTokens
supportsTools
canForceTool
One model contract for the agent. Ordered adapters underneath.

An agent's model is a chain of one or more tiers. Each tier is an adapter that knows how to call a provider — or any other implementation of the same ModelAdapter interface, including the deterministic test doubles you write yourself. The chain chooses a tier, handles retry and fallback, and returns a normalized step result to the turn.

This separates the agent's job from the mechanics of calling a particular provider. Your application declares the order and capabilities; the runtime applies the chain's failure policy.

Why use a chain?

A provider failure and a generated answer should be distinguishable in code. Keel records retry and fallback decisions and reports exhaustion as a typed chain-exhausted defect. It does not replace that failure with a generated apology and label it a successful model response.

Masked error
provider throws
catch → apology
"Sorry, try again."
reported as success
Keel chain
retry / fallback
all tiers fail
ok: false
"chain-exhausted"
The comparison is with a wrapper that masks errors; other systems can also preserve failures.

A custom wrapper can implement equivalent behavior. Keel makes it part of the model contract shared by every agent.

Streaming is the default path

A tier can implement an optional stream(ctx) method alongside generate. When it does, the runtime prefers the stream: text deltas land on the wire as they arrive instead of after the full step. All three shipped provider adapters stream, and they speak full tool use over the same streams.

Streaming does not weaken the failure policy. A stream that fails before producing content follows the normal retry and fallback classes; a stream that fails after content has already reached the wire is never retried — the turn is cut with a typed stream-error instead of duplicated output. See Retry and fallback for the policy and Custom adapters for implementing stream.

Rules by design

  1. Explicit order

    Try tiers in declaration order. Fallback advances the selection for the rest of the turn.

    tier 1 → tier 2 → tier n
  2. Classified failures

    Transient and designated pre-content failures get one retry. Other classified errors advance immediately.

    "transient" → retry once
    "unavailable" → fallback
  3. Declared limits

    Allocations must fit every tier at startup. Each model request is checked again.

    input + reserve ≤ tier window
    otherwise → configuration error
  4. Tools across every tier

    An agent with tools requires support from every tier. An incompatible fallback fails at definition time.

    supportsTools: false
    → configuration error
  5. Explicit exhaustion

    A chain with no usable result returns a defect; the turn handles it as a failure.

    ok: false
    cause: "chain-exhausted"

Work with models

GuideWhat you'll learn
Defining chainsBuild an ordered chain and connect it to an agent.
Connecting providersInstall adapters and supply credentials and model configuration.
Retry and fallbackFollow classified failures through retries, fallback, and exhaustion.
Tool capabilitiesKeep tool use available as the chain changes tiers.
Limits and usageUnderstand declared limits, token accounting, and cost estimates.
Custom adaptersImplement the model interface, including streaming, and run deterministic local tiers.

Next: Defining chains.