Skip to content
design
Components

LLM status

Which language model answers, how each provider is doing, and the tokens, cost and budget behind it, as a chip or a panel.

On this page

AI models

In useClaude Sonnet 4.6AnthropicWorking

This session · 21k tokens (18.6k in / 2.4k out) · 7 requests · $0.21 · 0.8% of the budget

This week

Tokens
4.2M
Cost
$16.00 · 64% of the budget

Tokens by day

  1. Mon 5 Oct: 540k tokens, $2.10 · 8.4% of the budget
  2. Tue 6 Oct: 720k tokens, $2.80 · 11% of the budget
  3. Wed 7 Oct: 410k tokens, $1.50 · 6% of the budget
  4. Thu 8 Oct: 880k tokens, $3.40 · 14% of the budget
  5. Fri 9 Oct: 650k tokens, $2.50 · 10% of the budget
  6. Sat 10 Oct: 560k tokens, $2.10 · 8.4% of the budget
  7. Sun 11 Oct, today: 440k tokens, $1.60 · 6.4% of the budget

Tokens by model

  1. Claude Sonnet 4.6Anthropic2.9M$15.20 · 61% of the budget
  2. Qwen3.5 4Bllama.cppLocal1.1M
  3. Gemini 2.5 FlashGoogle200k$0.80 · 3.2% of the budget

Budget

Remaining
$9.00
Renews
12 October 2026, 00:00 UTC
Emergency reserve
$4.60 left

When it runs out, cloud answers stop until it renews and Bosun answers with the models on board. Emergency requests, such as man overboard or mayday, still reach the cloud through the emergency reserve.

Providers

  • AnthropicClaude Sonnet 4.6Working2.8 s
  • OpenAIGPT-5.4Working2.1 s
  • GoogleGemini 2.5 FlashDegraded4.6 sRecent errors or slow replies
  • llama.cppQwen3.5 4BLocalWorking900 ms
A week on Claude Sonnet 4.6 through Anthropic, with a local Qwen model on board: the chip in the status strip shows 64% of the weekly budget used, and the panel holds the session, the week by day and by model, the budget and Google's degraded provider.
Code
import { LlmStatus } from "@bosunkit/components/llm-status";
import type { ReactElement } from "react";

export const description: string =
  "A week on Claude Sonnet 4.6 through Anthropic, with a local Qwen model on board: the chip in the status strip, " +
  "64% of the weekly budget used and Google's provider degraded, and the panel with the session on one line, the " +
  "days under their bars, each cost against the budget, the budget with the session's share and the emergency " +
  "reserve, and each provider's health.";

