Configuration API

Complete API reference for the MARSYS configuration system, including execution, status, communication, and error handling configurations.

The configuration system provides hierarchical settings for all aspects of multi-agent orchestration, with sensible defaults and granular override capabilities.

Core Classes

ExecutionConfig

Main configuration for orchestration execution.

Import

from marsys.coordination.config import ExecutionConfig, StatusConfig, ErrorHandlingConfig

Constructor

ExecutionConfig(
# Timeouts
convergence_timeout: float = 300.0,
branch_timeout: float = 600.0,
agent_acquisition_timeout: float = 240.0,
step_timeout: float = 600.0,
tool_execution_timeout: float = 120.0,
user_interaction_timeout: float = 300.0,
# Convergence behavior
dynamic_convergence_enabled: bool = True,
parent_completes_on_spawn: bool = True,
auto_detect_convergence: bool = True,
# Steering
steering_mode: Literal["auto", "always", "error"] = "error",
# User interaction
user_first: bool = False,
initial_user_msg: Optional[str] = None,
user_interaction: str = "terminal",
# Agent lifecycle management
auto_cleanup_agents: bool = True,
cleanup_scope: Literal["topology_nodes", "used_agents"] = "topology_nodes",
# Response format
response_format: str = "json",
# Sub-configurations
status: StatusConfig = field(default_factory=StatusConfig),
error_handling: Optional[ErrorHandlingConfig] = None
)

Parameters

ParameterTypeDescriptionDefault
convergence_timeoutfloatMax wait at convergence points (seconds)300.0
branch_timeoutfloatOverall branch execution timeout600.0
agent_acquisition_timeoutfloatTimeout for acquiring from pool240.0
step_timeoutfloatIndividual step timeout600.0
tool_execution_timeoutfloatTool call timeout120.0
user_interaction_timeoutfloatUser input timeout300.0
dynamic_convergence_enabledboolEnable runtime convergence detectionTrue
parent_completes_on_spawnboolParent completes when spawning childrenTrue
auto_detect_convergenceboolAutomatic convergence point detectionTrue
steering_modestrRetry guidance mode (auto, always, error)"error"
user_firstboolShow message to user before taskFalse
initial_user_msgstrCustom initial message for userNone
user_interactionstrUser interaction type"terminal"
auto_cleanup_agentsboolAutomatically cleanup agents after runTrue
cleanup_scopestrWhich agents to cleanup"topology_nodes"
response_formatstrResponse format for agent outputs"json"
statusStatusConfigStatus configurationStatusConfig()

Methods

MethodDescriptionReturns
should_apply_steering(is_retry)Determine if steering should be appliedbool

Example

# Production configuration
config = ExecutionConfig(
convergence_timeout=600.0,
step_timeout=300.0,
steering_mode="auto",
status=StatusConfig.from_verbosity(1)
)
# Development configuration
dev_config = ExecutionConfig(
step_timeout=30.0,
steering_mode="always",
status=StatusConfig.from_verbosity(2)
)
# Interactive configuration
interactive_config = ExecutionConfig(
user_first=True,
initial_user_msg="Hello! How can I help?",
user_interaction_timeout=300.0
)
# Long-running workflow (disable auto-cleanup)
long_running_config = ExecutionConfig(
auto_cleanup_agents=False, # Keep agents alive between runs
convergence_timeout=3600.0
)

StatusConfig

Configuration for monitoring and output display.

Import

from marsys.coordination.config import StatusConfig, VerbosityLevel

Constructor

StatusConfig(
enabled: bool = False,
verbosity: Optional[VerbosityLevel] = None,
cli_output: bool = True,
cli_colors: bool = True,
show_thoughts: bool = True,
show_tool_calls: bool = True,
show_timings: bool = True,
aggregation_window_ms: int = 500,
aggregate_parallel: bool = True,
max_events_per_session: int = 10000,
session_cleanup_after_s: int = 3600,
channels: List[str] = field(default_factory=lambda: ["cli"]),
show_agent_prefixes: bool = True,
prefix_width: int = 20,
prefix_alignment: str = "left",
follow_up_timeout: float = 30.0
)

Parameters

