Usage limits

defineUsageLimitProvider — surface your agent's plan or API usage in the app.

The toolbar's usage-limits popover is fed by plugin providers. A provider polls a source — typically your agent CLI's usage command — and reports structured limits.

import {
  definePlugin,
  defineUsageLimitProvider,
  runProviderCommand,
  CLI_MISSING_STATUS,
} from "@pragma-sh/plugin";

usageLimits: [
  defineUsageLimitProvider({
    id: "my-agent",
    title: "My Agent",
    iconPath: "./assets/agent.svg",
    dashboardUrl: "https://my-agent.dev/dashboard",
    primaryLimitId: "messages",
    refreshIntervalMs: 30_000, // minimum 15s; backoff on failure up to 15min
    load: async (ctx) => {
      const outcome = await runProviderCommand(ctx, ["my-agent", "usage", "--json"]);
      if (outcome.kind === "missing") {
        return {
          status: "unavailable",
          reason: "not-configured",
          message: "Install the my-agent CLI to see usage.",
        };
      }
      if (outcome.kind === "failed") {
        return { status: "unavailable", reason: "error", message: outcome.stderr };
      }
      const data = JSON.parse(outcome.stdout);
      return {
        status: "ready",
        observedAt: Date.now(),
        summary: data.messages,           // the collapsed-row limit
        limits: [data.messages, data.tokens],
      };
    },
  }),
],

Shapes

interface UsageLimit {
  id: string;
  title: string;
  used: number; // percent 0–100
  limit: number | null; // null = unlimited → "Unlimited"
  resetsInMs?: number; // drives the "Resets in" countdown
}

type UsageLimitsResult =
  | { status: "ready"; observedAt: number; summary?: UsageLimit; limits: UsageLimit[] }
  | {
      status: "unavailable";
      reason: "not-configured" | "authentication-required" | "unsupported" | "error";
      message: string;
    };

runProviderCommand executes a command and classifies the result: { kind: "missing" } when the binary is absent (exit status CLI_MISSING_STATUS = 20), { kind: "failed"; stderr }, or { kind: "ok"; stdout }. Report unavailable states honestly — the popover renders them instead of fake numbers.

The app renders the summary when collapsed, every limit when expanded, colours the progress bar (warning from 50%, destructive from 75%), and links dashboardUrl.

Not for UI work

A provider is data-only and runs host-side. UI goes in ui contributions; this API exists so the same popover covers every agent, including the ones you ship.

On this page