export default function Showcase(): ReactElement {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "var(--space-lg)", width: "100%" }}>
      <div
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "flex-end",
          gap: "var(--space-sm)",
          padding: "var(--space-xs) var(--space-sm)",
          borderBottom: "1px solid var(--border)",
        }}
      >
        <LlmStatus
          provider={{ name: "Anthropic", model: "Claude Sonnet 4.6", health: "ok", latencyMs: 2800 }}
          budget={{ limit: 25, spent: 16, resetsAt: Date.UTC(2026, 9, 12) }}
        />
      </div>
      <div style={{ maxWidth: "28em" }}>
        <LlmStatus
          variant="panel"
          provider={{ name: "Anthropic", model: "Claude Sonnet 4.6", health: "ok", latencyMs: 2800 }}
          session={{ inputTokens: 18_600, outputTokens: 2_400, requests: 7, cost: 0.21 }}
          usage={{ tokens: 4_200_000 }}
          budget={{
            limit: 25,
            spent: 16,
            resetsAt: Date.UTC(2026, 9, 12),
            emergency: { limit: 5, spent: 0.4 },
          }}
          byDay={[
            { date: Date.UTC(2026, 9, 5), tokens: 540_000, cost: 2.1 },
            { date: Date.UTC(2026, 9, 6), tokens: 720_000, cost: 2.8 },
            { date: Date.UTC(2026, 9, 7), tokens: 410_000, cost: 1.5 },
            { date: Date.UTC(2026, 9, 8), tokens: 880_000, cost: 3.4 },
            { date: Date.UTC(2026, 9, 9), tokens: 650_000, cost: 2.5 },
            { date: Date.UTC(2026, 9, 10), tokens: 560_000, cost: 2.1 },
            { date: Date.UTC(2026, 9, 11), tokens: 440_000, cost: 1.6, today: true },
          ]}
          byModel={[
            { model: "Claude Sonnet 4.6", provider: "Anthropic", tokens: 2_900_000, cost: 15.2 },
            { model: "Qwen3.5 4B", provider: "llama.cpp", local: true, tokens: 1_100_000 },
            { model: "Gemini 2.5 Flash", provider: "Google", tokens: 200_000, cost: 0.8 },
          ]}
          providers={[
            { name: "Anthropic", model: "Claude Sonnet 4.6", health: "ok", latencyMs: 2800 },
            { name: "OpenAI", model: "GPT-5.4", health: "ok", latencyMs: 2100 },
            { name: "Google", model: "Gemini 2.5 Flash", health: "degraded", latencyMs: 4600 },
            { name: "llama.cpp", model: "Qwen3.5 4B", local: true, health: "ok", latencyMs: 900 },
          ]}
        />
      </div>
    </div>
  );
}

An LLM status says which language model answers the crew and what it has cost. The compact form is a chip for the status strip: a health shape, the provider in use, or Local when the model runs on the vessel, a word when the provider is not working, and a hairline along its foot with the share of the budget left. A press opens the detail in a popover. The panel form is the same detail in a card.

The detail opens with two lines: the model in use, and this session's tokens, requests and cost, with the split between tokens in and out written small when it is known. Then come up to five sections, each drawn only when its data is given: the week's tokens and cost, tokens per day for the last seven days as bars with each day's weekday under its bar and the current day marked, tokens per model ranked by share with on-vessel models marked Local, the budget, and each provider's health and smoothed response time. A provider's health is a shape and a word: a filled circle for working, a triangle for degraded, a square for paused after repeated errors, a ring for offline.

Every cost is written with its share of the budget it draws from ("$0.21 · 0.8% of the budget"), and alone when no budget is set. The budget's bar shows what is spent, from the start, and what is left up to the limit's mark; the session's cost, and the week's within a monthly budget, are the stronger parts of the spent fill. The emergency reserve has its own thinner bar under it. Each bar is named in full for a screen reader ("Tue 6 Oct: 720k tokens, $2.80 · 11% of the budget"), and a pointer or the arrow keys over the bars read each day out.

Token counts are compact (12.4k, 1.3M) and every figure is in tabular mono. Weekdays and months are written in the crew's language; a range longer than a week labels its bars with dates, every few days. Money is written in the crew's language in the currency the currency prop names, US dollars by default, the currency bosund accounts in. The renewal is printed with its time reference: UTC by default, or the device's time zone with zone="local" and the reference the caller passes in timeReference.

01A budget is not an alarmThe budget bar turns amber past its warning share and stays amber when the budget is spent. It never takes an alert color: the alert board carries the budget lookout's own item.
02Missing is left outA section with no data is not drawn, so an unknown figure never reads as zero. No budget at all is said in words.
03Say what running out doesThe budget section says what bosund does when the money is gone: the cloud stops for normal requests, the models on board answer, and emergency requests use their own reserve.

Examples

Chip

The chip in each health. The status strip shows the chip; the detail opens on a press, and Escape or a press outside closes it. Pass open with onOpenChange to hold the state yourself.

The chip in each health: working, degraded, paused after repeated errors, and offline, each with its own shape; the last answers on board, so it reads Local. A press opens the detail.
Code
import { LlmStatus } from "@bosunkit/components/llm-status";
import type { ReactElement } from "react";

