Operating it

Private models and auth

Supplying a Hugging Face token for gated repos, without shipping it to the browser.

Two of the four NER models live in private StabRise repos. Reaching them needs a token.

configure({
    auth: async (repo) => {
        const response = await fetch('/api/hf-token')
        if (!response.ok) throw new Error('Sign in to use this model')
        return (await response.json()).token
    },
})

auth is called with the repo id, so one callback can mint different tokens for different repos — or refuse.

Never embed the token

Mint it server-side and scope it to the repos you need. A Hugging Face token shipped in client-side code is a published token, regardless of how it is obfuscated.

Prefer short-lived tokens: auth is called per fetch, so the callback is a natural place to hit an endpoint that issues one with a few minutes of life.

Tokenizers take a different path

GlinerNer needs a tokenizer, and that is fetched by @huggingface/transformers, which has its own host settings and does not see auth. For a gated repo, proxy it through your origin:

configure({
    hf: {
        remoteHost: `${location.origin}/`,
        remotePathTemplate: 'api/hf-model/{model}/resolve/{revision}/',
    },
})

Your endpoint then forwards to Hugging Face with the token attached server-side. {model} and {revision} are substituted by the transformers library.

Forgetting this is the most common failure: the ONNX weights download fine because they went through auth, and then the tokenizer 401s.

In a worker

auth is a function and does not survive postMessage, so client.configure({ auth }) is excluded by type. Set it inside the worker entry instead:

// src/scaledp.worker.ts
import { configure } from '@stabrise/scaledp'
import { registerStages, startScaleDpWorker } from '@stabrise/scaledp/worker'
import { GlinerNer } from '@stabrise/scaledp/ner'

configure({
    auth: async () => (await (await fetch('/api/hf-token')).json()).token,
})

registerStages({ GlinerNer })
startScaleDpWorker()

The fetch happens on the worker's thread but against the same origin and with the same cookies, so a session-cookie-authenticated endpoint works unchanged.

Checking before you try

The registry marks private models disabled in their enum options, which is enough for an interface to grey them out rather than let someone pick one and hit a 401 three stages into a run.

import { getNerModel } from '@stabrise/scaledp/ner'

getNerModel('stabrise-pii-multi')?.private   // true

On this page