Skip to content

harness-provider-map: missing opencode ↔ opencode-zen translation breaks shared model refs on OMP #344

Description

@Qiiks

Problem

src/shared/harness-provider-map.ts translates provider prefixes between the canonical (OpenCode) form and Pi/OMP-native selectors, but the map only covers subscription providers:

const CANONICAL_TO_PI_PROVIDER = { openai: "openai-codex", google: "google-antigravity" };
const CANONICAL_TO_OMP_PROVIDER = { openai: "openai-codex", google: "google-antigravity" };

The OpenCode Zen gateway provider id is opencode on OpenCode, but OMP exposes the same gateway under opencode-zen. Because neither prefix is in the map, a single model ref in the shared ~/.config/cortexkit/magic-context.jsonc cannot resolve on both harnesses:

  • historian.model: "opencode/deepseek-v4-flash-free" → works on OpenCode; on OMP the runner gets opencode/... unchanged (resolveModelRefForOmp is identity for unmapped prefixes) and the spawn fails.
  • historian.model: "opencode-zen/deepseek-v4-flash-free" → works on OMP; on OpenCode opencode-zen is not a known provider and the spawn fails.

The same issue applies to dreamer.model, sidekick, and any other shared-config model ref.

Current workaround

Listing both spellings in fallback_models works (model = OpenCode form, fallback_models = OMP form, and vice versa), but one harness burns a failed model spawn on every historian/dreamer run before hitting the working spelling.

Proposed change

Add the pair to the OMP (and Pi, if applicable) maps:

const CANONICAL_TO_OMP_PROVIDER: Readonly<Record<string, string>> = {
    openai: "openai-codex",
    google: "google-antigravity",
    opencode: "opencode-zen",
};

const OMP_TO_CANONICAL_PROVIDER: Readonly<Record<string, string>> = {
    "openai-codex": "openai",
    "google-antigravity": "google",
    "opencode-zen": "opencode",
};

modelRefLookupOrder already emits every known spelling of a ref with the canonical form first, so a single opencode/... ref in the config would then resolve on both harnesses with zero failed spawns. The header comment explicitly frames the map as "Provider IDs are a harness boundary, not a database identity", and the OpenCode form is canonical by definition ("OpenCode needs no translation because canonical is its native form").

Questions for the maintainers:

  • Should opencode-go also be registered as a known spelling of opencode in the OMP map, or is it a distinct gateway that should stay unmapped?
  • Is opencode-zen also present on plain Pi (not just OMP), warranting a Pi entry too?

Happy to open a PR with the map change plus the existing harness-provider-map.test.ts coverage extended.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions