Important
Coding Standards & Compliance
Before contributing to this project, you MUST read CODE.md. It acts as the authoritative source of truth for all coding standards, linting rules, and formatting guidelines. All code—source and tests—must strictly adhere to the patterns defined therein.
The Agent Orchestration Engine is a robust, event-driven platform designed to execute complex, multi-turn AI workflows. Its primary purpose is to act as the runtime environment that coordinates Agents, Skills, and Drivers to transform a user's intent into concrete digital artifacts.
The architecture follows a Core-Periphery philosophy:
- The Core (Engine): Responsible for state management, workflow orchestration, and robust error handling. It is stable, strongly typed, and changes infrequently.
- The Periphery (Content & Config): Defined in YAML and Markdown. This is where the specific behavior, personalities (Agents), and capabilities (Skills) are defined. This layer is highly volatile and designed for rapid iteration.
Understanding the system requires familiarity with its four foundational entities:
Agents are the high-level cognitive workers (e.g., Architect, Planner, Developer).
- Role: They encapsulate domain-specific logic, prompt engineering, and context management.
- Implementation: Agents are TypeScript classes that orchestrate one or more skills to achieve a goal.
- Interaction: They do not execute external tools directly; they delegate execution to Drivers via Skills.
Skills are atomic capabilities or "tools" that an Agent can wield.
- Definition: Skills are defined declaratively in YAML (e.g.,
research.skill.yaml). - Structure: They contain properties specific to the driver
providerwith which they depend on, which may include properties like aprompt_templateand configurationparams. - Purpose: Decouples the intent (what needs to be done) from the mechanism (how it is done).
Drivers are the execution layer for Skills.
- Role: They form the bridge between the Engine and the external world (e.g., an LLM API, a Shell, a Git implementation).
- Abstraction: All Drivers implement the
IDriverinterface, ensuring the Engine remains agnostic to the underlying provider (e.g., executing a prompt via Gemini vs. OpenAI vs. Local Model).
Workflow is the state machine that governs the lifecycle of a task.
- Role: It manages transitions between different execution phases (e.g.,
PLANNING->EXECUTING->VERIFYING). - Mechanism: It operates on a graph-based state model (
WorkflowGraph) and transitions based on Signals returned by States.
The system is layered to promote separation of concerns and testability.
graph TD
User[User / CLI] --> Orch[Orchestrator]
Orch --> Session[Session]
Session --> Workflow[Workflow Engine]
subgraph "Core Domain"
Workflow --> |Manage| State[EngineState]
Workflow --> |Delegate| Brain[Brain (Agent Hub)]
end
subgraph "Agent Layer"
Brain --> Architect[Architect Agent]
Brain --> Planner[Planner Agent]
Brain --> Developer[Developer Agent]
end
subgraph "Execution Layer"
Architect --> |Invoke| SkillRunner
Planner --> |Invoke| SkillRunner
SkillRunner --> |Resolve| DriverReg[Driver Registry]
DriverReg --> |Execute| Driver[Driver (Gemini/Shell)]
end
subgraph "Infrastructure"
Project[Project Config]
FS[FileSystem Service]
Prompt[Prompt Engine]
end
Brain -.-> Project
Brain -.-> Prompt
The Orchestrator is the main entry point. It is responsible for:
- Bootstrapping: deeply initializing the application.
- Context Creation: creating the
SessionandRuntimeHost. - Lifecycle Management: bridging the CLI/UI events with the internal
Workflow.
The system uses a strict Inversion of Control (IoC) pattern managed by ServiceFactory and DIContainer.
- ServiceFactory: Acts as the composition root. It wires together all core services (
Project,FileSystem,Brain). - Injection: Dependencies are injected via constructor injection. This makes every component unit-testable by allowing mocks to be passed during instantiation.
- Rule: Never instantiate complex dependencies (like
new FileSystemService()) inside a class. Always request them in the constructor.
The Brain class serves as the central hub and factory for Agents.
- Purpose: It holds references to all shared infrastructure (
PromptEngine,DriverRegistry) and injects them into specific Agents when created. - Pattern: It implements the Factory Pattern for Agents, ensuring that transient Agent instances are always created with fresh state but shared stateless services.
The execution engine is a Finite State Machine (FSM).
- States: Defined in
src/workflow/states/. Each state (e.g.,PlanningState) represents a distinct phase of operation. - Signals: Transitions are driven by
Signalobjects (e.g.,Signal.NEXT,Signal.FAIL,Signal.REPLAN). Determining the next state is the responsibility of theWorkflowGraph, not the State itself. - Persistence: The
EngineStateis persisted to disk (.ai/state.yml) after every transition. This allows for crash recovery and session resumption.
To add support for a new tool or LLM:
- Create a class implementing
IDriverinsrc/drivers/. - Extend
BaseDriverfor common utility access (Shell, FileSystem). - Implement
isSupported()to check for prerequisites (e.g., binary existence). - Implement
execute()to handle the logic. - Register the driver in
ServiceFactoryor ensure it's loaded viaDriverRegistry.
To create a specialized cognitive worker:
- Create a class in
src/agents/. - Accept
IProject,IWorkspace, andIPromptEnginein the constructor. - Implement a public method (e.g.,
design(),review()) that performs the work. - Register the agent factory in
Brain.registerAgent().
To give an Agent a new capability:
- Create a YAML definition in the
skills/directory (e.g.,my-job.skill.yaml). - Define the
provider(which driver acts on it). - Define
prompt_template,argsor any properties the driver requires. - The
SkillRunnerwill automatically discover and validate this skill on startup.
- Result Pattern: All Driver executions return a
Result<T, Error>object. Never throw exceptions from Drivers; returnResult.fail(). - Global Catch: The
Workflowloop contains a global try/catch block to prevent the process from crashing. - Signal Bubble-Up: Unhandled errors in a State are converted into
Signal.FAIL. TheWorkflowGraphcan be configured to route failure signals to recovery states (e.g.,PlanningState->ErrorRecovery_Planning).
- Interfaces: Preset with
I(e.g.,IProject,IDriver). - Service Classes: Suffix with
Service(e.g.,FileSystemService), unless it's a core domain entity (e.g.,Project). - Agents: Suffix with
Agent(e.g.,PlannerAgent). - Drivers: Suffix with
Driver(e.g.,GeminiDriver). - Files: PascalCase for classes (
Project.ts), camelCase for instances or utilities.
- Unit Tests: Because of DI, every class can be tested in isolation. Mock all
I*interfaces. - Integration Tests: Use
ProjectFixtureto create a temporary, scaffolded file system context. - Mocking: Use
jest.mockfor external modules, but prefer dependency injection of mocks for internal services.
This document is the sole source of architectural truth for the src/engine project. Review it before making structural changes.