Agent Factory Pattern
All agents follow thecreateXXXAgent(model) → AgentConfig pattern:
src/agents/oracle.ts:145
AgentConfig Schema
Agent Modes
| Mode | Model Selection | Use Case |
|---|---|---|
primary | Respects UI-selected model, uses fallback chain | Main orchestrators (Sisyphus) |
subagent | Uses own fallback chain, ignores UI | Specialized workers (Oracle, Librarian) |
all | Available in both contexts | Versatile agents (Sisyphus-Junior) |
Permission System
Restrict tool access per agent:src/agents/oracle.ts:146
Building a Custom Agent
import type { AgentConfig } from "@opencode-ai/sdk"
import type { AgentMode } from "./types"
import { createAgentToolRestrictions } from "../shared/permission-compat"
const MODE: AgentMode = "subagent"
const SYSTEM_PROMPT = `You are a specialized agent for [purpose].
<role>
You [core responsibility]. You do NOT [boundaries].
</role>
<workflow>
1. [Step one]
2. [Step two]
3. [Step three]
</workflow>
<constraints>
- [Constraint 1]
- [Constraint 2]
</constraints>`
export function createMyAgent(model: string): AgentConfig {
const restrictions = createAgentToolRestrictions(["write", "edit"])
return {
description: "Brief agent description for user",
mode: MODE,
model,
temperature: 0.1,
maxTokens: 16000,
prompt: SYSTEM_PROMPT,
...restrictions,
thinking: { type: "enabled", budgetTokens: 16000 }
}
}
createMyAgent.mode = MODE
import { createMyAgent } from "./my-agent"
export function createBuiltinAgents(deps: BuildAgentDeps) {
const agents: Record<string, AgentConfig> = {}
// ... existing agents
if (!deps.disabledAgents.has("my-agent")) {
agents["my-agent"] = buildAgent(
createMyAgent,
deps.model,
deps.categories,
deps.gitMasterConfig,
deps.browserProvider,
deps.disabledSkills
)
}
return agents
}
export const AgentNameSchema = z.enum([
// ... existing agents
"my-agent",
])
export type AgentName = z.infer<typeof AgentNameSchema>
Agent Builder
ThebuildAgent() function composes agent configurations:
src/agents/agent-builder.ts:14
Agent Builder Logic
src/agents/agent-builder.ts:14
Dynamic Prompt Building
Sisyphus demonstrates dynamic prompt construction:src/agents/sisyphus.ts:151
Pattern: Build prompts from available context (agents, tools, skills).
Model-Specific Configuration
Adjust settings per model family:src/agents/types.ts
Subagent Invocation
Agents are invoked via thetask or call_omo_agent tools:
Via task Tool (Recommended)
Via call_omo_agent Tool
Agent Prompt Metadata
Document agent usage patterns:Built-in Agent Examples
Oracle Agent
Purpose: Read-only strategic advisor for complex decisions Key Features:- Tool restrictions: No write/edit/task tools
- High thinking budget: 32000 tokens
- Structured response format: Bottom line → Action plan → Rationale
- Effort estimation: Quick/Short/Medium/Large tags
src/agents/oracle.ts:145
Sisyphus Agent
Purpose: Main orchestrator with delegation capabilities Key Features:- Dynamic prompt building from available agents/tools/skills
- Intent verbalization before classification
- Mandatory todo/task management for multi-step work
- Model-specific overlays (Gemini tool mandate)
- Parallel execution default
src/agents/sisyphus.ts:550
Hephaestus Agent
Purpose: Autonomous deep worker for complex implementation Key Features:- GPT-5.3-codex requirement (no fallback)
- High reasoning effort
- No subagent delegation (works independently)
- Focus on implementation depth
src/agents/hephaestus.ts
Agent Configuration Override
Users can override agent settings viaoh-my-opencode.jsonc:
Agent Resolution
The session agent resolver determines which agent owns a session:src/plugin/session-agent-resolver.ts
Testing Agents
Test agent factories:Related Files
- Agent Builder:
src/agents/agent-builder.ts - Agent Types:
src/agents/types.ts - Built-in Agents:
src/agents/builtin-agents.ts - Agent Registry:
src/agents/index.ts - Session Agent Resolver:
src/plugin/session-agent-resolver.ts - Model Requirements:
src/shared/model-requirements.ts