Adapter System
The adapter system provides a pluggable interface for AI backends, allowing Arial to work with different AI providers while maintaining a consistent internal API.
Overview
Adapters abstract the details of communicating with AI backends. Currently, Arial includes a Claude adapter, but the architecture supports adding other providers.
Core Interface
interface Adapter {
id: string
name: string
capabilities: AdapterCapability[]
hasCapabilities(required: AdapterCapability[]): boolean
createExecutionRunner(options: ExecutionRunnerOptions): AgentRunner
runPlanningAgent(options: PlanningAgentOptions): Promise<AgentRunResult>
runSpecReviewAgent(options: AgentRunOptions): Promise<AgentRunResult>
runConflictAgent(options: AgentRunOptions): Promise<AgentRunResult>
}Capabilities
Adapters declare their capabilities:
| Capability | Description |
|---|---|
| `file_read` | Read files from the filesystem |
| `file_write` | Write/edit files |
| `file_search` | Search for files by pattern |
| `bash_execute` | Execute shell commands |
| `web_search` | Search the web |
| `web_fetch` | Fetch web content |
| `code_analysis` | Analyze code structure |
| `git_operations` | Perform Git operations |
Specs can require specific capabilities via frontmatter:
---
requiredCapabilities:
- bash_execute
- file_write
---Adapter Registry
The registry (adapters/registry.ts) manages adapter instantiation:
Loading Configuration
function loadAdapterConfig(): AdapterConfigLoads configuration from environment variables:
ANTHROPIC_API_KEY- API key for ClaudeCLAUDE_LOCAL_CREDENTIALS- Use local Claude credentials
Creating Adapters
function createAdapter(config: AdapterConfig): AdapterFactory function that instantiates the appropriate adapter based on configuration.
Validating Capabilities
function validateCapabilities(
adapter: Adapter,
required: AdapterCapability[]
): Result<void, string>Ensures an adapter meets the requirements for a workstream.
Claude Adapter
Located in adapters/claude/, the Claude adapter implements:
Structure
adapters/claude/
├── index.ts # Adapter implementation
├── agent.ts # Single-call agent execution
├── runner.ts # Long-running execution runner
└── permissions.ts # Dangerous command detectionAgent Types
Single-Call Agents (agent.ts):
- Planning agent - Analyzes specs and suggests workstream organization
- Spec review agent - Evaluates spec completeness
- Conflict agent - Resolves merge conflicts
Execution Runner (runner.ts):
- Long-running agent for workstream execution
- Async with polling for status updates
- Streams tool execution events
Permission System
The Claude adapter includes dangerous command detection (permissions.ts):
- Fork bombs (
:(){:|:&};:) - Recursive deletion (
rm -rf /,rm -rf ~) - Filesystem formatting (
mkfs,dd to /dev/) - Pipe to shell (
curl | sh) - Permission bypasses (
chmod 777 /)
Adding a New Adapter
To add a new AI provider:
Agent Runner Interface
The AgentRunner interface for long-running execution:
interface AgentRunner {
start(): Promise<void>
stop(): void
isRunning(): boolean
wait(): Promise<AgentRunResult>
on(event: 'tool_start', handler: (tool: string) => void): void
on(event: 'tool_end', handler: (tool: string) => void): void
on(event: 'output', handler: (line: string) => void): void
}This abstraction allows different backends to implement execution in their own way while providing a consistent interface to the orchestrator.