ParameterTypeDescriptionDefault
enabledboolEnable status outputFalse
verbosityVerbosityLevelOutput verbosity levelNone
cli_outputboolShow CLI outputTrue
cli_colorsboolUse colored outputTrue
show_thoughtsboolShow agent reasoningTrue
show_tool_callsboolShow tool usageTrue
show_timingsboolShow execution timesTrue
aggregation_window_msintGroup updates within window500
aggregate_parallelboolAggregate parallel updatesTrue
show_agent_prefixesboolShow agent names in outputTrue
prefix_widthintWidth of agent name prefix20
prefix_alignmentstrPrefix alignment"left"

Class Methods

MethodDescriptionReturns
from_verbosity(level)Create from verbosity levelStatusConfig

Instance Methods

MethodDescriptionReturns
should_show_event(event_type)Check if event should be shownbool

VerbosityLevel Enum

class VerbosityLevel(IntEnum):
QUIET = 0 # Minimal output (no thinking, no tool calls)
NORMAL = 1 # Standard output (agent thinking, tool calls with reasoning)
VERBOSE = 2 # Detailed output (all of above + tool arguments, completion timings)

What Shows at Each Level

Event TypeQUIETNORMALVERBOSE
Agent start/completeYesYesYes
Agent thinkingNoYesYes
Tool call nameNoYesYes
Tool reasoningNoYesYes
Tool argumentsNoNoYes
Tool completionNoNoYes
Action type detailsNoNoYes

Example

# Create from verbosity level
status = StatusConfig.from_verbosity(1)
# Custom configuration
custom_status = StatusConfig(
enabled=True,
verbosity=VerbosityLevel.NORMAL,
show_thoughts=True,
show_tool_calls=True,
cli_colors=False # Disable colors for logs
)
# Quiet mode with timing
timing_only = StatusConfig(
enabled=True,
verbosity=VerbosityLevel.QUIET,
show_timings=True
)

CommunicationConfig

Configuration for user interaction and communication channels.

Import

from marsys.coordination.config import CommunicationConfig

Constructor

CommunicationConfig(
use_rich_formatting: bool = True,
theme_name: str = "modern",
prefix_width: int = 20,
show_timestamps: bool = True,
enable_history: bool = True,
history_size: int = 1000,
enable_tab_completion: bool = True,
use_colors: bool = True,
color_depth: str = "truecolor",
input_timeout: Optional[float] = None,
show_typing_indicator: bool = False,
use_enhanced_terminal: bool = True,
fallback_on_error: bool = True
)

Parameters

ParameterTypeDescriptionDefault
use_rich_formattingboolUse rich text formattingTrue
theme_namestrTheme name"modern"
prefix_widthintWidth for agent name prefixes20
show_timestampsboolShow timestamps in interactionsTrue
enable_historyboolKeep interaction historyTrue
history_sizeintMaximum history entries1000
enable_tab_completionboolTab completion for inputsTrue
use_colorsboolEnable colored outputTrue
color_depthstrColor depth setting"truecolor"
input_timeoutfloatTimeout for user inputNone
show_typing_indicatorboolShow typing indicatorFalse
use_enhanced_terminalboolUse enhanced terminal featuresTrue
fallback_on_errorboolFallback to basic mode on errorTrue

Theme Options

  • "modern" - Modern theme with gradients
  • "classic" - Traditional terminal colors
  • "minimal" - Minimal styling

Color Depth Options

  • "truecolor" - 24-bit true color
  • "256" - 256-color palette
  • "16" - 16-color basic palette
  • "none" - No colors

Example

# Rich terminal configuration
rich_config = CommunicationConfig(
use_rich_formatting=True,
theme_name="modern",
use_colors=True,
color_depth="truecolor"
)
# Basic terminal configuration
basic_config = CommunicationConfig(
use_rich_formatting=False,
use_colors=False,
use_enhanced_terminal=False
)
# Web interface configuration
web_config = CommunicationConfig(
use_rich_formatting=False, # Web handles formatting
use_colors=False, # Web handles colors
input_timeout=0 # Non-blocking
)

ErrorHandlingConfig

Advanced error handling and recovery configuration.

Import

from marsys.coordination.config import ErrorHandlingConfig

Constructor

ErrorHandlingConfig(
use_error_classification: bool = True,
notify_on_critical_errors: bool = True,
enable_error_routing: bool = True,
preserve_error_context: bool = True,
auto_retry_on_rate_limits: bool = True,
max_rate_limit_retries: int = 3,
pool_retry_attempts: int = 2,
pool_retry_delay: float = 5.0,
timeout_seconds: float = 300.0,
timeout_retry_enabled: bool = False,
provider_settings: Dict[str, Dict[str, Any]] = field(default_factory=dict)
)

