npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aetheros/models

v0.2.0

Published

Model catalog, cheap/strong routing and safe fallbacks across AI providers for AetherOS and Aevron.

Readme

@aetheros/models

One place to choose models across providers: a model catalog with prices and context sizes, cheap/strong routing, and safe fallbacks when a model is busy or down.

aether models                         # list models, prices, context sizes, and which providers have keys
aether models pick --tier cheap       # best ready model for a tier, then fallbacks
aether models pick --tier strong --needs tools --input 20000 --output 2000 --max-cost 0.10
aether models init                    # starter .aether/models.json (never overwrites)
aether models prices update           # fetch the public price list now (the workspace does it once a week)
aether models prices                  # what it fills in, and where it disagrees with checked prices

Catalog

  • Built in:
    • Claude: every Claude model still served, with published prices (dollars per million tokens), context size and output limit, dated with when the prices were checked.
    • Google, xAI and Mistral: current models with ids, prices (standard tier), context sizes and output limits copied from each provider's own pages (ai.google.dev, docs.x.ai, docs.mistral.ai), dated pricesAsOf 2026-11-01. Notes say where a price changes for long prompts or on a set date. xAI and Mistral don't publish output limits, so those are left out.
    • OpenAI: current models (GPT-6 Astra, GPT-6.1 Sol and Terra, GPT-6 Luna and Sol, GPT-5.6, GPT-5.5, GPT-5.4) with ids, prices (standard tier), cached-input prices (price.cachedInput), context sizes and output limits copied from developers.openai.com, dated pricesAsOf 2026-11-01. Prices are for prompts up to 272K tokens; notes give the long-prompt rate. Cost estimates count cached input (usage.cachedInputTokens, part of inputTokens) at price.cachedInput and the rest at the input price.
    • DeepSeek, Groq, Together, Z.ai: ids, context sizes and prices (with cached-input prices where published) copied from each provider's own pages, dated pricesAsOf 2026-11-04. DeepSeek's price is its peak-hour rate (off-peak is half). Moonshot Kimi (kimi-k3.1-pro, kimi-k3) and Perplexity (sonar) have ids and context but no price: it could not be verified on their own pages, so cost is unknown until you set it in .aether/models.json. OpenRouter and Azure OpenAI have no built-in rows (any model or deployment; add your own).
  • Your project: .aether/models.json adds other providers' models, corrects prices, or hides a model:
    {"schemaVersion": 1, "pricesAsOf": "2026-11-01", "models": [
      {"provider": "google", "id": "<model id>", "tier": "balanced", "contextTokens": 1000000, "price": {"input": 0, "output": 0}},
      {"provider": "local", "id": "llama3.1", "tier": "cheap", "price": {"input": 0, "output": 0}, "structuredOutput": false},
      {"provider": "claude", "id": "claude-fable-5-1", "disabled": true}
    ]}
    Providers: claude, openai, azure-openai, google, xai, mistral, deepseek, groq, openrouter, together, moonshot, zai, perplexity, local, plus your own named custom providers (below). Tiers: cheap, balanced, strong. Within a tier, list order is your preference. A missing price means "unknown": such models are skipped when you set a cost limit. Capabilities (tools, streaming, structuredOutput, vision) default to what the provider's adapter can do; set one to false to switch it off for a model. vision means the model reads images. Every adapter sends images now (Claude, OpenAI, Google, OpenAI-compatible). It is on by default for Claude, OpenAI, Google and xAI (every built-in model there takes image input), on for the built-in Mistral models that read images (Large 4, Ministral 3), and off for local models: set "vision": true on a local model that reads images (for example a LLaVA build).

Prices change. Take them from each provider's price page and keep pricesAsOf current.

Dated prices

Some prices are known to change on a set day. An entry (built in or in .aether/models.json) can say so:

  • "priceChange": {"on": "2026-12-01", "price": {"input": 4, "output": 20}}: an announced new price. From that day (UTC) the catalog uses it on its own, so cost estimates and daily budgets follow. After the day, aether models asks for the entry to be confirmed on the provider's page.
  • "priceCheck": {"by": "2026-11-22", "reason": "Promotional price"}: a price that may change without an announced new one (a promotion). The price stays; from that day aether models asks for it to be checked.

aether models and aether models prices list checks that are due and those coming in the next 31 days. Built in today: Gemini 4 Argon $2/$10 → $4/$20 on 1 Dec 2026; Gemini 3.8 and 3.6 Flash $0.75/$3.75 → $1.50/$7.50 on 1 Jan 2027; GPT-5.6 Sol's promotional $4/$20 checked from 22 Nov 2026. From code: priceChecks(catalog, {today, within}), loadCatalog(root, {today}).

