Skip to content

[Bug]: Prometheus agent uses Gemini-specific prompt when opencode.json global model is Gemini, ignoring agent-specific model override #2693

@llc1123

Description

@llc1123

Prerequisites

  • I will write this issue in English (see our Language Policy)
  • I have searched existing issues to avoid duplicates
  • I am using the latest version of oh-my-opencode
  • I have read the documentation or asked an AI coding agent with this project's GitHub URL loaded and couldn't find the answer

Bug Description

When opencode.json sets a global model to a Gemini model (e.g., "model": "google/gemini-3.1-pro-preview"), Prometheus uses the Gemini-specific system prompt even if the user explicitly configures agents.prometheus.model to a Claude model in oh-my-opencode.json.

Root cause: buildPrometheusAgentConfig() in src/plugin-handlers/prometheus-agent-config-builder.ts line 43 passes params.currentModel (the global opencode.json model) as uiSelectedModel to resolveModelPipeline() unconditionally. Since uiSelectedModel is the highest-priority Step 1 in the pipeline, it short-circuits before ever reaching Step 2 where the user's Prometheus-specific model override lives.

All other agents protect against this:

  • Sisyphus (sisyphus-agent.ts:55): uiSelectedModel: sisyphusOverride?.model ? undefined : uiSelectedModel
  • Atlas (atlas-agent.ts:42): uiSelectedModel: orchestratorOverride?.model ? undefined : uiSelectedModel
  • General agents (general-agents.ts:72): uiSelectedModel: (isPrimaryAgent && !override?.model) ? uiSelectedModel : undefined

Prometheus lacks this guard entirely.

Additionally, there is a prompt/model mismatch caused by the override spread on line 93: { ...base, ...restOverride } changes the final model to the user's config value, but the prompt was already computed from the pipeline-resolved model (the global Gemini model). The result is Claude model running with Gemini prompt.

A categoryConfig?.model (when user sets prometheus.category instead of prometheus.model) is also affected by the same issue, as it is folded into userModel at line 44, still below uiSelectedModel in priority.

Steps to Reproduce

  1. Set global model to Gemini in opencode.json:
    { "model": "google/gemini-3.1-pro-preview" }
  2. Set Prometheus model to Claude in oh-my-opencode.json:
    {
      "agents": {
        "prometheus": {
          "model": "anthropic/claude-opus-4-6",
          "variant": "max"
        }
      }
    }
  3. Select the Prometheus agent in the OpenCode conversation UI and start a conversation
  4. Observe the system prompt content sent to the model provider

Expected Behavior

  • Prometheus should resolve to anthropic/claude-opus-4-6 (the user's explicit agent override)
  • Prometheus should use the Claude-optimized (default) system prompt
  • /tmp/oh-my-opencode.log should show: Model resolved via config override

Actual Behavior

  • Pipeline resolves to google/gemini-3.1-pro-preview (global opencode.json model)
  • Prometheus uses the Gemini-specific system prompt (aggressive tool-call enforcement, thinking checkpoints) — observed via model provider's API call logs showing Gemini prompt content being sent to a Claude model endpoint
  • /tmp/oh-my-opencode.log shows: Model resolved via UI selection (Note: the log file does record model resolution, but the issue was originally discovered through the model provider's API request logs, which showed the Gemini-specific prompt being sent to the Claude API)
  • After the override spread on line 93, the final config has model: "anthropic/claude-opus-4-6" but prompt: <Gemini prompt> — a mismatch

Doctor Output

oMoMoMoMo Doctor
✓ System OK (opencode 1.2.27 · oh-my-opencode 3.12.0)

Configuration

{
  "agents": {
    "prometheus": {
      "model": "anthropic/claude-opus-4-6",
      "variant": "max"
    }
  }
}

(Global opencode.json has "model": "google/gemini-3.1-pro-preview")

Additional Context

Affected code path:

  1. src/plugin-handlers/agent-config-handler.ts:80currentModel = params.config.model reads the global model
  2. src/plugin-handlers/prometheus-agent-config-builder.ts:43 — passes it unconditionally as uiSelectedModel
  3. src/shared/model-resolution-pipeline.ts:49-53 — Step 1 short-circuits, never reaches Step 2
  4. src/plugin-handlers/prometheus-agent-config-builder.ts:72 — prompt computed from wrong model
  5. src/plugin-handlers/prometheus-agent-config-builder.ts:93 — spread changes model but not prompt

Suggested fix (low-risk, matches existing patterns):

// prometheus-agent-config-builder.ts, line 41-51
const configuredPrometheusModel =
  params.pluginPrometheusOverride?.model ?? categoryConfig?.model;

const modelResolution = resolveModelPipeline({
  intent: {
    uiSelectedModel: configuredPrometheusModel ? undefined : params.currentModel,
    userModel: params.pluginPrometheusOverride?.model,
    categoryDefaultModel: categoryConfig?.model,
  },
  constraints: { availableModels },
  policy: {
    fallbackChain: requirement?.fallbackChain,
    systemDefaultModel: undefined,
  },
});

This also separates categoryConfig?.model into categoryDefaultModel (its correct pipeline slot with availability checks) instead of folding it into userModel.

Operating System

Linux

OpenCode Version

1.2.27

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions