Files
command-center/agent/managed-skills/omp-per-model-sampler-config/SKILL.md
T
Frank 872e86399a agent: repoint FLM-NPU model roles off the retired provider; sync memory/skills
config.yml: vision -> llamacpp (dankclaw)/frank-large:auto,
tiny -> llamacpp (dankserver)/frank-small:off,
task -> llamacpp (dankclaw)/frank-large:medium (was flm dankclaw-npu),
matching the flm (dankclaw-npu) provider removal in models.yml.

Memories/managed skills: rollouts and learned notes from the frank-large
KV-pool + sampler work and the noctalia recolor; merged the duplicate
noctalia-palette-recolor skill into noctalia-custom-palette-recolor (adds
the dotfiles-tracking step and the +show-config delta gotcha) and dropped
the superseded legacy memory skills whose ghostty USR1 reload recipe is
wrong for this fleet.
2026-09-13 23:51:43 -07:00

3.1 KiB

name, description
name description
omp-per-model-sampler-config Set per-model sampler params and preserve_thinking in OMP's models.yml via compat.extraBody, and verify the exact wire body with an echo-capture profile.

OMP Per-Model Sampler Config (compat.extraBody)

~/.omp/agent/models.yml has no per-model sampler keys. Sampling is global (config.yml: temperature, topP, topK, minP, presencePenalty, repetitionPenalty; default -1 = not sent). The per-model hook is compat.extraBody.

Why it works

applyOpenAIExtraBody runs last in the openai-completions builder — after applyChatCompletionsCompatPolicy — via Object.assign(params, extraBody). So extraBody overrides global settings and compat-policy output.

Recipe

Use wire names, not OMP camelCase:

- id: frank-large
  compat:
    reasoningEffortMap:
      max: xhigh
    extraBody:
      temperature: 1.0
      top_p: 0.95
      top_k: 20
      min_p: 0.0
      presence_penalty: 0.0
      repetition_penalty: 1.0
      preserve_thinking: true

Two traps

  1. preserve_thinking is not user-settable. qwenPreserveThinking is auto-derived in buildOpenAICompat from the auto-detected thinkingFormat + local baseUrl, before applyCompatOverrides. Setting compat.thinkingFormat: qwen in models.yml does not enable it. Custom-named models (frank-large) match no Qwen id pattern → use extraBody: {preserve_thinking: true}.
  2. Never put chat_template_kwargs in extraBody. Object.assign is shallow — it replaces the whole object and silently drops the reasoning_effort kwarg the compat policy set. Top-level preserve_thinking is honoured by halogen; use that.

Gotcha: silent greedy decode

halogen-flash-server has no server-side sampler defaults — temperature absent or 0 = greedy. If OMP sends nothing, the endpoint decodes greedy while looking configured.

Verify the exact wire body (echo-capture)

Don't trust the YAML — capture what OMP actually emits.

  1. Echo server on 127.0.0.1:18099 that dumps the JSON body to a file and returns a canned chat.completion (include reasoning_content so thinking paths exercise).
  2. Copy the real models.yml into a throwaway profile with only the baseUrl swapped:
    sed 's|http://<host>:7770/v1|http://127.0.0.1:18099/v1|' \
      ~/.omp/agent/models.yml > ~/.omp/profiles/wiretest/agent/models.yml
    
  3. Run and inspect:
    omp --profile wiretest --model "<provider>/<model>" -p "hi" \
      --no-tools --no-session --no-extensions --no-skills --no-rules
    jq 'del(.messages, .tools)' last-body.json
    
    Confirm every intended field is present with the right value.

Verify a field is honoured, not just accepted

Unknown fields often return 200 anyway. Prove behavior with a prompt-token delta: replay an assistant turn carrying a long reasoning_content, then compare usage.prompt_tokens with the flag true vs false. A large delta means the field changed template rendering; zero delta means it was ignored.

Cleanup

Trash the probe profile and echo server (profiles/.AGENTTRASH), never rm.