Beta. Model Hub is not released yet. These pages describe the build in progress.
The API, call by call
What each Hub call does, what it takes and what comes back.
This page is the map. The full reference is generated from the code:
- For reading: the API reference, with every declaration, its signature and its comment.
- For tools and coding agents:
model-hub-api.d.ts, every public declaration in one TypeScript file, andapi.json, the same as data.
Both are also in the repo under docs/api/.
Finding the Hub
| Call | What it does |
|---|---|
getHub(app, wanted) | Returns { hub }, or { hub: null, reason, message } when the Hub is missing or its API is too old. |
onHubReady(app, plugin, wanted, cb) | Runs cb(hub) now if the Hub is loaded, and again each time it loads. |
isCompatible(actual, wanted) | True when an API at actual serves a plugin built for wanted. |
hub.version | The API's version. |
Roles and tiers
| Call | What it does |
|---|---|
registerRoles(pluginId, roles) | Declares your roles. Harmless to repeat. |
roles(pluginId) | Your roles as they resolve now: the tier, the models to try, and every limit that applies. tierMissing is set when a role names a tier that doesn't exist. |
setRole(pluginId, role, override) | Changes one of your roles; null puts it back to your default. Only the owning plugin may. |
openRoleEditor(pluginId) | Opens the Hub's editor for your roles. |
tiers() | Every tier as the user has set it: the seven built-in ones, then the user's own. Each has a stable id, a display name and custom. |
createTier(pluginId, name, policy) | Asks the user to add a tier. The Hub shows a dialog naming your plugin. Resolves to the tier, or null if the user declines. |
deleteTier(pluginId, id) | Asks the user to delete one of their own tiers. Resolves true or false. |
A role definition:
{
name: 'mine.summarize', // namespace.name, lowercase
description: 'Summaries of a note',
tier: 'quick', // a tier's id or name; 'balanced' if left out
ceilingUsd: 0.02, // optional: this role's own limit per call
monthlyBudgetUsd: 2, // optional: this role's own limit per month
allowAnyModel: false, // true for interactive roles where the user picks a model per run
}
A role may also carry its own ordered candidates instead of a tier. Store the id that createTier returns; names keep working across renames.
Calls
Every call takes a role name first. All of them reject with an error whose code is one of the refusal codes.
| Call | What it does |
|---|---|
complete(role, messages, opts?) | One call. Returns the text, plus tool calls, sources and a structured object when asked for. |
stream(role, messages, opts?) | The same, with textStream to read as it arrives. |
embed(role, values, opts?) | Embeddings for a batch of texts. |
decide(role, request, opts?) | Typed decisions: yes/no, pick one, or a score. calibrated says whether the probabilities come from a decision model. |
batch(items, fn, opts?) | Runs many calls with limited concurrency, reporting progress and cost. Stops early on an overcharged call, a spend limit or an abort. |
Options on complete and stream:
| Option | What it does |
|---|---|
system | The system prompt. |
maxOutputTokens | The longest reply allowed. The per-call limit is checked against it. |
tools | Tools the model may call. They are returned, not run: calls are single-turn. |
output | A schema (zod or JSON Schema) the reply must match. complete only. |
webSearch | Ask the provider to search the web. |
skills | Skills to apply, by name. |
needs | Capabilities you need beyond what the options imply. |
for | What the call is about, for the ledger. |
signal | An AbortSignal to stop the call. |
tier, model, candidates | Another tier, one model or a list for this run. Only for roles with allowAnyModel. |
routing | Routing merged into each model's own for this call, such as an OpenRouter price cap. |
What every finished call reports:
| Field | What it holds |
|---|---|
servedModel, servedProvider | Who answered. |
usage | Tokens in and out, cached and reasoning tokens. |
listedUsd | The cost at listed prices; null when unknown. |
billedUsd | What the provider says it charged, when it says. |
overcharged | Billed well above listed. |
attempts, fellBack | Every model considered, in order, and whether the answer came from a fallback. |
budgets | The monthly budgets that apply, with this month's spend; warn at 80%. |
ledgerId | The call's row in the ledger. |
Models, skills and usage
| Call | What it does |
|---|---|
models(filter?) | The models the Hub knows, filtered by provider or by capability, for pickers. |
skills() | The skills the Hub can apply: its own, those plugins registered, and the vault's. Each has files() for its own text files. |
registerSkills(pluginId, skills) | Registers your built-in skills, each as a folder of text files with a SKILL.md. Replaces what you registered before. |
skillsReady() | Resolves once the vault's skills have loaded. |
onSkillsChanged(cb) | Calls cb when skills change. Returns the function that stops it. |
usage(filter?) | Ledger rows: every call, with tokens and cost. |
A skill your plugin registers is used only when a call names it; it can't be always on. A vault skill with the same name overrides yours.