export const description: string =
  "The chip in each health: working, degraded, paused after repeated errors, and offline, each with its own shape; " +
  "the last answers on board, so it reads Local. A press opens the detail.";

export default function Chip(): ReactElement {
  const budget: { limit: number; spent: number; resetsAt: number } = {
    limit: 25,
    spent: 16,
    resetsAt: Date.UTC(2026, 9, 12),
  };
  return (
    <div style={{ display: "flex", flexWrap: "wrap", gap: "var(--space-sm)" }}>
      <LlmStatus provider={{ name: "Anthropic", model: "Claude Sonnet 4.6", health: "ok" }} budget={budget} />
      <LlmStatus provider={{ name: "Google", model: "Gemini 2.5 Flash", health: "degraded" }} budget={budget} />
      <LlmStatus provider={{ name: "OpenAI", model: "GPT-5.4", health: "circuit-open" }} budget={budget} />
      <LlmStatus provider={{ name: "llama.cpp", model: "Qwen3.5 4B", local: true, health: "ok" }} budget={budget} />
    </div>
  );
}

Healthy

Every provider answers and a fifth of the weekly budget is used.

AI models

In useClaude Sonnet 4.6AnthropicWorking

This session · 7.1k tokens (6.2k in / 900 out) · 3 requests · $0.03 · 0.1% of the budget

This week

Tokens
1.4M
Cost
$5.40 · 22% of the budget

Budget

Remaining
$19.60
Renews
12 October 2026, 00:00 UTC

When it runs out, cloud answers stop until it renews and Bosun answers with the models on board. Emergency requests, such as man overboard or mayday, still reach the cloud through the emergency reserve.

Providers

  • AnthropicClaude Sonnet 4.6Working2.6 s
  • OpenAIGPT-5.4Working1.9 s
  • llama.cppQwen3.5 4BLocalWorking850 ms
Early in the week: every provider answers, a fifth of the budget is used and the bar is the accent color.
Code
import { LlmStatus } from "@bosunkit/components/llm-status";
import type { ReactElement } from "react";

export const description: string =
  "Early in the week: every provider answers, a fifth of the budget is used and the bar is the accent color.";

export default function Healthy(): ReactElement {
  return (
    <div style={{ maxWidth: "28em" }}>
      <LlmStatus
        variant="panel"
        provider={{ name: "Anthropic", model: "Claude Sonnet 4.6", health: "ok", latencyMs: 2600 }}
        session={{ inputTokens: 6_200, outputTokens: 900, requests: 3, cost: 0.03 }}
        usage={{ tokens: 1_380_000 }}
        budget={{ limit: 25, spent: 5.4, resetsAt: Date.UTC(2026, 9, 12) }}
        providers={[
          { name: "Anthropic", model: "Claude Sonnet 4.6", health: "ok", latencyMs: 2600 },
          { name: "OpenAI", model: "GPT-5.4", health: "ok", latencyMs: 1900 },
          { name: "llama.cpp", model: "Qwen3.5 4B", local: true, health: "ok", latencyMs: 850 },
        ]}
      />
    </div>
  );
}

Budget nearly spent

Past warnAtPercent, 80 by default as bosund's WarnAtPercent, the chip's hairline and the week's bar turn amber. dailyLimitTokens draws a limit line over the days.

AI models

In useClaude Sonnet 4.6AnthropicWorking

This session · 31k tokens · 12 requests · $0.94 · 3.8% of the budget

This week

Tokens
5.7M
Cost
$22.00 · 88% of the budget

Tokens by day

  1. Sun 4 Oct: 610k tokens
  2. Mon 5 Oct: 930k tokens
  3. Tue 6 Oct: 1.1M tokens
  4. Wed 7 Oct: 760k tokens
  5. Thu 8 Oct: 990k tokens
  6. Fri 9 Oct: 840k tokens
  7. Sat 10 Oct, today: 450k tokens

Budget

Remaining
$3.00
Renews
12 October 2026, 00:00 UTC

