Insurgently

Add Model Hub to your plugin

Find the Hub, register your roles and make a first call, in about twenty lines.

For people building on Model Hub.

With Model Hub, your plugin holds no keys and names no models. It declares the jobs it needs a model for, and the user decides which models serve them. Spend is credited to your plugin in the user's ledger.

Before you start#

  • Model Hub is desktop only, so a plugin that requires it is too.
  • The API's types aren't published as a package yet. Until they are, copy model-hub-api.d.ts into your plugin: it is every public declaration in one file. getHub and onHubReady are a few lines each; copy them from api/index.ts.

Steps#

  1. Find the Hub. getHub checks that Model Hub is installed and that its API is new enough for you. If not, it gives a plain message to show the user.

    const found = getHub(this.app, '0.4.0');
    if (!found.hub) return new Notice(found.message);
    const hub = found.hub;
    
  2. Register your roles. A role is named namespace.name in lowercase. The first plugin to use a namespace owns it. Each role names a tier (balanced if you name none).

    hub.registerRoles(this.manifest.id, [
      { name: 'mine.summarize', description: 'Summaries of a note', tier: 'quick' },
      { name: 'mine.embed', description: 'Vectors for search', tier: 'embedding' },
    ]);
    
  3. Make a call. Pass for so the ledger says what the call was about.

    const r = await hub.complete('mine.summarize', [{ role: 'user', content: noteText }], { for: file.path });
    // r.text, r.usage, r.listedUsd, r.billedUsd, r.servedModel, r.fellBack …
    
  4. Handle refusals. Every refusal or failure is an error with a code and a message written for the user.

    try {
      await hub.complete('mine.summarize', messages);
    } catch (e) {
      new Notice((e as Error).message); // e.code: 'over-ceiling', 'over-budget', 'provider-unavailable' …
    }
    
  5. Let the user remap your roles. One call opens the Hub's role editor for your plugin, so you have no model settings to build.

    hub.openRoleEditor(this.manifest.id);
    

If the Hub is reloaded#

The user may disable and enable Model Hub while your plugin runs. The new Hub fires model-hub:ready on the workspace. onHubReady runs your callback now and on every reload, so do your registration inside it:

onHubReady(this.app, this, '0.4.0', (hub) => {
  hub.registerRoles(this.manifest.id, MY_ROLES);
  hub.registerSkills(this.manifest.id, MY_SKILLS);
});

Registering roles again is harmless. Registered skills are lost on a reload, so they must be registered again.

What you get#

  • Your roles show in Settings → Model Hub → Roles under your plugin's name.
  • Every call is checked against the user's limits before it is sent, and recorded in the ledger with its cost.
  • When a model fails, the Hub falls back along the user's own list and tells you (fellBack, attempts).
Package
@insurgently/model-hub-api
Plugin id
model-hub
Needs
Obsidian 1.13.1, desktop
License
MIT