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

@mupt-ai/dari-router

v0.2.1

Published

End-to-end TypeScript framework for routing across LLMs with built-in Pi AI execution and pluggable policies and executors.

Readme

Dari Router Framework

@mupt-ai/dari-router is a pre-1.0 TypeScript framework for serving OpenAI Chat Completions and Anthropic Messages through one endpoint while choosing among multiple models.

It gives you three replaceable pieces:

  • Models describe candidates and capabilities.
  • Policies choose an eligible model.
  • Executors call the chosen model.

The root package also includes a Pi AI executor and a hosted Auto Router policy.

Install

npm install @mupt-ai/dari-router

The package is ESM and requires Node.js 22.19 or later, or Bun. Pi AI is an optional peer dependency: install @mupt-ai/pi-ai when using createPiRuntime; deterministic subpaths do not install its provider SDKs.

Minimal router

import { createRouter, type RouterExecutor } from "@mupt-ai/dari-router";

const executor: RouterExecutor = {
  execute({ model }) {
    return {
      type: "complete",
      output: {
        content: [{ type: "text", text: `Served by ${model.id}` }],
        finishReason: "stop",
      },
    };
  },
};

const router = createRouter({
  models: [{ id: "demo/model", executor: "demo" }],
  executors: { demo: executor },
  policy: ({ candidates }) => ({
    model: candidates[0]!.id,
    reason: "Use the only eligible candidate.",
  }),
});

Bun.serve({ port: 3000, fetch: router.fetch });

Send POST /v1/chat/completions or POST /v1/messages. The response uses the request's protocol and reports the selected model in routing metadata.

Pi execution

Use the built-in runtime when your models are in Pi's catalog:

import { createPiRuntime, createRouter } from "@mupt-ai/dari-router";

const pi = await createPiRuntime({ apiKey: process.env.OPENAI_API_KEY! });
const router = createRouter({
  executor: pi,
  models: [pi.model("openai/gpt-5.4-mini"), pi.model("openai/gpt-5.4")],
  policy: ({ candidates }) => ({ model: candidates[0]!.id }),
});

Credentials are supplied by your application; the runtime does not read environment variables itself. A canonical model ID identifies the model independently of where it runs. If that ID names the model owner rather than the execution provider, set provider to the service that will execute it and providerModelId to that service's Pi catalog ID:

const fireworksModel = pi.model("deepseek-ai/DeepSeek-V4-Pro-0813", {
  provider: "fireworks",
  providerModelId: "accounts/fireworks/models/deepseek-v4-pro-0813",
});

For multiple providers, supply a credential callback. It receives the selected provider, model, API, and whether the call is for execution or selection:

const pi = await createPiRuntime({
  apiKey: ({ provider }) => {
    const key = provider === "fireworks"
      ? process.env.FIREWORKS_API_KEY
      : process.env.OPENAI_API_KEY;
    if (!key) throw new Error(`Missing API key for ${provider}`);
    return key;
  },
});

Explicit provider metadata always wins; provider-prefixed IDs keep legacy prefix inference. See the framework documentation. Managed-router YAML manifests for use with the Dari CLI are in examples/managed/.

Explicit advanced boundaries

The root API is the end-to-end framework. Deterministic preparation, cache-aware evidence, selector parsing, and anonymous actions are under /policy-engine:

import { prepareRoute, finalizeRoute } from "@mupt-ai/dari-router/policy-engine";

Pure OpenAI/Anthropic adapters and continuation-state helpers are under /protocols:

import { openAIChatRequest, anthropicRequest } from "@mupt-ai/dari-router/protocols";

Browser-safe benchmark score imputation is available without Pi AI or provider SDKs:

import {
  createThinkingLevelRatios,
  resolveRouterEvalScore,
} from "@mupt-ai/dari-router/eval-score-imputation";

Most applications should use createRouter. Use router.evaluatePolicy() for stateless previews and router.select() when you need the same lease-aware selection used by router.fetch().

Development

bun install --frozen-lockfile
bun run typecheck
bun test
bun run build

Apache-2.0. See LICENSE.