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

@hokusai/router

v0.4.0

Published

Thin, zero-config façade over @hokusai/core for routing a task to a model and reporting the outcome.

Readme

@hokusai/router

The front-door SDK for the Hokusai task router. One import, two calls: ask the router which model to use, then report how it went. Reporting outcomes is what trains the router and mints tokens proportional to the performance lift.

@hokusai/router is a thin façade over @hokusai/core. It owns the wiring the common case should not have to think about — the API client, the dispatch builder, the consent snapshot, and the model registry. When you need more control, drop to @hokusai/core directly.

Install

npm install @hokusai/router

Quickstart

import { route } from '@hokusai/router';

// Your own model runners. Hokusai never calls a model — it only tells you which
// one to call, ranked across the pool you give it.
const models = {
  'claude-sonnet-4-6': { run: async (task: string) => ({ ok: true, costUsd: 0.42 }) },
  'claude-opus-4-8': { run: async (task: string) => ({ ok: true, costUsd: 1.10 }) },
};

const task = 'Refactor the billing webhook retry handling.';

// Reads HOKUSAI_API_KEY from the environment.
const { model, reasoning } = await route({
  task,
  context: { domain: 'payments', repo_type: 'monorepo' },
  availableModels: Object.keys(models),
  maxCostUsd: 1,
});

const result = await models[model].run(task);

// Reporting the outcome is what trains the router.
await route.reportOutcome({
  status: result.ok ? 'succeeded' : 'failed',
  actualCostUsd: result.costUsd,
});

route(...) returns the recommended model, the router's reasoning, a confidence, ranked alternatives, a routeId, and a correlationId. route.reportOutcome attributes the outcome to the most recent route() call, so the common single-flight loop needs nothing threaded through.

Report External Outcomes

If your harness already chose the model outside Hokusai, report that as an external observation rather than forcing a fake route. This is the path for Qwen, GLM, Gemini, Grok, DeepSeek, Kimi, Llama, Mistral, or custom policy runs that Hokusai did not decide:

await route.reportExternalOutcome({
  task: 'Fix flaky provider resolution.',
  allowedModels: ['qwen-3-coder', 'glm-5.2', 'gemini-2.5-pro'],
  model: 'qwen-3-coder',
  status: 'succeeded',
  budgetUsd: 0.5,
  actualCostUsd: 0.12,
  harness: 'custom-harness',
});

This still submits a contribution row to /contributions, but without an inference_log_id. The server's returned fidelityTier is authoritative: route-less observations may improve coverage without earning route-attributed rewards unless the backend policy explicitly classifies them as eligible.

Make the contribution count

reportOutcome submits a contribution row — the record the router actually trains on. The server scores it and returns a fidelityTier, and only training_eligible rows train the router or earn rewards:

const { fidelityTier } = await route.reportOutcome({ status: 'succeeded', actualCostUsd: 0.42 });
// 'training_eligible'

To reach that tier the server needs to score the cost against the budget, so it needs both:

| You must pass | Where | | --- | --- | | maxCostUsd — the budget | route({ ... }) | | actualCostUsd — what it really cost | route.reportOutcome({ ... }) |

Omit either and the row is accepted but classified partial: stored as telemetry, trains nothing, earns nothing. The router warns when this happens rather than letting you discover it in the tier. The tier is server-authoritative — never compute it locally.

Configuration

For anything beyond the zero-config default — a pinned model pool, a default objective, or an injected client — build a router explicitly:

import { createRouter } from '@hokusai/router';

const route = createRouter({
  apiKey: process.env.HOKUSAI_API_KEY,
  availableModels: ['claude-sonnet-4-6', 'qwen-3-coder', 'gemini-2.5-pro'],
  objective: 'reliability', // 'speed' | 'cost' | 'reliability'
});

Per-call overrides take precedence over the router defaults:

await route({
  task,
  availableModels: ['claude-opus-4-8', 'claude-sonnet-4-6'],
  objective: 'speed',
  maxCostUsd: 0.5,
  maxLatencySeconds: 30,
});

Candidate pools are honest

The router ranks across a typed candidate pool. A pool it cannot rank — one model, after de-duplication — is not swallowed: route(...) throws the same HokusaiValidationError that @hokusai/core raises. If you deliberately want to route with a single model (and record the row as non-ranking telemetry), opt in:

await route({
  task,
  availableModels: ['claude-sonnet-4-6'],
  routingMode: 'non-ranking',
});

Offline / mocked usage

Inject a client for tests or offline development — no network, no API key:

import { createRouter } from '@hokusai/router';
import { HokusaiClient } from '@hokusai/core';

const client = new HokusaiClient({
  apiKey: 'test',
  transport: (input, init) => {
    const pathname = new URL(input).pathname;
    if (pathname.endsWith('/predict')) {
      return Promise.resolve({
        status: 200,
        headers: { get: () => null },
        text: () =>
          Promise.resolve(
            JSON.stringify({
              routeId: 'route-1',
              taskId: 'task-1',
              status: 'accepted',
              recommendation: { model: 'claude-sonnet-4-6', reason: 'Mocked.' },
            }),
          ),
      });
    }
    // Outcomes are submitted as contribution rows.
    return Promise.resolve({
      status: 200,
      headers: { get: () => null },
      text: () =>
        Promise.resolve(
          JSON.stringify({
            accepted: true,
            rows_accepted: 1,
            row_fidelity_tiers: ['training_eligible'],
          }),
        ),
    });
  },
});

const route = createRouter({ client });
const { model } = await route({ task: 'Anything, offline.' });

Dropping to @hokusai/core

Advanced integrations that need custom consent, redaction, correlation storage, or the raw request/response shapes should use @hokusai/core's HokusaiClient and HokusaiDispatchBuilder directly. @hokusai/router is built entirely on those public APIs and hides none of them.