When it runs out, cloud answers stop until it renews and Bosun answers with the models on board. Emergency requests, such as man overboard or mayday, still reach the cloud through the emergency reserve.

Saturday, with 88% of the budget used: the chip's bar and the week's bar turn amber past the 80% warning share. Nothing takes an alert color; bosund's own budget lookout raises the board item.
Code
import { LlmStatus } from "@bosunkit/components/llm-status";
import type { ReactElement } from "react";

export const description: string =
  "Saturday, with 88% of the budget used: the chip's bar and the week's bar turn amber past the 80% warning share. " +
  "Nothing takes an alert color; bosund's own budget lookout raises the board item.";

export default function NearlySpent(): ReactElement {
  const budget: { limit: number; spent: number; resetsAt: number } = {
    limit: 25,
    spent: 22,
    resetsAt: Date.UTC(2026, 9, 12),
  };
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "var(--space-md)", maxWidth: "28em" }}>
      <LlmStatus provider={{ name: "Anthropic", model: "Claude Sonnet 4.6", health: "ok" }} budget={budget} />
      <LlmStatus
        variant="panel"
        provider={{ name: "Anthropic", model: "Claude Sonnet 4.6", health: "ok", latencyMs: 2900 }}
        session={{ tokens: 31_000, requests: 12, cost: 0.94 }}
        usage={{ tokens: 5_700_000 }}
        budget={budget}
        byDay={[
          { date: Date.UTC(2026, 9, 4), tokens: 610_000 },
          { date: Date.UTC(2026, 9, 5), tokens: 930_000 },
          { date: Date.UTC(2026, 9, 6), tokens: 1_120_000 },
          { date: Date.UTC(2026, 9, 7), tokens: 760_000 },
          { date: Date.UTC(2026, 9, 8), tokens: 990_000 },
          { date: Date.UTC(2026, 9, 9), tokens: 840_000 },
          { date: Date.UTC(2026, 9, 10), tokens: 450_000, today: true },
        ]}
        dailyLimitTokens={1_000_000}
      />
    </div>
  );
}

Budget spent

At the limit bosund stops sending normal requests to the cloud and the local model answers. The bar runs past the limit mark when reconciled spend overshoots it.

AI models

In useQwen3.5 4Bllama.cppLocalWorking

This week

Tokens
6.1M
Cost
$25.40 · 102% of the budget

Tokens by model

  1. Claude Sonnet 4.6Anthropic4.3M
  2. Qwen3.5 4Bllama.cppLocal1.5M
  3. GPT-5.4OpenAI300k

Budget

Remaining
$0.00
Renews
12 October 2026, 00:00 UTC

Budget used up. Cloud answers stop until 12 October 2026, 00:00 UTC; Bosun is answering with the models on board.

The budget is used up: bosund stops sending normal requests to the cloud until Monday, and the local Qwen model answers, so the chip reads Local and the budget says what happens next.
Code
import { LlmStatus } from "@bosunkit/components/llm-status";
import type { ReactElement } from "react";

export const description: string =
  "The budget is used up: bosund stops sending normal requests to the cloud until Monday, and the local Qwen model " +
  "answers, so the chip reads Local and the budget says what happens next.";

export default function Spent(): ReactElement {
  const budget: { limit: number; spent: number; resetsAt: number } = {
    limit: 25,
    spent: 25.4,
    resetsAt: Date.UTC(2026, 9, 12),
  };
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "var(--space-md)", maxWidth: "28em" }}>
      <LlmStatus provider={{ name: "llama.cpp", model: "Qwen3.5 4B", local: true, health: "ok" }} budget={budget} />
      <LlmStatus
        variant="panel"
        provider={{ name: "llama.cpp", model: "Qwen3.5 4B", local: true, health: "ok", latencyMs: 940 }}
        usage={{ tokens: 6_100_000 }}
        budget={budget}
        byModel={[
          { model: "Claude Sonnet 4.6", provider: "Anthropic", tokens: 4_300_000 },
          { model: "Qwen3.5 4B", provider: "llama.cpp", local: true, tokens: 1_500_000 },
          { model: "GPT-5.4", provider: "OpenAI", tokens: 300_000 },
        ]}
      />
    </div>
  );
}

