π«π· Version franΓ§aise
YAML, Builders and CrewFactory
See also: Bootstrap Β· YAML schema reference Β· Back to the index
Fluent Builders
The three main entities are built via fluent builders defined in the Domain layer:
AgentBuilder(Orkeon.Domain.Agent): configures role, goal, backstory, tools, execution constraints, prompt templates, tool access policyCrewTaskBuilder(Orkeon.Domain.Task): configures description, expected output, priority, dependencies, output JSON schema, async mode, human interventionCrewBuilder(Orkeon.Domain.Crew): configures goal, process type, agents, tasks, planning, memory, callbacks, dynamic agents
Each builder internally delegates to the factory methods Agent.Create(), CrewTask.Create(), Crew.Create() and throws a BuilderValidationException if the required fields are missing.
YAML configuration
Orkeon supports full crew configuration via YAML. The YamlCrewDefinitionLoader loader (Orkeon.Infrastructure.Configuration) converts YAML files into domain objects.
Configuration schema (abridged)
The YAML structure follows this schema:
# CrewYamlConfig schema β most-used keys (see docs/architecture/yaml-schema.md for the full surface:
# crew-level llm:/rag:/links:, agent knowledge:, task tools:/deliverable:/llm_override:, llm thinking/responseFormat/cache)
name: string # Crew identifier
goal: string # Goal (required)
process: string # "sequential" | "hierarchical" | "parallel" | "consensual" | "graph" | "autonomous"
verbose: bool # default: false
memory: bool # default: false
memoryProvider: string # "InMemory" | "Redis" | "Sqlite" | "ChromaDb" | "Pinecone" | "LanceDb"
planning: bool # default: false
managerAgent: string # Required when process = "hierarchical"
agents:
<agent_id>: # Key = unique agent identifier
role: string # Agent role (required)
goal: string # Agent's personal goal (required)
backstory: string # Context and expertise (multi-line recommended)
tools: [string] # Names of tools registered in IToolRegistry
allowDelegation: bool # default: true β allows delegation to other agents
maxIter: int # default: 20 β maximum iterations before timeout
maxRpm: int # default: 10 β requests per minute (rate limiting)
verbose: bool # default: false β detailed logs for this agent
llm:
model: string # LLM model ("gpt-4", "claude-3-opus", etc.)
temperature: float # Creativity (0.0-1.0)
maxTokens: int # Output token limit
tasks:
<task_id>: # Key = unique task identifier
description: string # Detailed task description (required)
expectedOutput: string # Expected output format/content (required)
agent: string # ID of the agent assigned to the task
dependencies: [string] # IDs of prerequisite tasks (guarantees ordering)
asyncExecution: bool # default: false β RECORDED, honoured by no mode yet (use process: parallel)
humanInput: bool # default: false β requests human intervention
context: {key: value} # Additional context data
circuitBreaker: # FSM / circuit breaker configuration (optional)
preset: string # "strict" | "permissive" | "default"
maxTransitions: int # Max transitions before trip
stateTimeoutSeconds: int # Per-state timeout (seconds)
maxStateVisits: int # Max visits of the same state (cycles)
maxTotalDurationSeconds: int # Max total duration (seconds)
useDegradedMode: bool # true = Degraded, false = exception
maxRetries: int # Retries after failure
maxToolCallsPerRound: int # Max tool calls per round
maxValidationRetries: int # Max validation loops
guardrails: # Task-level guardrails (optional) β same shape as at agent level
preset: string # "analysis" | "strict" | "creative"
header: string
rules: [string]
toolRules:
<tool_name>: [string]
The circuitBreaker block can also be used at the root level of the YAML (default for all tasks). See FSM Orchestration for the full details.
Guardrails may be declared on an agent (all its tasks) and/or on a task (that task only). When both exist, both apply β agent rules first, then the task's β injected into the executing agent's system prompt. See YAML schema β Guardrails configuration.
When process: "graph" is used, an additional graphConfig block configures the state graph engine:
graphConfig:
maxRetryCycles: int # default: 2 β retry cycles for failed tasks
circuitBreakerPreset: string # "strict" | "permissive" | "default"
maxTransitions: int # Overrides the preset
maxStateVisits: int # Cycle detection (overrides the preset)
maxTotalDurationSeconds: int # Total duration in seconds (overrides the preset)
See Graph Orchestration for the full details.
YAML models
The YAML models include:
CrewYamlConfig(complete definition of a crew)AgentYamlConfig(role, goal, backstory, tools, limits)TaskYamlConfig(description, expected output, dependencies, circuit breaker)LlmYamlConfig(model, temperature, max tokens)CircuitBreakerYamlConfig(preset, thresholds, guards β see FSM Orchestration)GraphYamlConfig(maxRetryCycles, circuitBreakerPreset, overrides β see Graph Orchestration)
There is no framework-level "predefined configuration" object: a host composes its own settings through AddOrkeonInfrastructure / AddOrkeonApplication and its appsettings.json.
Loading modes
The YamlCrewDefinitionLoader loader supports two modes:
Single-file mode: contains agents and tasks in a single file
// loader: ICrewDefinitionLoader (YamlCrewDefinitionLoader implementation) resolved via DI
var config = await loader.LoadFromFileAsync("crews/research_crew.yaml", ct);
var crew = await crewFactory.CreateFromConfigAsync(config, ct);
Multi-file mode: separate agents.yaml, tasks.yaml, and crew.yaml in a directory
var config = await loader.LoadFromDirectoryAsync("crews/research/", ct);
var crew = await crewFactory.CreateFromConfigAsync(config, ct);
// Automatically loads: crew.yaml, agents.yaml, tasks.yaml
Per-entity directory mode: crew settings in config.yaml
(or crew.yaml), one agent per file under agents/, one task per file under tasks/.
The file-name stem is the entity id β i.e. the dictionary key used in the flat formats.
LoadFromDirectoryAsync selects this mode automatically as soon as an agents/ or tasks/
sub-directory is present.
crews/research/
βββ config.yaml # crew settings (name, goal, process, llm, β¦) β or crew.yaml
βββ agents/
β βββ researcher.yaml # β agent id "researcher"
β βββ writer.yaml # β agent id "writer"
βββ tasks/
βββ collect.yaml # β task id "collect"
βββ report.yaml # β task id "report"
// Same call: the layout is detected automatically.
var config = await loader.LoadFromDirectoryAsync("crews/research/", ct);
var crew = await crewFactory.CreateFromConfigAsync(config, ct);
Notes:
config.yamlis preferred overcrew.yamlwhen both are present; a missing settings file raisesFileNotFoundException(parity with flat mode).- Empty or absent
agents//tasks/folders simply yield no agents/tasks β the usual "at least one agent/task" validation error then surfaces vialoader.Validate(config). - Mixing the two layouts (e.g. both
agents.yamland anagents/directory) raisesInvalidOperationExceptionrather than picking a silent precedence. - Limitation: YAML anchors cannot span files β each file is preprocessed independently (this was already true across the three flat files).
On the CLI side, orkeon run <directory> accepts these directories directly
β see
Three ways to run Orkeon.
CrewFactory β From YAML to domain objects
The creation pipeline transforms the YAML configuration into operational domain objects via CrewFactory (Orkeon.Infrastructure.Configuration), which implements ICrewFactory (Orkeon.Application.Interfaces).
Creation pipeline
- YAML β CrewYamlConfig: YAML deserialization into configuration models
- CrewYamlConfig β CrewConfiguration: Mapping of the YAML models to the application DTOs with basic validation
- Tool resolution: Tool names (strings) resolved via
IToolRegistry.GetToolByNameAsync(name)intoIBaseToolinstances - Agent creation:
Agentinstances built withAgentBuilderand resolved tools - Task creation:
CrewTaskinstances built withCrewTaskBuilderand validated dependencies - Dependency validation: Circular dependency detection and order validation
- Crew creation:
Crewinstance built withCrewBuilder, process strategy applied - Persistence: Agents, Tasks, Crew persisted in the repositories (optional)
Entry points
CrewFactory exposes three public methods:
/// <summary>
/// Creates a Crew from an already deserialized CrewConfiguration.
/// Used after LoadFromFile/LoadFromDirectory.
/// </summary>
public async Task<Crew> CreateFromConfigAsync(
CrewConfiguration config,
CancellationToken ct = default)
{
// Validates the config, resolves the tools, creates agents/tasks/crew
}
/// <summary>
/// Creates a Crew directly from a YAML file.
/// Single-file mode (agents + tasks in the same file).
/// </summary>
public async Task<Crew> CreateFromFileAsync(
string yamlFilePath,
CancellationToken ct = default)
{
// Deserializes YAML β CrewYamlConfig β calls CreateFromConfigAsync
}
/// <summary>
/// Creates a Crew from a YAML directory.
/// Multi-file mode: crew.yaml + agents.yaml + tasks.yaml
/// </summary>
public async Task<Crew> CreateFromDirectoryAsync(
string directoryPath,
CancellationToken ct = default)
{
// Loads agents.yaml, tasks.yaml, crew.yaml β calls CreateFromConfigAsync
}
Tool resolution
The tool names specified in agents[].tools[] are resolved at construction time via IToolRegistry.GetToolByNameAsync(toolName). What happens when a tool is missing depends on CrewFactoryOptions.StrictTools (config key Orkeon:CrewFactory:StrictTools): the runners (orkeon run) default it to true and CrewFactory then throws with the list of missing tools; the library default is false β the tool is skipped with a Warning log and the crew loads without it.
Example error (strict mode):
Crew configuration references unknown tool(s): web_scraper, custom_analyzer. Available tools: file_read, file_write, http_api, ...