Prices fetched automatically

No provider offers a price API, and scraping each provider's page breaks whenever a page changes. So prices are fetched from one maintained, machine-readable list instead: LiteLLM's model price list (MIT licence, updated by many contributors and used by a lot of tools).

  • It only fills gaps. A model whose price, context size or output limit is unknown gets the fetched value. In aether models a fetched price is marked *, with pricesAsOf set to the day it was fetched. Prices checked on a provider's own page (built in) or set in .aether/models.json are never replaced.
  • Disagreements are shown, not applied. aether models prices lists what was filled in and where the list disagrees with a checked price, so a person can check the provider's page.
  • Output limits: an output limit as large as the context is the list's placeholder, not a published limit, so it is skipped.
  • When: aether models prices update fetches now. aether workspace refreshes in the background when the saved list is over a week old, so budgets can count models without a built-in price. --no-price-refresh or AETHER_PRICES=off turns that off. A failed fetch keeps the previous list.
  • Where: .aether/local/models-prices.json, per machine and git-ignored. loadCatalog(root, {fetched: null}) ignores it.
  • From code: refreshPrices(root), fetchPrices(), applyFetchedPrices(catalog, prices).

Routing

chooseModels(catalog, {tier, providers, needs, inputTokens, outputTokens, maxCostUsd}) returns models best first: the asked tier, then the nearest tiers. It leaves out models that lack a needed feature (tools, streaming, structured output), whose context is too small, or that cost more than the limit. availableProviders() lists providers whose keys are set.

Fallbacks

withFallbacks([{id, provider}, ...]) is one provider made of several. When a model fails with a "try elsewhere" error (rate limit, overload, server error, timeout, network) the next one answers. It never falls back:

  • after a tool was called (the call may already have changed something),
  • after reply text was shown to the person,
  • after the request was cancelled,
  • on a refusal (that is an answer, not a failure),
  • to a model that can't do what the request needs (for example tools).

It plugs into Aevron like any provider. Aevron itself still never retries or switches providers on its own.

Providers

createProvider(provider, model) builds a client from environment keys:

| Provider | Package | Keys | |---|---|---| | claude | @aetheros/provider-claude | ANTHROPIC_API_KEY (or an ant auth login profile) | | openai | @aetheros/provider-openai | OPENAI_API_KEY | | google | @aetheros/provider-google | GEMINI_API_KEY (or GOOGLE_API_KEY) | | azure-openai | @aetheros/provider-openai | AZURE_OPENAI_API_KEY, AZURE_OPENAI_ENDPOINT (https://<resource>.openai.azure.com), optional AZURE_OPENAI_API_VERSION; the model is the deployment name (or AZURE_OPENAI_DEPLOYMENT) | | xai, mistral | @aetheros/provider-openai-compatible | XAI_API_KEY, MISTRAL_API_KEY | | deepseek, groq, openrouter, together, moonshot, zai, perplexity | @aetheros/provider-openai-compatible | DEEPSEEK_API_KEY, GROQ_API_KEY, OPENROUTER_API_KEY, TOGETHER_API_KEY, MOONSHOT_API_KEY, ZAI_API_KEY, PERPLEXITY_API_KEY (addresses and default models in that package's README) | | local | @aetheros/provider-openai-compatible | LOCAL_MODEL, optional LOCAL_MODEL_URL (default Ollama at http://127.0.0.1:11434/v1) |

openai also reads OPENAI_BASE_URL (a company proxy or other Responses-compatible address; https only, plain http only for this machine).

Every adapter offers structured output and all of them stream. Every adapter except Perplexity's offers tools, so an agent with tools can fall back to any other provider. For a local model without function calling, set "tools": false on its catalog entry.

Named custom providers (any OpenAI-compatible endpoint, no code): add a providers list to .aether/models.json, then models for it:

{"schemaVersion": 1,
 "providers": [{"id": "acme-llm", "label": "Acme LLM", "baseUrl": "https://llm.acme.example/v1", "keyVar": "ACME_LLM_KEY", "model": "acme-large", "effort": true}],
 "models": [{"provider": "acme-llm", "id": "acme-large", "tier": "strong", "price": {"input": 1, "output": 4}}]}

Fields: id (lowercase, not a built-in name), label, baseUrl (https; http only for this machine; no credentials or query), keyVar (the name of the environment variable with the key, never the key; optional only on this machine), optional model / modelVar, path (default /chat/completions), tools, structuredOutput, vision, documents (PDF file parts), effort (sends reasoning_effort). createProvider('acme-llm', model, {root}) builds it; readCustomProviders(root) lists them; availableProviders(env, {customProviders}) includes the ones whose key is set.