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

omp-plugin-dynamic-system-prompt

v0.6.0

Published

Append a per-model tuning block to the omp system prompt, scaled by model family, version, and tier.

Readme

omp-plugin-dynamic-system-prompt

Scales system-prompt guidance to the model that will read it — less instruction for frontier models, more for the ones that need it.

npm license runtime: bun

An oh-my-pi plugin. It appends one ## Model tuning section to the system prompt on every turn, choosing the directives from the model actually in use.


Why

A prompt written for a weak model wastes tokens and credibility on a strong one. "Stop searching once you have the answer" is worth saying to a model that keeps searching; on a frontier reasoner it is noise that displaces something useful.

So the guidance is inverted from the obvious direction: capability buys silence. A frontier flagship gets a light prompt. An older or small-tier model in the same family gets more. An unrecognized model gets the heaviest budget, on the assumption that it needs the most help.

gpt-5.6            -> light   (336 chars of 700)
claude-opus-4.5    -> medium  (286 chars of 1600)
claude-haiku-4.5   -> heavy   (286 chars of 3000)
glm-4.5-air        -> heavy   (298 chars of 3000)

The block never names the model, its version, or the resolved profile. Nothing tells the model it is being profiled.

Install

omp plugin install omp-plugin-dynamic-system-prompt

It works with no configuration. Every setting below has a default.

How it works

Three stages, one per module.

model id  ->  resolve axis  ->  select rules  ->  render block
              (model-axis)      (render)          (render)

1. Resolve the axis. The model id is normalized (bareModelId, lowercased, with suffixes like :thinking, :free, -high stripped) and classified into three independent dimensions:

| Dimension | Values | | --------- | --------------------------------------------------------------------------------------- | | family | openai anthropic gemini glm kimi deepseek grok qwen minimax unknown | | version | numeric series — gpt-5.6 → 5.6, kimi-k2.7 → 2.7; null when unparseable | | tier | flagship mid small |

Parsing is delegated to @oh-my-pi/pi-catalog/identity rather than reimplemented, so new model ids are recognized as the host catalog learns them.

2. Derive the weight. weight falls out of how far the version sits behind the family's frontier, plus a penalty for small-tier models. unknown always lands heavy.

| Distance from frontier | flagship / mid | small | | ---------------------- | -------------- | -------- | | current generation | light | medium | | one generation back | medium | heavy | | older, or unparseable | heavy | heavy |

3. Select and render. Rules whose applies(axis) holds and whose minWeight fits are sorted by priority, reduced to one rule per concern, then trimmed from the lowest priority end until the rendered block fits CHAR_BUDGET[weight] — 700, 1600, or 3000 characters.

When no rule applies, nothing is appended and the prompt is returned untouched. This is the normal outcome for an unrecognized model: it resolves heavy, but every rule gates on a known family, so the block is empty.

Worked examples

| model id | profile | weight | rules | block / budget | | --------------------- | ---------------------- | ------ | ----- | -------------- | | gpt-5.6 | openai-5.6-flagship | light | 2 | 336 / 700 | | gpt-5.5 | openai-5.5-flagship | light | 1 | 175 / 700 | | claude-opus-5 | anthropic-5-flagship | light | 3 | 498 / 700 | | claude-sonnet-5 | anthropic-5-mid | light | 2 | 337 / 700 | | kimi-k3 | kimi-3-flagship | light | 4 | 692 / 700 | | grok-4.5 | grok-4.5-flagship | light | 4 | 653 / 700 | | gemini-3-pro | gemini-3-flagship | medium | 1 | 206 / 1600 | | claude-opus-4.5 | anthropic-4.5-flagship | medium | 2 | 286 / 1600 | | claude-haiku-4.5 | anthropic-4.5-small | heavy | 2 | 286 / 3000 | | deepseek-v4-pro | deepseek-4-flagship | light | 2 | 341 / 700 | | deepseek-v4-flash | deepseek-4-small | medium | 5 | 786 / 1600 | | glm-4.5-air | glm-4.5-mid | heavy | 2 | 298 / 3000 | | grok-3-mini | grok-3-small | heavy | 1 | 184 / 3000 | | claude-opus-6 | anthropic-6-flagship | light | 0 | 0 / 700 | | some-unlisted-model | unknown-flagship | heavy | 0 | 0 / 3000 |

What glm-4.5-air actually receives:

## Model tuning

Settle one reading and act on it; reopen it only when a tool result
contradicts it. Re-deliberating the same evidence adds no information.

When the answer is already in context, return it. Skip filler verification
language and do not re-derive facts you settled earlier this turn.

Settings

Configurable in omp's settings UI, in ~/.omp/plugins/omp-plugins.lock.json, or by environment variable. The lockfile wins over the environment.

| Setting | Env | Values | Default | Effect | | ------------ | ------------------------- | ------------------------------------- | ------- | ------------------------------------------------------------- | | enabled | OMP_MODEL_TUNING | boolean | true | Append the block at all. | | weight | OMP_MODEL_TUNING_WEIGHT | auto light medium heavy off | auto | Override the derived weight. off disables the plugin. | | showStatus | OMP_MODEL_TUNING_STATUS | boolean | true | Show the tuning weight and injection state in the omp footer. |

With showStatus on, omp's footer carries one line: ● tuning heavy when the block was appended this turn, ○ tuning heavy when the resolved model matched no rule and nothing was appended. omp strips colour from extension status text, so the symbol is the whole signal. Switching models with /model updates it on the next turn, not immediately — omp emits no model_select event, so the axis is resolved when the turn starts.

Rules

Sixteen rules across twelve concerns. Only one rule per concern ever ships, so priority decides which of several competing directives a given model sees.

| id | concern | priority | min weight | | ------------------------------ | ---------------- | -------- | ---------- | | declared-stop | completion | 8 | light | | verify-once | verification | 9 | light | | real-surface-verify | verification | 10 | light | | settled-reading | deliberation | 11 | light | | reasoning-aim | deliberation | 12 | light | | effort-calibration | deliberation | 13 | medium | | no-filler-verification | verification | 14 | medium | | injected-directive-authority | harness-contract | 15 | medium | | search-stop | retrieval | 16 | medium | | reflect-then-ask | ambiguity | 20 | light | | confirmation-executed | re-litigation | 21 | medium | | todo-live | todo | 22 | medium | | recommendation-not-survey | reporting | 25 | light | | scope-literalism | scope | 30 | light | | compaction-persistence | context-budget | 40 | medium | | house-style-counter | aesthetics | 50 | medium |

The table is deliberately sparse. A rule earns its place only on evidence that a family needs the correction and that omp's base prompt does not already make it. Every light rule is also bounded to the series its evidence names, so a rule written for one generation cannot follow the family into the next — claude-opus-6 and gpt-6 resolve to an empty block for the same reason an unrecognized model does.

Development

bun install
bun test ./test                        # 74 tests across 6 files
bun x tsc --noEmit -p tsconfig.json    # typecheck

One peer dependency: @oh-my-pi/pi-catalog at >=16.0.5 with no upper bound, satisfied by the host omp. Every other import is a Node builtin.

Two invariants worth knowing before changing anything:

  • Append-only. The before_agent_start handler never replaces omp's system prompt, and it checks for TUNING_HEADER before appending so the block cannot accumulate across turns.
  • The block is anonymous. No model name, version, or profile string may appear in the rendered output.

AGENTS.md carries the full contract.

License

MIT