Skip to content

[omp] dreamer.pi / historian.pi models ignored on OMP: live config sampling creates an empty omp block that shadows pi #645

Description

@sisttri

Short description

On OMP, dreamer.pi / historian.pi models are ignored and tasks silently run on OMP's default model

What happened?

On OMP, if the config only has pi blocks (the plugin falls back from omp to pi), dreamer tasks and the historian run on OMP's default model instead of the configured one. There's no warning, and doctor reports everything PASS.

Config (trimmed):

{
  "historian": { "pi": { "model": "claude-sonnet-5-5" } },
  "dreamer": {
    "pi": {
      "model": "claude-sonnet-5-5",
      "tasks": { "curate": { "model": "gpt-6-luna" } }
    }
  }
}

Expected: /ctx-dream curate runs on gpt-6-luna.

Actual: it runs on claude-opus-5-5, which is my OMP modelRoles.default. dream_runs reports the task as completed, so nothing looks wrong unless you check provider usage. From my provider's request log, two manual curate runs (main session requests filtered out; input = uncached + cache write + cache read):

time      model            input  output
15:11:40  claude-opus-5-5   8529    577
15:16:21  claude-opus-5-5   8889   1192
15:16:27  claude-opus-5-5  10189    498

After renaming pi to omp in both places (nothing else changed), the same command:

time      model        input  output
15:21:50  gpt-6-luna    4392    643
15:21:55  gpt-6-luna    5079    148

I think this is the cause:

sampleLiveConfig (packages/plugin/src/config/live-run-config.ts) walks every path in LIVE_RELOAD_CONFIG_PATHS, and for each parent segment it does target[part] = copy, creating {} when the parent doesn't exist. Since the list includes dreamer.omp.model, dreamer.omp.tasks, historian.omp.model etc., the sampled config always ends up with dreamer.omp = { model: undefined, tasks: undefined, ... } even when the user never wrote an omp block.

Then resolveHarnessBlock does

harness === "omp" ? container?.omp ?? container?.pi : container?.[harness]

and the empty object wins over pi, so no model is resolved and the child falls back to the host default.

I checked it by running the bundled functions against my config: with pi blocks, after sampleLiveConfig both curate's and the historian's model come back undefined; with omp blocks they resolve to luna / sonnet. So the historian is probably affected too. I only confirmed curate end to end through request logs. The code is unchanged on master as of today.

Possible fixes, either one would do:

  • in sampleLiveConfig, skip a path when the fresh value is undefined instead of creating the parent chain, or
  • in resolveHarnessBlock, only take omp when it actually has keys.

Workaround: use "omp" instead of "pi" for the historian / dreamer blocks.

Repro: put only pi blocks with a non-default model in the config, run /ctx-dream curate in OMP, and check which model the provider actually receives.

Diagnostics

Output of `npx @cortexkit/magic-context@0.46.1 doctor --issue --harness omp --report <file>` (taken after switching to the `omp` workaround; it was all PASS before as well):


- Magic Context CLI: 0.46.1
- PASS: OMP 18.8.6 detected at ~/.bun/bin/omp
- PASS: @cortexkit/pi-magic-context 0.46.1 is enabled
- PASS: Plugin exposes an OMP/Pi extension manifest
- PASS: OMP native compaction is disabled
- PASS: OMP automatic memory backend is disabled
- PASS: OMP agent directory resolved to ~/.omp/agent
- PASS: Magic Context config parses: ~/.config/cortexkit/magic-context.jsonc
- PASS: Magic Context runtime config loads successfully
- INFO: Shared storage: ~/.local/share/cortexkit/magic-context (source: platform default)
- PASS: SQLite integrity_check: ok
- PASS: Background maintenance completed its last pass

Plugin version

0.46.1

OpenCode version

N/A (Oh My Pi 18.8.6)

Platform

macOS arm64

Client

Pi

Log output (optional)

Activity

  1. magic-alfonso commented on Oct 9, 2026

    @magic-alfonso

    Thanks. Your diagnosis is correct, and the request logs made it easy to confirm. sampleLiveConfig created the parent object for every live path, so a config with only pi blocks gained an empty omp block. OMP resolves omp before falling back to pi, so the historian and dreamer lost their configured models and ran on OMP's default model. This affects the historian too, not just the dreamer.

    The fix is on master: an unset live path no longer creates its parent objects, and a key you remove from the config while running is still cleared. A regression test covers a pi-only config on OMP for both the historian and a dreamer task model. It ships in the next release. Until then, your workaround (writing the blocks as omp) is the right one.

  2. magic-alfonso commented on Oct 9, 2026

    @magic-alfonso

    Fixed in 0.47.0. Reloading config no longer creates an empty omp block, so pi historian and dreamer models apply on OMP again. Thanks for tracing it.

    Update to 0.47.0 (OpenCode: opencode-magic-context@0.47.0; Pi and Oh My Pi: @cortexkit/pi-magic-context@0.47.0). There is no database migration, so restarting the host is enough. OpenCode 2 needs 2.0.22 or newer and does not update plugins on its own: open /plugins, select Magic Context and press ctrl+u. Release notes: https://github.com/cortexkit/magic-context/releases/tag/v0.47.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions