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

@ncdlabs/openclaw-difficulty-router

v1.0.4

Published

OpenClaw plugin that selects the model per turn based on prompt difficulty (simple / default / complex)

Readme

OpenClaw Difficulty Router

OpenClaw plugin that selects the provider/model per turn based on prompt difficulty. It implements the before_model_resolve hook and returns providerOverride / modelOverride so simple prompts can use a small model and complex prompts a larger one.

  • Automatic mode: No config (or empty config). No overrides; OpenClaw uses its default model. Behavior is predictable.
  • Single config: Configure tiers (and optional heuristic tuning) in one place: either the plugin config block in OpenClaw config or one optional JSON file.

No changes to the OpenClaw core repo are required. Install into an existing OpenClaw installation and enable the plugin.

Requirements: Node.js >= 18, OpenClaw >= 2026.2.0.

Installation

From the OpenClaw project or environment where the openclaw CLI is available:

openclaw plugin install @ncdlabs/openclaw-difficulty-router

OpenClaw may also support installing from GitHub; see OpenClaw plugin docs for current options.

After install, enable the plugin (if not auto-enabled) and optionally add config:

openclaw plugins enable difficulty-router

Configuration

All user-facing configuration is either:

  • Automatic: No file, no plugin config. The plugin does not override; OpenClaw’s default model is used every turn.
  • Plugin config block: In your main OpenClaw config (openclaw.yaml or openclaw.json), under plugins.entries.difficulty-router.config.
  • Single JSON file (optional): Set configFile in the plugin config to a path (e.g. ~/.openclaw/difficulty-router.json). That file can define tiers and heuristic; values there override the plugin config block.

Tier keys

Tiers are: simple, default, complex. Each value is a model ref in the same format OpenClaw uses: provider/model-id (e.g. ollama/qwen2.5-coder:3b, openai/gpt-4o-mini).

  • simple: Very short prompts and no sign of multi-step work (see heuristic below).
  • default: Everything that is neither simple nor complex.
  • complex: Long prompts or clearly multi-part / step-by-step prompts.

You can set only the tiers you care about. If a tier is missing, that turn is not overridden and OpenClaw’s default applies.

Heuristic (tunable)

When tiers are configured, difficulty is computed as follows (thresholds are configurable):

  • simple: Prompt length ≤ simpleMaxChars (default 50) and no multi-step indicators (e.g. “step 1”, “first, then”, bullet lists).
  • complex: Prompt length ≥ complexMinChars (default 500) or contains multi-step indicators.
  • default: Everything else.

Prefer default when in doubt. Thresholds can be set under heuristic in the plugin config or in the optional JSON file.

Example: plugin config only

In openclaw.yaml (or equivalent):

plugins:
  entries:
    difficulty-router:
      enabled: true
      config:
        tiers:
          simple: "ollama/qwen2.5-coder:3b"
          default: "ollama/qwen2.5-coder:7b"
          complex: "ollama/qwen2.5-coder:32b"
        heuristic:
          simpleMaxChars: 80
          complexMinChars: 400

Example: single JSON file

In OpenClaw config, point to one file:

plugins:
  entries:
    difficulty-router:
      enabled: true
      config:
        configFile: "~/.openclaw/difficulty-router.json"

Then create ~/.openclaw/difficulty-router.json:

{
  "tiers": {
    "simple": "ollama/qwen2.5-coder:3b",
    "default": "ollama/qwen2.5-coder:7b",
    "complex": "ollama/qwen2.5-coder:32b"
  },
  "heuristic": {
    "simpleMaxChars": 50,
    "complexMinChars": 500
  }
}

Behavior

  • When no tiers are set (automatic or empty config): the plugin never overrides; OpenClaw’s default provider/model is used.
  • When tiers are set: on each turn the plugin computes difficulty, picks the tier’s model ref, and returns providerOverride and modelOverride. OpenClaw then uses that model for that run. If the overridden model fails, OpenClaw’s existing fallback behavior applies.

Heuristic validation

If simpleMaxChars is set greater than or equal to complexMinChars, the plugin automatically sets complexMinChars to simpleMaxChars + 1 so the default band is never empty.

Troubleshooting

  • Plugin does not override: Ensure at least one tier is set under tiers (simple, default, or complex) and the plugin is enabled (plugins.entries.difficulty-router.enabled: true). Check gateway logs for [difficulty-router] loaded with tiers at startup.
  • configFile not found or invalid: If you set configFile, the path is resolved via OpenClaw’s resolvePath (e.g. ~ expands to your home directory). The file must be valid JSON. You’ll see [difficulty-router] configFile not found or configFile parse error in logs if the file is missing or invalid.
  • Invalid tier model ref: Each tier value must be provider/model (e.g. ollama/qwen2.5-coder:3b). If a ref is malformed, that tier is skipped for the run and no override is returned.
  • Hook errors: If the hook throws (e.g. bug), the plugin catches, logs [difficulty-router] before_model_resolve error: ..., and returns no override so the run continues with the default model.

Security / Scanning

This plugin has zero runtime dependencies (only a peer dependency on OpenClaw). That keeps the supply-chain surface small: no transitive packages from this plugin.

After installing (e.g. into ~/.openclaw/extensions/difficulty-router/), you can run:

  • npm audit – From the plugin directory: npm audit. Any reported vulnerabilities will be from OpenClaw’s dependency tree (installed as a peer), not from this package’s own dependencies.
  • Socket – For a deeper scan, use Socket CLI: socket login (once, with your API token), then socket scan create from the plugin directory or socket package score npm @ncdlabs/openclaw-difficulty-router.

See SECURITY.md for how to report vulnerabilities.

Development

npm install
npm run build

Build output is dist/. The OpenClaw plugin entry is ./dist/index.js (see openclaw.extensions in package.json). Run npm pkg fix to normalize package.json if needed.

License

MIT.