Offline, local only

With no connection the cloud providers are offline and the model on board answers. A local session has no cost to show, so it shows none.

AI models

In useQwen3.5 4Bllama.cppLocalWorking

This session · 4.7k tokens · 5 requests

Providers

  • AnthropicClaude Sonnet 4.6OfflineCan't be reached from the vessel
  • OpenAIGPT-5.4OfflineCan't be reached from the vessel
  • llama.cppQwen3.5 4BLocalWorking910 ms
Mid-Atlantic with no connection: every cloud provider is offline, the local model answers, and the session's tokens cost nothing, so it shows no cost.
Code
import { LlmStatus } from "@bosunkit/components/llm-status";
import type { ReactElement } from "react";

export const description: string =
  "Mid-Atlantic with no connection: every cloud provider is offline, the local model answers, and the session's " +
  "tokens cost nothing, so it shows no cost.";

export default function Offline(): ReactElement {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "var(--space-md)", maxWidth: "28em" }}>
      <LlmStatus provider={{ name: "llama.cpp", model: "Qwen3.5 4B", local: true, health: "ok" }} />
      <LlmStatus
        variant="panel"
        provider={{ name: "llama.cpp", model: "Qwen3.5 4B", local: true, health: "ok", latencyMs: 910 }}
        session={{ tokens: 4_720, requests: 5 }}
        providers={[
          { name: "Anthropic", model: "Claude Sonnet 4.6", health: "offline" },
          { name: "OpenAI", model: "GPT-5.4", health: "offline" },
          { name: "llama.cpp", model: "Qwen3.5 4B", local: true, health: "ok", latencyMs: 910 },
        ]}
      />
    </div>
  );
}

No budget configured

budget={null} is bosund in manual mode, on the vessel's own API keys with no compute period: spend is not limited, and the panel says so. Leave budget unset to leave the section out.

AI models

In useGPT-5.4OpenAIWorking

This session · 11.1k tokens (9.8k in / 1.3k out) · 4 requests · $0.06

Budget

No budget is set, so cloud use isn't limited by cost.

A vessel on its own API keys, with no fleet grant: bosund has no compute period, so no budget is set, the chip draws no bar and the session's cost is written without a share of a budget.
Code
import { LlmStatus } from "@bosunkit/components/llm-status";
import type { ReactElement } from "react";

export const description: string =
  "A vessel on its own API keys, with no fleet grant: bosund has no compute period, so no budget is set, the chip " +
  "draws no bar and the session's cost is written without a share of a budget.";

export default function NoBudget(): ReactElement {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "var(--space-md)", maxWidth: "28em" }}>
      <LlmStatus provider={{ name: "OpenAI", model: "GPT-5.4", health: "ok" }} budget={null} />
      <LlmStatus
        variant="panel"
        provider={{ name: "OpenAI", model: "GPT-5.4", health: "ok", latencyMs: 2200 }}
        session={{ inputTokens: 9_800, outputTokens: 1_300, requests: 4, cost: 0.06 }}
        budget={null}
      />
    </div>
  );
}

Data from bosund

The component fetches nothing; the caller maps bosund's figures onto the props.

