Recipes

OpenRouter

Cloud path for fx.ask — provider openrouter auto-resolves base URL; router aliases pick free, auto, coding, fusion, and latest models.

OpenRouter is the simplest way to call a real model from OKE: no Docker, no Python, no local weights. Set provider: "openrouter" and an API key — baseUrl resolves from the verified registry.

The one rule

Use a dedicated OpenRouter API key on the binding (apiKey), prefer the stable openrouter/free router alias for zero-cost smoke tests, and keep other providers on their own ai.model + apiKey so keys never collide.

Quick start

Declare the cloud binding

import { ai } from "okengine";

export const smart = ai.model("smart", {
  provider: "openrouter",
  model: "openrouter/free",
  apiKey: process.env.OPENROUTER_API_KEY,
});

export const triage = smart.prompt("triage");

baseUrl becomes https://openrouter.ai/api/v1 automatically. Pass an explicit baseUrl only to point at a proxy or mirror.

Ask from a flow

src/flows/main/ask.ts
import { on, flow, http } from "okengine";

export const ask = on(
  http.post(),
  flow({ asks: ["triage"] }, async (fx, input) => {
    return await fx.ask("triage", input);
  }),
);

Optional setup via CLI

create-oke Recommended / Customize / Reuse and oke ai setup --provider openrouter pick openrouter/free, write OPENROUTER_API_KEY to .env.local + vault.secret (no dev: stub). Missing key → oke dev asks again (openrouter.ai).

Router aliases

OpenRouter routers are model slugs that pick (or compose) upstream models for you. Pass the slug as model on ai.model — same as any other OpenRouter id.

SlugWhat it doesCost
openrouter/freeRandom free model that supports your request featuresFree
openrouter/autoMarket-based pick by task type + cost tierSelected model rate
openrouter/pareto-codeStrong coding model by min_coding_scoreSelected model rate
openrouter/fusionMulti-model panel + analyst deliberation~4–5× one completion
openrouter/bodybuilderNL → parallel request bodies (you run them)Builder free; executions billed
~author/family-latestNewest concrete version in a familyTarget model rate

Consequence: the response model field is the concrete upstream that answered — log it for auditability.

Router plugin knobs (cost_tier, allowed_models, min_coding_score, fusion panel) live on OpenRouter’s request plugins / account Routing defaults; OKE passes the model slug through the openai-compatible driver.

Free Models Router — openrouter/free

Ideal for smoke tests, demos, and learning. The router filters free models for capabilities your request needs (vision, tools, structured outputs), then picks one at random.

export const smoke = ai.model("smoke", {
  provider: "openrouter",
  model: "openrouter/free",
  apiKey: process.env.OPENROUTER_API_KEY,
});
DetailBehavior
SelectionRandom among eligible free models
Pin a free modelUse author/model:free instead of the router
LimitsLower rate limits; availability and latency vary

Official guide: Free Models Router.

Auto Router — openrouter/auto

Classifies the prompt (~30 task types), ranks by community spend share over a trailing 7-day window, then applies your cost band and fallbacks.

export const smart = ai.model("smart", {
  provider: "openrouter",
  model: "openrouter/auto",
  apiKey: process.env.OPENROUTER_API_KEY,
});
DetailBehavior
Early trackopenrouter/auto-beta (plugin id auto-beta-router)
Cost bandslow · medium · high · xhigh · max (default ≈ low)
Allow / denyWildcard patterns via allowed_models / excluded_models
SessionsPrefers the prior model while it stays a top candidate
PricingNo router fee — pay the selected model

Official guide: Auto Router.

Pareto Router — openrouter/pareto-code

Coding-only. You set a minimum coding score (01); the router maps it to a tier and picks the cheapest (or fastest with :nitro) eligible model.

export const coder = ai.model("coder", {
  provider: "openrouter",
  model: "openrouter/pareto-code",
  apiKey: process.env.OPENROUTER_API_KEY,
});
min_coding_scoreTier
>= 0.66 (default if omitted)high — top of AA coding field
>= 0.33, < 0.66medium
< 0.33low

Within the tier: cheapest available (+ same-tier fallbacks on provider errors). Use session_id for multi-turn stickiness. Official guide: Pareto Router.

Fusion Router — openrouter/fusion

A panel of models answers in parallel; an analyst returns structured consensus / contradictions / gaps; your outer model writes the final answer.

export const deliberate = ai.model("deliberate", {
  provider: "openrouter",
  model: "openrouter/fusion",
  apiKey: process.env.OPENROUTER_API_KEY,
});
DetailBehavior
Fast presetopenrouter/fusion-flash (general-fast panel)
Default panelQuality: Claude Opus / GPT / Gemini latest aliases
CostN panel + 1 analyst + outer — expect ~4–5× with 3 models
Force fusionOpenRouter tool_choice: "required" (model decides by default)

Official guide: Fusion Router.

Body Builder — openrouter/bodybuilder

Describe a multi-model job in natural language. The response is JSON { requests: [...] } — generate is free; you execute each body yourself. Useful for A/B checks, not a single fx.ask answer.

export const builder = ai.model("builder", {
  provider: "openrouter",
  model: "openrouter/bodybuilder",
  apiKey: process.env.OPENROUTER_API_KEY,
});

Official guide: Body Builder.

Latest resolution — ~author/family-latest

Stable family alias that always retargets to the newest visible model in that family. Response model reports the concrete slug.

export const opus = ai.model("opus", {
  provider: "openrouter",
  model: "~anthropic/claude-opus-latest",
  apiKey: process.env.OPENROUTER_API_KEY,
});
DetailBehavior
ReproducibilityPin a concrete slug (e.g. anthropic/claude-opus-4.8)
Reasoning paramsUnsupported none / disabled may remap on ~latest only
PricingListed as the current target’s rates

Official guide: Latest Model Resolution.

Multi-provider projects

export const viaOr = ai.model("via-or", {
  provider: "openrouter",
  model: "openrouter/free",
  apiKey: process.env.OPENROUTER_API_KEY,
});

export const viaGroq = ai.model("via-groq", {
  provider: "groq",
  model: "llama-3.1-8b-instant",
  apiKey: process.env.GROQ_API_KEY,
});

Each binding keeps its own apiKey and auto-resolved baseUrl. No shared process-wide token.

Troubleshooting

Learn more

  • Models — verified providers, limited compatibility, BYO /v1
  • AI — prompts and fx.ask
  • OpenRouter routers — Auto, Free, Pareto, Fusion, Body Builder, Latest

Any OpenAI-compatible /v1 endpoint works via custom baseUrl / OKE_AI_URL on an openai-compatible binding — see Models.

Next

On this page