Templates¶
Pre-built company templates, personality presets, and template builder.
Schema¶
schema
¶
Template schema: Pydantic models for company templates.
TemplateVariable
pydantic-model
¶
Bases: BaseModel
A user-configurable variable within a template.
Variables declared here are extracted from the template YAML during
the first parsing pass (before Jinja2 rendering). The variables
section must use plain YAML -- no Jinja2 expressions.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
NotBlankStr
|
Variable name (used in |
description |
str
|
Human-readable description for prompts/docs. |
var_type |
Literal['str', 'int', 'float', 'bool']
|
Expected Python type name. |
default |
str | int | float | bool | None
|
Default value ( |
required |
bool
|
Whether the user must provide this value. |
Config:
frozen:Trueextra:forbidallow_inf_nan:False
Fields:
-
name(NotBlankStr) -
description(str) -
var_type(Literal['str', 'int', 'float', 'bool']) -
default(str | int | float | bool | None) -
required(bool)
Validators:
-
_validate_required_has_no_default -
_validate_default_matches_var_type
TemplateAgentConfig
pydantic-model
¶
Bases: BaseModel
Agent definition within a template.
Uses string references and presets rather than full AgentConfig.
The renderer expands these into full agent configuration dicts.
Attributes:
| Name | Type | Description |
|---|---|---|
role |
NotBlankStr
|
Built-in role name (case-insensitive match to role catalog). |
name |
str
|
Agent name (may contain Jinja2 placeholders; empty triggers auto-generation). |
level |
SeniorityLevel
|
Seniority level override. |
model |
NotBlankStr | dict[str, Any]
|
Model tier alias ( |
personality_preset |
NotBlankStr | None
|
Named personality preset from the presets registry. |
personality |
dict[str, Any] | None
|
Inline personality config dict (alternative to
|
department |
NotBlankStr | None
|
Department override ( |
merge_id |
str
|
Stable identity for inheritance merge. When a
template has multiple agents with the same |
remove |
bool
|
Merge directive -- when |
Config:
frozen:Trueextra:forbidallow_inf_nan:False
Fields:
-
role(NotBlankStr) -
name(str) -
level(SeniorityLevel) -
model(NotBlankStr | dict[str, Any]) -
personality_preset(NotBlankStr | None) -
personality(dict[str, Any] | None) -
department(NotBlankStr | None) -
merge_id(str) -
remove(bool)
Validators:
-
_validate_model→model -
_validate_personality_mutual_exclusion
TemplateDepartmentConfig
pydantic-model
¶
Bases: BaseModel
Department definition within a template.
Provides structural information -- department names, budget allocations, the head role, reporting lines, and operational policies.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
NotBlankStr
|
Department name (standard or custom). |
budget_percent |
float
|
Percentage of company budget (0-100). |
head_role |
NotBlankStr | None
|
Role name of the department head. |
head_merge_id |
NotBlankStr | None
|
Optional |
reporting_lines |
tuple[dict[str, str], ...]
|
Reporting line definitions within this department. |
policies |
dict[str, Any] | None
|
Department operational policies. |
ceremony_policy |
dict[str, Any] | None
|
Per-department ceremony policy override
( |
remove |
bool
|
Merge directive -- when |
Config:
frozen:Trueextra:forbidallow_inf_nan:False
Fields:
-
name(NotBlankStr) -
budget_percent(float) -
head_role(NotBlankStr | None) -
head_merge_id(NotBlankStr | None) -
reporting_lines(tuple[dict[str, str], ...]) -
policies(dict[str, Any] | None) -
ceremony_policy(dict[str, Any] | None) -
remove(bool)
Validators:
-
_validate_head_merge_id_requires_head_role
TemplateMetadata
pydantic-model
¶
Bases: BaseModel
Metadata about a company template.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
NotBlankStr
|
Template display name. |
description |
str
|
What this template is for. |
version |
NotBlankStr
|
Semantic version string. |
company_type |
CompanyType
|
Which |
min_agents |
int
|
Minimum number of agents. |
max_agents |
int
|
Maximum number of agents. |
tags |
tuple[NotBlankStr, ...]
|
Categorization tags. |
skill_patterns |
tuple[SkillPattern, ...]
|
Skill interaction patterns this template exhibits. |
Config:
frozen:Trueextra:forbidallow_inf_nan:False
Fields:
-
name(NotBlankStr) -
description(str) -
version(NotBlankStr) -
company_type(CompanyType) -
min_agents(int) -
max_agents(int) -
tags(tuple[NotBlankStr, ...]) -
skill_patterns(tuple[SkillPattern, ...])
Validators:
-
_validate_agent_range -
_validate_unique_skill_patterns
TemplateMemoryConfig
pydantic-model
¶
Bases: BaseModel
Template-level memory configuration overrides.
Attributes:
| Name | Type | Description |
|---|---|---|
embedder |
EmbedderOverrideConfig | None
|
Optional embedder override for the template. |
Config:
frozen:Trueextra:forbidallow_inf_nan:False
Fields:
-
embedder(EmbedderOverrideConfig | None)
CompanyTemplate
pydantic-model
¶
Bases: BaseModel
A complete company template definition.
This is the top-level model parsed from a template YAML file during the first pass (before Jinja2 rendering). It holds metadata, variable declarations, and the structural definitions for agents and departments.
The raw YAML text is stored separately by the loader for the second pass (Jinja2 rendering).
Attributes:
| Name | Type | Description |
|---|---|---|
metadata |
TemplateMetadata
|
Template metadata. |
variables |
tuple[TemplateVariable, ...]
|
Declared template variables (plain YAML, no Jinja2). |
agents |
tuple[TemplateAgentConfig, ...]
|
Template agent definitions. |
departments |
tuple[TemplateDepartmentConfig, ...]
|
Template department definitions. |
workflow |
WorkflowType
|
Workflow name. |
workflow_config |
dict[str, Any]
|
Optional Kanban/Sprint sub-configurations,
validated as |
communication |
NotBlankStr
|
Communication pattern name. |
budget_monthly |
float
|
Default monthly budget in USD (base currency). |
autonomy |
dict[str, Any]
|
Autonomy configuration dict (e.g. |
workflow_handoffs |
tuple[dict[str, Any], ...]
|
Cross-department workflow handoff definitions. |
escalation_paths |
tuple[dict[str, Any], ...]
|
Cross-department escalation path definitions. |
extends |
NotBlankStr | None
|
Parent template name for inheritance ( |
memory |
TemplateMemoryConfig
|
Memory configuration overrides (e.g. embedder settings). |
Config:
frozen:Trueextra:forbidallow_inf_nan:False
Fields:
-
metadata(TemplateMetadata) -
variables(tuple[TemplateVariable, ...]) -
agents(tuple[TemplateAgentConfig, ...]) -
departments(tuple[TemplateDepartmentConfig, ...]) -
workflow(WorkflowType) -
workflow_config(dict[str, Any]) -
communication(NotBlankStr) -
budget_monthly(float) -
autonomy(dict[str, Any]) -
workflow_handoffs(tuple[dict[str, Any], ...]) -
escalation_paths(tuple[dict[str, Any], ...]) -
extends(NotBlankStr | None) -
uses_packs(tuple[NotBlankStr, ...]) -
memory(TemplateMemoryConfig)
Validators:
-
_normalize_extends→extends -
_validate_agent_count_in_range -
_validate_unique_variable_names -
_validate_unique_department_names -
_validate_unique_pack_names
workflow_config
pydantic-field
¶
Optional Kanban/Sprint sub-configurations. Validated as WorkflowConfig on the rendered RootConfig.
Loader¶
loader
¶
Template loading from built-in, user directory, and file-system sources.
Implements a two-pass loading strategy:
- Pass 1: YAML-parse the template to extract metadata and the
variablessection (which uses plain YAML, no Jinja2). - Pass 2: Performed later by the renderer -- Jinja2-renders the raw YAML text, then YAML-parses the result.
Both are returned bundled as a :class:LoadedTemplate dataclass.
TemplateInfo
dataclass
¶
TemplateInfo(
name,
display_name,
description,
source,
tags=(),
skill_patterns=(),
variables=(),
agent_count=0,
department_count=0,
autonomy_level=SEMI,
workflow="agile_kanban",
)
Summary information about an available template.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Template identifier (e.g. |
display_name |
str
|
Human-readable display name. |
description |
str
|
Short description. |
source |
Literal['builtin', 'user']
|
Where the template was found ( |
tags |
tuple[str, ...]
|
Free-form categorization tags for filtering and discovery. |
skill_patterns |
tuple[SkillPattern, ...]
|
Skill design pattern identifiers describing how the template's agents interact. |
variables |
tuple[TemplateVariable, ...]
|
User-configurable |
agent_count |
int
|
Number of agents defined in the template. |
department_count |
int
|
Number of departments defined in the template. |
autonomy_level |
AutonomyLevel
|
Autonomy level governing approval routing. |
workflow |
str
|
Workflow type (e.g. |
LoadedTemplate
dataclass
¶
Result of loading a template: structured data + raw text.
Attributes:
| Name | Type | Description |
|---|---|---|
template |
CompanyTemplate
|
Validated |
raw_yaml |
str
|
Raw YAML text for Pass 2 (Jinja2 rendering). |
source_name |
str
|
Label for error messages. |
list_templates
¶
Return all available templates (user directory + built-in).
User templates override built-in ones. Sorted by name.
Returns:
| Type | Description |
|---|---|
tuple[TemplateInfo, ...]
|
Sorted tuple of :class: |
Source code in src/synthorg/templates/loader.py
list_builtin_templates
¶
Return names of all built-in templates.
Returns:
| Type | Description |
|---|---|
tuple[str, ...]
|
Sorted tuple of built-in template names. |
load_template
¶
Load a template by name: user directory first, then builtins.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Template name (e.g. |
required |
Returns:
| Type | Description |
|---|---|
LoadedTemplate
|
class: |
Raises:
| Type | Description |
|---|---|
TemplateNotFoundError
|
If no template with name exists. |
Source code in src/synthorg/templates/loader.py
load_template_file
¶
Load a template from an explicit file path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path | str
|
Path to the template YAML file. |
required |
Returns:
| Type | Description |
|---|---|
LoadedTemplate
|
class: |
Raises:
| Type | Description |
|---|---|
TemplateNotFoundError
|
If the file does not exist. |
TemplateValidationError
|
If validation fails. |
Source code in src/synthorg/templates/loader.py
Renderer¶
renderer
¶
Template rendering: Jinja2 substitution + validation to RootConfig.
Implements the second pass of the two-pass rendering pipeline:
- Collect user variables + defaults from the
CompanyTemplate. - Render the raw YAML text through a Jinja2
SandboxedEnvironment. - YAML-parse the rendered text.
- Build a
RootConfig-compatible dict and validate.
Template inheritance (extends) is resolved at the renderer level:
each template's Jinja2 is rendered independently, then configs are
merged via :func:~synthorg.templates.merge.merge_template_configs.
render_template
¶
Render a loaded template into a validated RootConfig.
Resolves template inheritance (extends) before validation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loaded
|
LoadedTemplate
|
:class: |
required |
variables
|
dict[str, Any] | None
|
User-supplied variable values (overrides defaults). |
None
|
locales
|
list[str] | None
|
Faker locale codes for auto-name generation.
Defaults to all Latin-script locales when |
None
|
custom_presets
|
Mapping[str, dict[str, Any]] | None
|
Optional mapping of custom preset names to personality config dicts for resolving user-defined presets. |
None
|
Returns:
| Type | Description |
|---|---|
RootConfig
|
Validated, frozen :class: |
Raises:
| Type | Description |
|---|---|
TemplateRenderError
|
If rendering fails. |
TemplateValidationError
|
If validation fails. |
TemplateInheritanceError
|
If inheritance resolution fails. |
Source code in src/synthorg/templates/renderer.py
Merge¶
merge
¶
Template config merging for inheritance.
Provides merge_template_configs which combines a parent config dict
with a child config dict, implementing the merge semantics described in
the template inheritance design.
merge_template_configs
¶
Merge a parent config dict with a child config dict.
Merge strategies by field:
company_name,company_type: child wins if present.config(dict): deep-merged; child keys override parent.agents(list): merged by(role, department, merge_id)key.departments(list): merged byname(case-insensitive).workflow,workflow_handoffs,escalation_paths: child replaces entirely if present; otherwise inherited from parent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
dict[str, Any]
|
Rendered parent config dict (post-Jinja2, pre-defaults). |
required |
child
|
dict[str, Any]
|
Rendered child config dict (post-Jinja2, pre-defaults). |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
New merged config dict. |
Source code in src/synthorg/templates/merge.py
Presets¶
presets
¶
Personality presets and auto-name generation for templates.
Provides comprehensive personality presets with Big Five dimensions and behavioral enums, plus internationally diverse auto-name generation backed by the Faker library.
get_personality_preset
¶
Look up a personality preset by name.
Custom presets are checked first (higher precedence), then builtins.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Preset name (case-insensitive, whitespace-stripped). |
required |
custom_presets
|
Mapping[str, dict[str, Any]] | None
|
Optional mapping of custom preset names to personality config dicts. Keys must be lowercased. |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
A copy of the personality configuration dict. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the preset name is not found in either source. |
Source code in src/synthorg/templates/presets.py
validate_preset_references
¶
Check all agent personality_preset references against known presets.
Returns a tuple of warning messages for unknown presets. Does not raise -- purely advisory for pre-flight validation and template import/export scenarios.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
template
|
CompanyTemplate
|
Parsed template to validate. |
required |
custom_presets
|
Mapping[str, dict[str, Any]] | None
|
Optional custom preset mapping. Keys must be lowercased. |
None
|
Returns:
| Type | Description |
|---|---|
tuple[str, ...]
|
Tuple of warning strings (empty when all presets are known). |
Source code in src/synthorg/templates/presets.py
generate_auto_name
¶
Generate an internationally diverse agent name using Faker.
When seed is provided, a local random.Random deterministically
selects a locale, then a fresh single-locale Faker instance
generates the name -- the cached instance is never mutated.
The role parameter is accepted because callers
(setup_agents.py, renderer.py) pass it positionally;
it does not influence name generation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
role
|
str
|
The agent's role name. Unused since the switch from role-based name pools to Faker. |
required |
seed
|
int | None
|
Optional random seed for deterministic naming. |
None
|
locales
|
list[str] | None
|
Faker locale codes to draw from. Defaults to all
Latin-script locales when |
None
|
Returns:
| Type | Description |
|---|---|
str
|
A generated full name string. |
Source code in src/synthorg/templates/presets.py
Model Requirements¶
model_requirements
¶
Structured model requirements and personality-based model affinity.
Provides :class:ModelRequirement for expressing what kind of LLM an
agent needs (tier, priority, context window, capabilities) and a
preset-keyed affinity mapping that supplies soft defaults when the
template does not specify full requirements.
ModelTier
module-attribute
¶
Model capability tier: large (most capable), medium, small (cheapest).
ModelRequirement
pydantic-model
¶
Bases: BaseModel
Structured model requirement for a template agent.
Describes what an agent needs from an LLM without referencing a specific provider or model. Used by the matching engine to select the best available model.
Attributes:
| Name | Type | Description |
|---|---|---|
tier |
ModelTier
|
Cost/capability tier (large = most capable, small = cheapest). |
priority |
ModelPriority
|
Optimization axis when multiple models match a tier. |
min_context |
int
|
Minimum context window in tokens (0 = no minimum). |
capabilities |
tuple[str, ...]
|
Future-use capability tags (e.g. |
Config:
frozen:Trueextra:forbidallow_inf_nan:False
Fields:
-
tier(ModelTier) -
priority(ModelPriority) -
min_context(int) -
capabilities(tuple[str, ...])
parse_model_requirement
¶
Parse a model requirement from a string tier or dict.
Backward-compatible: accepts the legacy "medium" string format
used by existing template YAML files as well as the new dict format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
str | dict[str, Any]
|
Either a tier string ( |
required |
Returns:
| Type | Description |
|---|---|
ModelRequirement
|
Parsed |
Raises:
| Type | Description |
|---|---|
ValueError
|
If raw is a string not in the valid tier set. |
ValidationError
|
If raw is a dict with invalid fields. |
Source code in src/synthorg/templates/model_requirements.py
resolve_model_requirement
¶
Merge a template tier alias with personality-preset affinity.
The template's tier always wins. Affinity provides priority
and min_context defaults based on the personality preset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tier_str
|
str
|
Tier alias from the template agent config. |
required |
preset_name
|
str | None
|
Optional personality preset name for affinity lookup. |
None
|
Returns:
| Type | Description |
|---|---|
ModelRequirement
|
Resolved |
Source code in src/synthorg/templates/model_requirements.py
Model Matcher¶
model_matcher
¶
Tier-to-model matching engine.
Given a :class:~synthorg.templates.model_requirements.ModelRequirement
and a set of available provider models, selects the best-fit model by
classifying models into cost-based tiers and ranking within each tier
according to the requirement's priority axis.
ModelMatch
pydantic-model
¶
Bases: BaseModel
Result of matching a single agent to a provider model.
Attributes:
| Name | Type | Description |
|---|---|---|
agent_index |
int
|
Index of the agent in the template agent list. |
provider_name |
NotBlankStr
|
Name of the matched provider. |
model_id |
NotBlankStr
|
Matched model identifier. |
tier |
ModelTier
|
Original tier requirement from the template. |
score |
float
|
Match quality score (higher is better, 0-1 range). |
Config:
frozen:Trueextra:forbidallow_inf_nan:False
Fields:
-
agent_index(int) -
provider_name(NotBlankStr) -
model_id(NotBlankStr) -
tier(ModelTier) -
score(float)
match_model
¶
Select the best model for a requirement from available models.
Models are classified into cost-based tiers (thirds by input cost), then ranked within the matching tier according to the requirement's priority axis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
requirement
|
ModelRequirement
|
Structured model requirement. |
required |
available
|
tuple[ProviderModelConfig, ...]
|
Tuple of available models from a single provider. |
required |
Returns:
| Type | Description |
|---|---|
tuple[ProviderModelConfig | None, float]
|
Tuple of (best matching model or None, score 0-1). |
Source code in src/synthorg/templates/model_matcher.py
match_all_agents
¶
Batch-match template agents to provider models.
For each agent, resolves its model requirement and finds the best model across all configured providers.
Note
The agents list is shallow-copied from the caller. Each dict
is shared, so nested mutable values (e.g. personality) are
not copied. This function only reads agent dicts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agents
|
list[dict[str, Any]]
|
List of expanded agent config dicts. Model requirement resolution uses three paths (checked in order):
|
required |
providers
|
dict[str, Any]
|
Provider name -> provider config mapping. Each
provider config must have a |
required |
Returns:
| Type | Description |
|---|---|
list[ModelMatch]
|
List of |
list[ModelMatch]
|
the result when no models exist across any provider or when |
list[ModelMatch]
|
requirement resolution fails. Agents with a viable provider |
list[ModelMatch]
|
but no tier match get a |
list[ModelMatch]
|
first available provider/model as a fallback. |
Source code in src/synthorg/templates/model_matcher.py
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | |
Errors¶
errors
¶
Custom exception hierarchy for template errors.
TemplateError
¶
TemplateNotFoundError
¶
TemplateRenderError
¶
Bases: TemplateError
Raised when template rendering fails.
Covers Jinja2 evaluation errors, missing required variables, YAML parse errors during template processing, and invalid numeric values in rendered output.
Source code in src/synthorg/config/errors.py
TemplateInheritanceError
¶
Bases: TemplateRenderError
Raised when template inheritance fails.
Covers circular inheritance chains, excessive depth, and merge conflicts.
Source code in src/synthorg/config/errors.py
TemplateValidationError
¶
Bases: TemplateError
Raised when a rendered template fails validation.
Attributes:
| Name | Type | Description |
|---|---|---|
field_errors |
Per-field error messages as
|
Source code in src/synthorg/templates/errors.py
__str__
¶
Format validation error with per-field details.