Skip to content

Feature Request: Allow plugin agents to override mode from frontmatter #1032

@borgius

Description

@borgius

Feature Request: Allow plugin agents to override mode from frontmatter

Summary

Plugin agents are currently hardcoded to mode: "subagent" and cannot be made switchable via the tab interface. This prevents plugins from providing primary agents that users can switch to, even though the AgentOverrideConfigSchema already supports mode field.

Current Behavior

In loadPluginAgents function (around line 46840 in dist/index.js):

const config3 = {
  description: formattedDescription,
  mode: "subagent",  // <-- Hardcoded
  prompt: body.trim()
};

All plugin agents are forced to mode: "subagent", regardless of any mode field specified in the agent's frontmatter markdown file.

Desired Behavior

Respect the mode field from agent frontmatter:

const config3 = {
  description: formattedDescription,
  mode: data.mode || "subagent",  // <-- Allow override
  prompt: body.trim()
};

This would allow plugin authors to create switchable agents by adding:

---
name: my_agent
description: My custom agent
mode: "primary"
---

Agent prompt here...

Use Case

I'm developing a plugin for competitive analysis (opencode-competitive-analysis) that orchestrates a team of specialist agents. I want to provide a switchable agent for this workflow so users can:

  1. Switch to the competitive analysis agent via tab
  2. Use it as their primary agent for market research tasks
  3. Leverage the tool orchestrator pattern similar to Sisyphus

Currently, I can only invoke this agent via @plugin-name:agent-name mentions, but not switch to it.

Benefits

  • Extensibility: Plugins can provide full-featured primary agents, not just subagents
  • Consistency: Aligns with AgentOverrideConfigSchema which already supports mode for built-in agents
  • Simplicity: Small code change with minimal risk
  • No Breaking Changes: Defaults to "subagent" if mode not specified

Alternatives Considered

  • Forking oh-my-opencode to modify behavior (not ideal - can't benefit from upstream updates)
  • Using only tool-based approach (less ergonomic - users prefer switching agents)
  • Manually editing oh-my-opencode after each update (not sustainable)

Implementation

// In loadPluginAgents function
function loadPluginAgents(plugins) {
  const agents = {};
  for (const plugin2 of plugins) {
    if (!plugin2.agentsDir || !existsSync50(plugin2.agentsDir))
      continue;
    const entries = readdirSync18(plugin2.agentsDir, { withFileTypes: true });
    for (const entry of entries) {
      if (!isMarkdownFile(entry))
        continue;
      const agentPath = join58(plugin2.agentsDir, entry.name);
      const agentName = basename7(entry.name, ".md");
      const namespacedName = `${plugin2.name}:${agentName}`;
      try {
        const content = readFileSync32(agentPath, "utf-8");
        const { data, body } = parseFrontmatter(content);
        const name = data.name || agentName;
        const originalDescription = data.description || "";
        const formattedDescription = `(plugin: ${plugin2.name}) ${originalDescription}`;
        
        const config3 = {
          description: formattedDescription,
          mode: data.mode || "subagent",  // Allow override from frontmatter
          prompt: body.trim()
        };
        
        const toolsConfig = parseToolsConfig2(data.tools);
        if (toolsConfig) {
          config3.tools = toolsConfig;
        }
        agents[namespacedName] = config3;
        log(`Loaded plugin agent: ${namespacedName}`, { path: agentPath });
      } catch (error45) {
        log(`Failed to load plugin agent: ${agentPath}`, error45);
      }
    }
  }
  return agents;
}

Additional Considerations

Should we add validation for the mode field? Ensure it's one of ["subagent", "primary", "all"]?

const validModes = ["subagent", "primary", "all"];
const mode = data.mode || "subagent";
if (!validModes.includes(mode)) {
  log(`Warning: Invalid mode "${mode}" for agent ${namespacedName}, defaulting to "subagent"`);
  config3.mode = "subagent";
} else {
  config3.mode = mode;
}

Environment

  • OpenCode version: latest
  • oh-my-opencode version: 2.14.0
  • OS: macOS (darwin)

Thank you for this amazing project! Sisyphus has been incredibly helpful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions