omp packages

omp-plugin-dynamic-system-prompt0.6.0

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

metaphorics Published 1 month ago MIT ~98 downloads/mo

Built for omp

The author tagged this package oh-my-pi.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

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