How the SDK Works
The SDK is compiler-first: it transforms Python code into validated YAML definitions for Platform Core.
Core Function
SDK Purpose: Create and validate Agent Definitions locally before platform submission, with an optional runtime wrapper for ATOMIC handlers.
It does not decide execution, state, or billing?Platform Core does.
Compilation Pipeline
Python Code → Builders → Entities → Validation → YAMLStep 1: Define with Builders
Builders provide a fluent API for constructing definitions:
from ainalyn import AgentBuilder, WorkflowBuilder, NodeBuilder
workflow = (
WorkflowBuilder("process")
.description("Main processing workflow")
.add_node(
NodeBuilder("task")
.description("Process data")
.uses_prompt("task-prompt")
.build()
)
.entry_node("task")
.build()
)
agent = (
AgentBuilder("my-agent")
.version("1.0.0")
.description("Processes user data")
.add_workflow(workflow)
.build()
)Builders perform immediate validation:
- Name format checking
- Required field validation
- Duplicate detection
- Reference integrity
Step 2: Validate Definition
from ainalyn.api import validate
result = validate(agent)Validation performs:
-
Schema Validation
- Structural correctness
- Type checking
- Required fields present
-
Static Analysis
- Workflow is DAG (no cycles)
- All nodes reachable from entry
- All references resolve
- No orphaned resources
if result.is_valid:
print("Validation passed")
else:
for error in result.errors:
print(f"{error.severity}: {error.code} - {error.message}")Step 3: Export to YAML
from ainalyn.api import export_yaml
yaml_output = export_yaml(agent)
print(yaml_output)Output format:
# Ainalyn Agent Definition
# This file is a description submitted to Platform Core for review.
# It does NOT execute by itself. Execution is handled by Platform Core.
name: my-agent
version: 1.0.0
description: Processes user data
workflows:
- name: process
description: Main processing workflow
entry_node: task
nodes:
- name: task
description: Process data
type: prompt
reference: task-promptWhat the SDK Validates
Builder-Time Validation
Immediate checks when calling .build():
- Name format:
[A-Za-z0-9_-]+ - Version format:
MAJOR.MINOR.PATCH - Required fields present
- No duplicate names in scope
- Referenced resources exist
Example error:
AgentBuilder("Invalid Name") # Raises InvalidFormatError
# InvalidFormatError: Invalid value for 'name': 'Invalid Name'.
# Agent name must contain only letters, numbers, hyphens, and underscores.Compile-Time Validation
Checks performed by validate():
Schema Validation
- All required fields present
- Field types correct
- Values within constraints
Review Gates
- Contract completeness (goal, completion criteria, schemas)
- No shadow runtime patterns (loops, retries, billing signals)
- Result sovereignty (workflow-determined outcomes)
- Billing hint only (no price decisions)
- EIP dependency declarations
Static Analysis
-
Cycle Detection
# This fails validation: # node-a → node-b → node-c → node-a (cycle!)Error:
CyclicDependencyError: Workflow contains a cycle: node-a → node-b → node-c → node-a -
Reachability Analysis
# This fails if node-orphan is unreachable:Error:
UnreachableNodeError: Node 'node-orphan' is unreachable from entry node 'start' -
Reference Resolution
# This fails if prompt doesn't exist: NodeBuilder("task").uses_prompt("undefined-prompt")Error:
ReferenceError: 'task' references undefined prompt 'undefined-prompt'
What the SDK Does NOT Do
The SDK does not decide execution. It cannot and does not:
- Execute workflows
- Make network requests
- Call tools or modules
- Calculate costs
- Authenticate users
- Handle retries
- Manage state
These are Platform Core responsibilities.
Complete Workflow
Developer Side (SDK)
# 1. Define agent
agent = AgentBuilder("processor").version("1.0.0")...build()
# 2. Validate locally
result = validate(agent)
if not result.is_valid:
for error in result.errors:
print(error)
exit(1)
# 3. Export to YAML
yaml_content = export_yaml(agent)
# 4. Write to file
with open("agent.yaml", "w") as f:
f.write(yaml_content)
# 5. Submit to platform (outside SDK scope)Platform Side (NOT SDK)
- Receive YAML submission
- Apply governance policies
- Review definition
- Approve or reject
- Make available in marketplace
- Handle execution requests
- Allocate resources
- Execute workflows
- Return results
- Calculate costs
- Process payments
Validation Result Structure
from ainalyn.api import validate
result = validate(agent)
# Properties
result.is_valid # bool: No errors
result.has_warnings # bool: Has warnings
result.errors # tuple[ValidationError, ...]
# ValidationError structure
for error in result.errors:
error.code # str: Error code (e.g., "CYCLIC_DEPENDENCY")
error.message # str: Human-readable message
error.severity # Severity: ERROR or WARNING
error.path # str: Where the issue occurredError Codes
Build-Time Errors
| Code | Description | Example |
|---|---|---|
MISSING_FIELD | Required field not provided | Missing version |
INVALID_FORMAT | Value doesn’t match pattern | Invalid name format |
DUPLICATE_NAME | Name used multiple times in scope | Two nodes named “task” |
REFERENCE_ERROR | Resource reference not found | Node uses undefined prompt |
EMPTY_COLLECTION | Required collection is empty | Agent with no workflows |
Validation Errors
| Code | Description | Example |
|---|---|---|
CYCLIC_DEPENDENCY | Workflow contains cycle | node-a → node-b → node-a |
UNREACHABLE_NODE | Node not reachable from entry | Orphaned node |
SCHEMA_VIOLATION | Definition doesn’t match schema | Invalid field type |
API Functions
validate()
from ainalyn.api import validate
from ainalyn.domain.entities import AgentDefinition
def validate(definition: AgentDefinition) -> ValidationResult:
"""
Validate agent definition structure and logic.
Parameters:
definition: AgentDefinition to validate
Returns:
ValidationResult with errors and warnings
Validation includes:
- Schema validation
- Static analysis (cycles, reachability)
- Reference integrity
"""export_yaml()
from ainalyn.api import export_yaml
from ainalyn.domain.entities import AgentDefinition
def export_yaml(definition: AgentDefinition) -> str:
"""
Export agent definition to YAML string.
Parameters:
definition: AgentDefinition to export
Returns:
YAML-formatted string with header comments
Note: Does NOT validate before export.
Use compile_agent() for validation + export.
"""compile_agent()
from ainalyn.api import compile_agent
from ainalyn.domain.entities import AgentDefinition
from pathlib import Path
def compile_agent(
definition: AgentDefinition,
output_path: Path | None = None
) -> CompilationResult:
"""
Validate and export agent definition.
Parameters:
definition: AgentDefinition to compile
output_path: Optional path to write YAML file
Returns:
CompilationResult with:
- validation_result: ValidationResult
- yaml_content: str | None (if successful)
- output_path: Path | None (if written)
- is_successful: bool
Workflow:
1. Validate definition
2. Export to YAML (only if valid)
3. Write to file (if output_path provided)
"""Development Flow
Recommended Approach
from ainalyn import AgentBuilder
from ainalyn.api import compile_agent
from pathlib import Path
# 1. Build definition
agent = (
AgentBuilder("my-agent")
.version("1.0.0")
.description("Agent description")
.add_workflow(workflow)
.build() # ← Immediate validation
)
# 2. Compile with validation
result = compile_agent(agent, Path("output.yaml"))
# 3. Check result
if result.is_successful:
print(f"Success! Written to {result.output_path}")
else:
print("Compilation failed:")
for error in result.validation_result.errors:
print(f" {error.code}: {error.message}")Quick Validation
from ainalyn.api import validate
result = validate(agent)
if result.is_valid:
print("Valid definition")
else:
for error in result.errors:
print(f"{error.severity}: {error.message}")Common Patterns
Iterative Development
# Build incrementally
agent = AgentBuilder("test-agent").version("1.0.0")
# Add components
agent = agent.description("Test agent")
agent = agent.add_workflow(workflow)
# Validate at each step
try:
built_agent = agent.build()
result = validate(built_agent)
if result.is_valid:
print("Ready to export")
except DomainError as e:
print(f"Build error: {e}")Error Handling
from ainalyn.domain.errors import (
MissingFieldError,
InvalidFormatError,
ReferenceError,
DomainError
)
try:
agent = AgentBuilder("my-agent").build()
except MissingFieldError as e:
print(f"Missing: {e.field_name}")
except InvalidFormatError as e:
print(f"Invalid {e.field_name}: {e.value}")
except ReferenceError as e:
print(f"Undefined {e.resource_type}: {e.reference}")
except DomainError as e:
print(f"Error: {e.message}")Best Practices
1. Validate Early and Often
# Validate after each major change
workflow = WorkflowBuilder(...).build() # Validates workflow
agent = AgentBuilder(...).build() # Validates agent
result = validate(agent) # Full validation2. Use compile_agent() for Production
# Combines validation + export
result = compile_agent(agent, Path("agent.yaml"))
if not result.is_successful:
# Handle errors before submission
pass3. Handle Errors Specifically
# Catch specific error types
try:
agent = builder.build()
except InvalidFormatError as e:
# Fix name format issues
pass
except ReferenceError as e:
# Add missing resources
pass4. Review Generated YAML
# Always inspect output
yaml = export_yaml(agent)
print(yaml) # Ensure it matches intentNext Steps
- What You Control - SDK vs Platform boundaries
- Building Your Agent - Design patterns
- Validation Guide - Detailed validation rules
- Error Handling - Complete error reference