Model Router
App prompts converging on a router that picks a model for each one, then fanning out to a card of models, each with what it is picked for, its prompts, its share of traffic, and its average response time, counting up as pulses arrive.
Installation
The source for model-router comes with a Cortexcn Pro license, along with every other chart and the website templates. Pick a license on the pricing page.
Already have a license? Open the code
Usage
import { ModelRouter } from "@/components/model-router";<ModelRouter
title="Traffic by model"
models={[
{ name: "Brisk 3", role: "Short answers", prompts: 18420, latencyMs: 340 },
{ name: "Sage 2", role: "Reasoning", prompts: 6910, latencyMs: 1840 },
{ name: "Prism", role: "Images and files", prompts: 2270, latencyMs: 920 },
]}
/>Each model gets a row: its name, what the router picks it for, the prompts sent to it, and its average response time, with a bar showing its share of all prompts. Use it on the page for an AI product that routes between models, or to explain cost and speed tradeoffs in a model gateway.
Examples
Support routing
Four models for a support desk, with the source relabeled.
Static
With animated={false}, nothing moves and the numbers stay as given.
Behavior
- While the flow is on screen, pulses run from the left into the router, then on to each model. The prompt counts count up from zero, then each model adds its
perPulseevery time a pulse reaches it, and the shares follow the new counts. - The count under the source label goes up as pulses reach the router.
- With reduced motion enabled, or off screen, nothing moves and every number shows its given value.
- The whole flow is one SVG that scales to its container. It lays out at
minWidthor wider (560px by default); in a narrower container it scrolls sideways and takes keyboard focus. - Screen readers hear one summary: each model, what it is for, its prompts, its share, and its average response time.
- The model names are made up, and the caption in the corner says the numbers are illustrative. Use your own models and numbers.
Props
ModelRouter
| Prop | Type | Default | Description |
|---|---|---|---|
models | ModelRouterModel[] | Three sample models | The models the router picks between |
title | string | "Traffic by model" | The card's title |
routerName | string | "Router" | The name in the middle node |
routerCaption | string | "Picks a model for every prompt" | A line under the middle node |
sourceLabel | string | "App prompts" | The label over the incoming lines |
promptsLabel | string | "prompts today" | The words after the count under the source label |
apiLabel | string | "Routing rules" | The label on the lines into the card |
note | string | "Hard prompts get the reasoning model." | A note at the foot of the card |
caption | string | "Illustrative numbers" | A small label in the bottom-left corner |
locale | string | "en-US" | The locale numbers are written in |
lines | number | 22 | How many lines of traffic come in from the left |
segments | number | 24 | How many segments each share bar has |
accent | string | "var(--foreground)" | Color of the pulses, markers, and share segments |
animated | boolean | true | Run the pulses and count up while on screen |
minWidth | number | 560 | Narrowest layout width in pixels; below it, scroll |
ariaLabel | string | "Model router" | Names the flow for screen readers |
className | string | - | Extra classes on the frame |
ModelRouterModel
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | - | The model's name |
role | string | - | What it is picked for, such as "Reasoning" |
prompts | number | - | Prompts routed to it so far |
latencyMs | number | - | Its average response time, in milliseconds |
perPulse | number | 2 | Prompts added each time a pulse reaches it while live |