Parameters

ParameterTypeDescriptionDefault
use_error_classificationboolEnable intelligent error classificationTrue
notify_on_critical_errorsboolSend notifications for critical errorsTrue
enable_error_routingboolRoute errors to User node for interventionTrue
preserve_error_contextboolInclude full error context in responsesTrue
auto_retry_on_rate_limitsboolAutomatically retry rate-limited requestsTrue
max_rate_limit_retriesintMaximum retries for rate limit errors3
pool_retry_attemptsintNumber of retries for pool exhaustion2
pool_retry_delayfloatDelay between pool retry attempts5.0
timeout_secondsfloatDefault timeout for operations300.0
timeout_retry_enabledboolRetry after timeoutFalse
provider_settingsDictProvider-specific settings{}

Methods

MethodDescriptionReturns
get_provider_setting(provider, setting, default)Get provider-specific settingAny

Provider Settings Structure

provider_settings = {
"openai": {
"max_retries": 3,
"base_retry_delay": 60,
"insufficient_quota_action": "raise" # "raise", "notify", "fallback"
},
"anthropic": {
"max_retries": 3,
"base_retry_delay": 30,
"insufficient_quota_action": "raise"
}
}

Example

# Aggressive retry strategy
aggressive = ErrorHandlingConfig(
auto_retry_on_rate_limits=True,
max_rate_limit_retries=10,
timeout_retry_enabled=True,
pool_retry_attempts=5
)
# Conservative strategy
conservative = ErrorHandlingConfig(
auto_retry_on_rate_limits=False,
max_rate_limit_retries=0,
timeout_retry_enabled=False,
enable_error_routing=True # Route to user
)
# Custom provider settings
custom = ErrorHandlingConfig(
provider_settings={
"openai": {"max_retries": 5, "base_retry_delay": 30},
"anthropic": {"max_retries": 3, "base_retry_delay": 60}
}
)

Configuration Patterns

Development Configuration

def create_dev_config() -> ExecutionConfig:
"""Development configuration with verbose output."""
return ExecutionConfig(
status=StatusConfig(
enabled=True,
verbosity=VerbosityLevel.VERBOSE,
show_thoughts=True,
show_tool_calls=True
),
step_timeout=30.0,
steering_mode="always"
)

Production Configuration

def create_prod_config() -> ExecutionConfig:
"""Production configuration with minimal output."""
return ExecutionConfig(
status=StatusConfig.from_verbosity(0),
step_timeout=600.0,
convergence_timeout=1200.0,
steering_mode="auto",
error_handling=ErrorHandlingConfig(
auto_retry_on_rate_limits=True,
max_rate_limit_retries=5
)
)

Testing Configuration

def create_test_config() -> ExecutionConfig:
"""Testing configuration with fast failure."""
return ExecutionConfig(
status=StatusConfig.from_verbosity(1),
step_timeout=5.0,
convergence_timeout=10.0,
steering_mode="error"
)

Interactive Configuration

def create_interactive_config() -> ExecutionConfig:
"""User-interactive configuration."""
return ExecutionConfig(
user_first=True,
initial_user_msg="Hello! How can I help?",
user_interaction_timeout=300.0,
status=StatusConfig(
enabled=True,
cli_colors=True,
show_agent_prefixes=True
)
)

Advanced Features

Agent Lifecycle Management

The framework provides automatic agent cleanup to prevent resource leaks and registry collisions.

How It Works

# Default behavior - auto-cleanup enabled
result = await Orchestra.run(
task="Analyze data",
topology=topology,
execution_config=ExecutionConfig(
auto_cleanup_agents=True # Default
)
)
# After run completes:
# 1. Closes model resources (aiohttp sessions, etc.)
# 2. Closes agent-specific resources (browsers, playwright, etc.)
# 3. Unregisters agents from registry (frees names for reuse)

Cleanup Scopes

  • topology_nodes (default): Cleanup all agents defined in the topology
  • used_agents: Cleanup only agents that were actually invoked during execution

When to Disable

