Skip to content

[Bug]: Custom agents from .opencode/agents/ invisible to orchestrator agents (Sisyphus/Atlas/Hephaestus) #1623

@dtateks

Description

@dtateks

Summary

Custom agents defined in .opencode/agents/ (or .claude/agents/) are correctly loaded and registered in OpenCode — they can be invoked via @agent_name. However, they are completely invisible to orchestrator agents (Sisyphus, Hephaestus, Atlas) because they are never injected into the availableAgents list that builds the orchestrator's system prompt.

This means orchestrators will never autonomously delegate to user-defined custom agents, defeating the purpose of the multi-agent orchestration system.

Steps to Reproduce

  1. Create a custom agent in .opencode/agents/researcher.md:

    ---
    description: Research agent for deep analysis
    mode: subagent
    ---
    You are a research agent...
  2. Start OpenCode with oh-my-opencode plugin

  3. Verify @researcher works (it does — agent is registered)

  4. Ask Sisyphus a question that would benefit from delegating to researcher

  5. Observe: Sisyphus never mentions or delegates to researcher — it doesn't know it exists

Root Cause Analysis

Layer 1: Custom agents ARE loaded and registered ✅

config-handler.ts (lines 392-403) correctly merges custom agents into config.agent:

config.agent = {
  ...agentConfig,           // plugin built-in (sisyphus, etc.)
  ...builtinAgents,         // other built-in agents
  ...userAgents,            // ~/.claude/agents/ ✅ loaded
  ...projectAgents,         // .claude/agents/   ✅ loaded
  ...pluginAgents,          // Claude Code plugins
  ...filteredConfigAgents,  // OpenCode native agents (includes .opencode/agents/) ✅ loaded
};

Layer 2: Custom agents are NOT in availableAgents

src/agents/utils.ts (lines 252-345) builds availableAgents exclusively from agentSources — a hardcoded map of built-in agents:

const availableAgents: AvailableAgent[] = []  // starts empty

for (const [name, source] of Object.entries(agentSources)) {  // only built-in agents
  // ...
  const metadata = agentMetadata[agentName]
  if (metadata) {
    availableAgents.push({...})  // only agents with metadata
  }
}

agentSources (lines 23-35) is hardcoded:

const agentSources: Record<BuiltinAgentName, AgentSource> = {
  sisyphus, hephaestus, oracle, librarian, explore,
  "multimodal-looker", metis, momus, atlas
}

Layer 3: availableAgents is the SOLE source for orchestrator prompts ❌

availableAgents is passed to createSisyphusAgent() (line 373-379), createHephaestusAgent() (line 418-424), and createAtlasAgent() (line 467-472). These use dynamic-agent-prompt-builder.ts to render Delegation Table, Key Triggers, and Agent Selection sections.

Result: Custom agents exist in the system but orchestrators are blind to them.

Impact

Capability Status
@custom_agent manual invocation ✅ Works
Custom agent appears in system prompt ❌ Missing
Sisyphus auto-delegates to custom agent ❌ Impossible
Atlas orchestrates with custom agent ❌ Impossible
Hephaestus delegates to custom agent ❌ Impossible

Proposed Fix

Collect custom agents (from userAgents, projectAgents, pluginAgents, and filteredConfigAgents) and append them to availableAgents before passing to orchestrator agent factories.

Rough approach:

// In createBuiltinAgents() or in config-handler.ts after agent merging

// Collect custom agents as AvailableAgent entries
const customAgentEntries: AvailableAgent[] = [
  ...Object.entries(userAgents),
  ...Object.entries(projectAgents),
  ...Object.entries(pluginAgents),
].map(([name, config]) => ({
  name,
  description: config.description ?? "",
  metadata: {
    category: "custom",
    cost: "unknown",
    triggers: [],
  },
}));

// Merge into availableAgents before creating orchestrator agents
const allAvailableAgents = [...availableAgents, ...customAgentEntries];

The dynamic-agent-prompt-builder.ts would need a section to render custom agents separately (e.g., "User-Defined Agents" table) so orchestrators know they exist and when to use them.

Environment

  • oh-my-opencode version: latest (dev branch)
  • OpenCode: >= 1.0.150
  • Relevant files:
    • src/agents/utils.ts (lines 228-485) — createBuiltinAgents()
    • src/agents/dynamic-agent-prompt-builder.ts — prompt rendering
    • src/plugin-handlers/config-handler.ts (lines 392-403) — agent merging
    • src/features/claude-code-agent-loader/loader.ts.claude/agents/ loader

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