) to inject project context. Nested files allow granular context injection based on directory structure.
- Context Management: Relies on automatic compaction. Older tool outputs are cleared, and sessions are summarized when approaching context windows.
- Tool Use: Tool definitions are tightly integrated with the model's native tool-calling capabilities, reducing parsing overhead.
Implementation Example: Vertical Configuration & Hooks
In a vertical runtime, you define project memory and permission hooks. The following TypeScript snippet demonstrates a conceptual permission hook structure and memory configuration for a vertical agent environment.
// Vertical Runtime: Permission Hook Interface
interface PermissionHook {
validate(command: string, context: AgentContext): ValidationResult;
}
interface ValidationResult {
allowed: boolean;
reason?: string;
sanitizedCommand?: string;
}
// Example: Restrict destructive commands
const safetyHook: PermissionHook = {
validate(command: string): ValidationResult {
const dangerousPatterns = [/rm\s+-rf\s+\//, /sudo\s+.*delete/];
const isDangerous = dangerousPatterns.some(pattern => pattern.test(command));
if (isDangerous) {
return { allowed: false, reason: "Destructive system command blocked." };
}
return { allowed: true };
}
};
// Vertical Runtime: Memory Configuration
// CLAUDE.md structure injected into system prompt
const projectMemory = {
global: `
# Project Guidelines
- Use TypeScript strict mode.
- All API responses must follow the standard envelope format.
- Run 'npm run lint' before committing.
`,
directorySpecific: {
"src/auth": `
# Auth Module Context
- Uses JWT with refresh token rotation.
- Do not modify the token signing logic without security review.
`
}
};
2. The Open Orchestration Pattern
Open runtimes abstract the model layer, allowing a single agent interface to interact with multiple providers. This requires a normalization layer that handles differences in tool call formats, context limits, and response structures. These runtimes often persist full conversation history in a database, enabling advanced pruning strategies and audit trails.
Architecture Rationale:
- Model Routing: The runtime reads provider metadata to determine context limits and capabilities. Tasks can be routed to cheaper models for simple edits or powerful models for complex reasoning.
- Memory: Uses portable formats like
AGENTS.md. This file can be committed to version control, shared across teams, and used by multiple agent tools, reducing vendor lock-in.
- Context Management: Explicitly monitors context usage against model limits. It maintains a buffer for output and prunes old tool outputs before summarizing. History is stored in SQLite, ensuring data is never lost during pruning.
- Tool Use: The runtime normalizes tool calls across providers. If a model does not support native tool calling, the runtime may parse text outputs or use function calling wrappers.
Implementation Example: Open Orchestration Configuration
The following TypeScript example demonstrates a configuration structure for an open orchestrator, defining providers, agents, and storage backends.
// Open Orchestration: Provider Routing
interface ProviderRoute {
id: string;
model: string;
apiKeyEnv: string;
contextLimit: number;
capabilities: ('tool_call' | 'vision' | 'json_mode')[];
}
const providers: ProviderRoute[] = [
{
id: 'anthropic-primary',
model: 'claude-sonnet-4-20250514',
apiKeyEnv: 'ANTHROPIC_API_KEY',
contextLimit: 200000,
capabilities: ['tool_call', 'json_mode']
},
{
id: 'openai-fallback',
model: 'gpt-4o-mini',
apiKeyEnv: 'OPENAI_API_KEY',
contextLimit: 128000,
capabilities: ['tool_call']
},
{
id: 'local-ollama',
model: 'llama3.1:8b',
apiKeyEnv: '', // Local
contextLimit: 32000,
capabilities: ['tool_call']
}
];
// Open Orchestration: Agent Definition
interface AgentDefinition {
name: string;
role: string;
primaryProvider: string;
fallbackProviders: string[];
tools: string[];
instructions: string;
}
const codingAgent: AgentDefinition = {
name: 'feature-developer',
role: 'Implements features based on ticket descriptions.',
primaryProvider: 'anthropic-primary',
fallbackProviders: ['openai-fallback'],
tools: ['read', 'write', 'edit', 'bash', 'grep', 'glob'],
instructions: `
You are a senior developer.
1. Analyze the request.
2. Search the codebase using grep/glob.
3. Implement changes using write/edit.
4. Run tests to verify.
Always update AGENTS.md if project conventions change.
`
};
// Open Orchestration: Storage Configuration
interface StorageConfig {
type: 'sqlite';
path: string;
retentionPolicy: 'prune-and-summarize';
}
const storage: StorageConfig = {
type: 'sqlite',
path: './.agent/history.db',
retentionPolicy: 'prune-and-summarize'
};
3. Task Delegation and Subagents
Both paradigms support subagents to handle complex tasks without bloating the main context window. Subagents are isolated instances that execute specific subtasks and return results to the primary agent.
- Vertical Approach: Subagents are often managed internally by the runtime, with limited configuration. They share the same permission model and tool access as the parent.
- Open Approach: Subagents can be explicitly defined with different models, tools, and instructions. This allows for heterogeneous delegation, such as using a fast, cheap model for file searching and a powerful model for code synthesis.
Best Practice: Use subagents for isolated operations like running test suites, generating documentation, or refactoring large modules. This preserves the primary agent's context for high-level reasoning and coordination.
Pitfall Guide
Production experience with coding agents reveals common failure modes. Avoid these pitfalls to ensure reliable operation.
-
Context Bleed via Memory Files
- Explanation: Storing excessive project details in
CLAUDE.md or AGENTS.md consumes context tokens on every turn, increasing latency and cost.
- Fix: Keep memory files concise. Use nested memory files to inject context only when relevant. Regularly audit and trim memory content.
-
Ignoring Context Limits in Open Runtimes
- Explanation: Open orchestrators support models with varying context limits. Failing to configure limits correctly can cause silent truncation or API errors.
- Fix: Explicitly define
contextLimit for each provider. Implement monitoring to warn when sessions approach 80% of the limit.
-
Over-Permissive Tool Access
- Explanation: Granting agents unrestricted bash access or file write permissions can lead to accidental data loss or security vulnerabilities.
- Fix: Configure granular permissions. Restrict bash commands to safe operations. Use allowlists for file paths and require approval for destructive actions.
-
Tool Call Hallucination
- Explanation: Some models struggle with structured tool calls, returning malformed JSON or incorrect arguments.
- Fix: Use models with proven tool-calling capabilities. Implement output validation in the runtime. For open orchestrators, enable retry logic with corrected prompts.
-
Vendor Lock-in via Configuration
- Explanation: Writing agent configurations or hooks that are specific to one runtime makes migration difficult.
- Fix: Prefer portable formats like
AGENTS.md. Abstract custom tools behind standard interfaces. Document dependencies clearly.
-
Cost Spikes from Model Switching
- Explanation: In open runtimes, dynamically switching to expensive models for simple tasks can inflate costs.
- Fix: Define routing rules based on task complexity. Use cheaper models for search and edit operations. Set budget alerts and hard limits.
-
Assuming Persistence Equals Memory
- Explanation: Storing history in SQLite does not automatically make the agent "remember" past decisions. The agent only sees the current context window.
- Fix: Implement retrieval-augmented generation (RAG) or explicit memory summarization to inject relevant past context into new sessions.
Production Bundle
Action Checklist
Decision Matrix
Use this matrix to select the appropriate runtime based on your operational requirements.
| Scenario | Recommended Approach | Why | Cost Impact |
|---|
| High-Volume Daily Coding | Vertical Integration | Prompt caching reduces latency and cost per session. Polished UX boosts productivity. | Subscription fee; predictable but capped. |
| Strict Budget / Cost Sensitivity | Open Orchestration | Pay-per-use pricing and local models minimize costs. Route simple tasks to cheap models. | Variable; can be optimized to near-zero with local models. |
| Enterprise Compliance / Data Residency | Open Orchestration | Local model support ensures code never leaves the premises. SQLite storage allows full audit control. | Infrastructure costs for local inference hardware. |
| Multi-Model Experimentation | Open Orchestration | Ability to swap providers and compare outputs without changing the agent interface. | API costs scale with usage; no subscription lock-in. |
| Rapid Prototyping / Low Friction | Vertical Integration | Zero-config setup with optimized defaults. Immediate access to state-of-the-art models. | Subscription fee; potential limit friction. |
Configuration Template
Below is a ready-to-use configuration template for an open orchestration runtime. This includes a portable memory file and a TypeScript configuration structure.
AGENTS.md
# Project: Acme Platform
## Tech Stack
- Frontend: React 18, TypeScript, Tailwind CSS
- Backend: Node.js, Express, PostgreSQL
- Testing: Jest, Playwright
## Conventions
- Use functional components with hooks.
- API routes must include error handling middleware.
- Run `npm run test` after every code change.
- Commit messages must follow Conventional Commits.
## Memory Rules
- Do not store sensitive data in code.
- Update this file if conventions change.
- Keep this file concise.
agent.config.ts
import { OpenCodeRuntimeConfig } from '@opencode/runtime';
export const config: OpenCodeRuntimeConfig = {
providers: [
{
id: 'main',
model: 'claude-sonnet-4-20250514',
apiKeyEnv: 'ANTHROPIC_API_KEY',
contextLimit: 200000,
capabilities: ['tool_call', 'json_mode']
},
{
id: 'backup',
model: 'gpt-4o-mini',
apiKeyEnv: 'OPENAI_API_KEY',
contextLimit: 128000,
capabilities: ['tool_call']
}
],
agents: [
{
name: 'developer',
role: 'Implements features and fixes bugs.',
primaryProvider: 'main',
fallbackProviders: ['backup'],
tools: ['read', 'write', 'edit', 'bash', 'grep', 'glob', 'test-runner'],
instructions: 'Follow AGENTS.md conventions. Run tests before finishing.'
}
],
storage: {
type: 'sqlite',
path: './.agent/data.db',
retentionPolicy: 'prune-and-summarize'
},
permissions: {
bash: {
allow: ['npm run *', 'git *', 'docker *'],
deny: ['rm -rf', 'sudo', 'chmod 777']
},
fileWrite: {
allow: ['src/**', 'tests/**', 'docs/**'],
deny: ['**/.env', '**/secrets/**']
}
}
};
Quick Start Guide
Get your coding agent runtime operational in under five minutes.
-
Install the Runtime:
# For Open Orchestration
npm install -g @opencode/cli
# For Vertical Integration
# Follow provider-specific installation instructions
-
Initialize Project:
opencode init
# This creates .opencode/ directory and default configs
-
Configure Memory and Permissions:
- Create
AGENTS.md in the project root with your guidelines.
- Edit
agent.config.ts to set providers, tools, and permission rules.
- Set environment variables for API keys.
-
Launch Agent:
opencode start --agent developer
# The agent will scan the repo, load memory, and await tasks.
-
Verify Operation:
- Run a simple task: "Create a README.md with project description."
- Check tool usage logs and SQLite history to confirm persistence.
- Review output for adherence to
AGENTS.md conventions.