# Scenario 1: Multiple runs with same agents
config = ExecutionConfig(auto_cleanup_agents=False)
for task in tasks:
result = await Orchestra.run(task, topology, execution_config=config)
# Agents stay alive, registry intact
# Scenario 2: Long-lived agent pools
pool = await create_browser_agent_pool(num_instances=3, register=False)
AgentRegistry.register_pool(pool)
# Pool manages its own lifecycle
result = await Orchestra.run(
task="Scrape websites",
topology=topology,
execution_config=ExecutionConfig(auto_cleanup_agents=False)
)
await pool.cleanup() # Manual cleanup when done

Benefits

  • No Resource Leaks: aiohttp sessions, browser instances closed deterministically
  • No Registry Collisions: Agent names freed for reuse in subsequent runs
  • No Manual Cleanup: Works out of the box without user intervention
  • Identity-Safe: Uses instance identity checks to prevent race conditions

Low-Level Control

from marsys.agents.registry import AgentRegistry
# Manual cleanup for specific agent
agent = AgentRegistry.get("my_agent")
if agent:
await agent.cleanup() # Close resources
AgentRegistry.unregister_if_same("my_agent", agent) # Identity-safe unregister

Response Format Configuration

The response_format parameter controls how agents structure their outputs and how the system builds agent system prompts.

Available Formats

FormatDescription
jsonDefault JSON format with next_action/action_input structure

How It Works:

  1. System Prompt Building: The format determines how coordination instructions are included in agent system prompts
  2. Response Parsing: Each format has an associated processor for parsing agent responses
  3. Parallel Invocation Examples: Format-specific examples guide agents on correct parallel invocation patterns

Example

# Default JSON format (recommended)
config = ExecutionConfig(response_format="json")
# The JSON format produces system prompts with instructions like:
# --- STRICT JSON OUTPUT FORMAT ---
# Your response MUST be a single, valid JSON object...
# ```json
# {
# "thought": "reasoning...",
# "next_action": "invoke_agent",
# "action_input": [...]
# }
# ```

Custom Formats

To implement a custom format (e.g., XML):

from marsys.coordination.formats import BaseResponseFormat, register_format
class XMLResponseFormat(BaseResponseFormat):
def get_format_name(self) -> str:
return "xml"
def build_format_instructions(self, actions, descriptions) -> str:
# Build XML-specific instructions
...
def get_parallel_invocation_examples(self, context) -> str:
# Provide XML examples for parallel invocation
...
def create_processor(self):
return XMLProcessor()
# Register and use
register_format("xml", XMLResponseFormat)
config = ExecutionConfig(response_format="xml")

Configuration Merging

from dataclasses import replace
# Base configuration
base_config = ExecutionConfig(
step_timeout=300.0,
status=StatusConfig.from_verbosity(1)
)
# Override specific settings
custom_config = replace(
base_config,
step_timeout=60.0,
steering_mode="always"
)

Dynamic Configuration

def get_config_for_task(task_type: str) -> ExecutionConfig:
"""Get configuration based on task type."""
configs = {
"research": ExecutionConfig(
convergence_timeout=600.0,
max_steps=200
),
"quick_query": ExecutionConfig(
step_timeout=30.0,
max_steps=10
)
}
return configs.get(task_type, ExecutionConfig())

Environment Variable Integration

import os
from dotenv import load_dotenv
load_dotenv()
config = ExecutionConfig(
step_timeout=float(os.getenv("MARSYS_TIMEOUT", "300")),
status=StatusConfig(
verbosity=int(os.getenv("MARSYS_VERBOSITY", "1"))
)
)

Configuration Lifecycle

Configuration Priority

  1. Explicit parameters (highest priority)
  2. Configuration objects
  3. Environment variables
  4. Default values (lowest priority)

Runtime Updates

# Start with base config
orchestra = Orchestra(execution_config=base_config)
# Override for specific run
result = await orchestra.execute(
task=task,
topology=topology,
execution_config=ExecutionConfig(
step_timeout=60.0 # Override just this setting
)
)

Best Practices

Do

  • Start with defaults and override as needed
  • Use verbosity levels appropriately
  • Configure timeouts based on expected task duration
  • Enable error routing for critical workflows
  • Use provider-specific settings for API optimization

Don't

  • Set timeouts too short (< 10 seconds)
  • Disable all retries in production
  • Use VERBOSE mode in production
  • Ignore error handling configuration
  • Mix incompatible settings

Pro Tip

Use StatusConfig.from_verbosity() for quick setup. It automatically configures all related settings appropriately for the chosen verbosity level.

Configuration Validation

Always validate custom configurations, especially when merging multiple sources. Invalid configurations can cause runtime failures.