Propbosund source
provider, providers[].healthProviderPool.Stats(): Blocked is circuit-open, ConsecutiveErrors above 0 is degraded; a grant degraded to local only makes cloud providers offline
providers[].latencyMsProviderStats.LatencyEWMAMs, the pool's smoothed latency
budget.limit, budget.spentBudgetStats.IncludedMicroUSD and NormalSpentMicroUSD, divided by a million
budget.resetsAtBudgetStats.PeriodEnd, the end of the fleet grant's compute period
budget.emergencyBudgetStats.EmergencyReserveMicroUSD and EmergencySpentMicroUSD, divided by a million
budget={null}BudgetStats.HasPeriod false: manual mode, money unconstrained
warnAtPercentBudgetConfig.WarnAtPercent
session.tokens, session.requestsSessionStats.ConversationTokens and DailyRequests, kept per session but on no endpoint
session.inputTokens, outputTokensNot in bosund: the session's tokens are one combined count
session.cost, byDay[].cost, byModel[].costNot exposed: the model_usage journal holds each call's tokens, which pricing can cost
byDay, byModel, usage.tokensNot exposed: the model_usage journal holds each managed cloud call with its tokens, but no endpoint sums it
dailyLimitTokensNot in bosund: its daily limit counts requests per session, not tokens

Props

PropTypeDefaultDescription
variantLlmStatusVariant | undefined–compact, a chip for a status strip that opens the detail in a popover, or panel, the detail as a card.
providerLlmStatusProvider | null | undefined–The provider answering now; null when none is available, unset to leave the line out of the detail.
providersreadonly LlmStatusProvider[] | undefined–Every configured provider with its health and latency, for the Providers section.
sessionLlmStatusSession | undefined–The current session's tokens, requests and cost.
usageLlmStatusUsage | undefined–The tokens and cost of the budget's period, this week by default.
byDayreadonly LlmStatusDay[] | undefined–Tokens per day, oldest first: the last seven days, drawn as bars with each day under its bar.
dailyLimitTokensnumber | undefined–A token limit per day, drawn as a reference line over the bars. bosund has none today: its per-session daily limit counts requests (MaxRequestsPerDay), not tokens.
byModelreadonly LlmStatusModel[] | undefined–Tokens per model over one window; ranked by share, an on-vessel model marked Local.
budgetLlmStatusBudget | null | undefined–The budget: null when none is set (bosund in manual mode, with no compute period, so spend is unconstrained), unset to leave the budget out.
warnAtPercentnumber | undefined–The share of the budget, in percent, past which its bar turns amber; 80 by default, bosund's WarnAtPercent.
currencystring | undefined–The ISO 4217 code money is written in; USD by default, the currency bosund accounts in.
zoneClockZone | undefined–The clock the renewal time is written on: utc by default, or local, the device's time zone.
timeReferencestring | undefined–The reference printed after the renewal time; UTC, or LT on the local clock, when unset.
openboolean | undefined–Whether the compact form's popover is open, for a caller that holds the state; pair it with onOpenChange.
defaultOpenboolean | undefined–Whether the compact form's popover starts open, when the caller does not hold the state.
onOpenChange((open: boolean) => void) | undefined–Called with the open state a press on the chip, Escape or a press outside asks for.
headingLevel2 | 3 | 4 | 5 | undefined–The level of the panel's title; its sections take the next level. 3 by default.
classNamestring | undefined–Classes added to the root.
testIdstring | undefined–Becomes data-testid on the root. The parts are --chip, --chip-health, --chip-bar, --popover, --in-use, --session, --week, --meter, --by-day, --days, --by-model, --budget and --providers.
refRef<HTMLElement> | undefined–The root element: the chip's wrapper, or the panel's card.
Do

AI models

In useGPT-5.4OpenAIWorking

Budget

No budget is set, so cloud use isn't limited by cost.

Pass budget={null} when bosund has no compute period. The panel says spend is not limited by cost.
Don't

AI models

In useGPT-5.4OpenAIWorking

This week

Cost
$0.00

Budget

Remaining
$0.00

Budget used up. Cloud answers stop until it renews; Bosun is answering with the models on board.

Don't pass a zero limit for a budget nobody set. The bar reads as a budget used up, and the crew think the cloud has stopped.
  • Status strip: the strip the compact chip sits in.
  • Popover: the panel the chip opens its detail in.
  • Sparkline: the bars the tokens per day are drawn with.