kaboo_workflows.config¶
Config schema, loaders, interpolation, and infrastructure resolution.
kaboo_workflows.config ¶
YAML configuration loading, validation, and resolution.
ResolvedConfig
dataclass
¶
ResolvedConfig(
*,
agents=dict(),
orchestrators=dict(),
entry,
mcp_lifecycle=MCPLifecycle(),
app_config=None,
)
Fully resolved config — lifecycle started, agents ready.
After calling :func:~kaboo_workflows.config.loaders.load, use
:meth:wire_event_queue to set up event streaming::
resolved = load("config.yaml")
event_queue = resolved.wire_event_queue()
wire_event_queue ¶
wire_event_queue(*, session_id=None, tool_labels=None)
Wire all agents and orchestrators for event streaming.
This is the recommended way to set up event streaming. It:
- Builds a :class:
~kaboo_workflows.types.SessionManifestfrom the resolved runtime objects. - Auto-resolves stream groups from the original AppConfig so every agent is attributed to a hierarchical dot-path group.
- Collects tool labels from MCP clients and agents in the original AppConfig (agent-level overrides MCP-level).
- Wires every agent (and orchestrator) with an
:class:
~kaboo_workflows.hooks.EventPublishervia :func:~kaboo_workflows.wire.make_event_queue. - Emits a SESSION_START event carrying the manifest as the first event on the queue.
.. warning::
This **mutates** the agents and orchestrators stored on this
instance by adding hooks and overwriting ``callback_handler``.
Call it only once per ``ResolvedConfig`` instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str | None
|
Optional session ID to embed in events. |
None
|
tool_labels
|
dict[str, str] | None
|
Optional runtime tool name → display label mapping. These take highest priority, overriding both agent-level and MCP-client-level labels from YAML config. |
None
|
Returns:
| Type | Description |
|---|---|
EventQueue
|
A ready-to-use :class: |
EventQueue
|
SESSION_START already on it. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the entry node cannot be resolved by object identity. |
Source code in src/kaboo_workflows/config/resolvers/config.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | |
ResolvedInfra
dataclass
¶
ResolvedInfra(
models=dict(),
clients=dict(),
mcp_lifecycle=MCPLifecycle(),
)
Infrastructure resolved from config — lifecycle NOT started.
This is the pure result of :func:resolve_infra. Lifecycle is cold,
agents are not yet created.
Session managers are NOT stored here — they are built per agent and per
orchestration at session time, from config.session_manager (the global
def) plus effective_session_id computed by load_session.
Use :func:~kaboo_workflows.config.loaders.load for a fully
activated system, or manually::
infra = resolve_infra(config)
infra.mcp_lifecycle.start()
agents = resolve_agents(agent_defs=config.agents, ...)
AgentDef ¶
Bases: BaseModel
Top-level agent definition.
All agents are defined flat under the agents: section.
Multi-agent orchestration is configured separately in the orchestrations: section.
tools accepts spec strings:
"module.path:function_name"— single function from module"module.path"— all@toolfunctions in module"./path/to/file.py:function_name"— single function from file"./path/to/file.py"— all@toolfunctions in file"./path/to/dir/"— all@toolfunctions in directory
hooks accepts import-path strings ("module.path:ClassName" or
"./file.py:ClassName") or inline :class:HookDef objects with
explicit type + optional params.
type
class-attribute
instance-attribute
¶
type = None
Custom agent factory import path.
Format: module.path:ClassName or ./file.py:ClassName.
When set, the factory is called instead of strands.Agent() directly.
The agent_kwargs dict is spread as **kwargs to this factory.
agent_kwargs
class-attribute
instance-attribute
¶
agent_kwargs = Field(default_factory=dict)
Additional keyword arguments passed to strands.Agent() or custom factory.
Valid Agent parameters: messages, callback_handler, record_direct_tool_call, trace_attributes, state, plugins, structured_output_prompt, structured_output_model, tool_executor, retry_strategy, concurrent_invocation_mode, load_tools_from_directory.
Warning: Use at your own risk — no schema-level validation is performed. Agent.init has 24 explicit parameters and no **kwargs; any invalid key will raise TypeError at construction time.
AppConfig ¶
Bases: BaseModel
Root YAML configuration.
Orchestrations are defined as a dict of named orchestration blocks that can reference each other for arbitrary nesting.
version
class-attribute
instance-attribute
¶
version = '1'
Schema version — omit to use the default "1".
history
class-attribute
instance-attribute
¶
history = False
Global default for per-agent history:.
Applies to any agent that does not set its own history:. Defaults to
False so sub-agents are stateless per run unless opted in. The entry
agent is unaffected — its transcript is always the CopilotKit chat.
ConversationManagerDef ¶
Bases: BaseModel
Conversation manager configuration.
type must be a module.path:ClassName import path or a
./file.py:ClassName file-based import path. The resolver raises
ValueError if there is no colon separator. params are forwarded
as constructor kwargs.
Built-in strands classes:
strands.agent:SlidingWindowConversationManagerstrands.agent:SummarizingConversationManagerstrands.agent:NullConversationManager
DelegateConnectionDef ¶
Bases: BaseModel
A delegation connection: orchestrator calls agent as a tool.
DelegateOrchestrationDef ¶
Bases: BaseModel
Delegate mode: entry agent calls other agents as tools.
A new Agent is constructed from the entry_name agent's blueprint
(model, system_prompt, hooks, tools, etc.) with delegate tools added for
each connection. The original agent is never mutated.
Entry point is explicit via entry_name (consistent with swarm/graph).
agent_kwargs is merged over the entry agent's agent_kwargs —
orchestration values win on conflict, unset keys are inherited.
agent_kwargs
class-attribute
instance-attribute
¶
agent_kwargs = Field(default_factory=dict)
Merged over the entry agent's agent_kwargs (orchestration wins).
Common uses: system_prompt, callback_handler, conversation_manager.
reference_fields
classmethod
¶
reference_fields()
Return mapping of JSON paths to reference types for name sanitization.
Source code in src/kaboo_workflows/config/schema.py
270 271 272 273 274 275 276 | |
GraphEdgeDef ¶
Bases: BaseModel
An edge in a graph orchestration.
GraphOrchestrationDef ¶
Bases: BaseModel
Graph mode: DAG-based orchestration with conditional edges.
Agents execute in parallel batches based on dependency order. Uses strands Graph under the hood.
chat_output names the node whose streamed text becomes the assistant
reply when the graph is a first-class AG-UI entry. When omitted, the
adapter streams the sole terminal node (a node with no outgoing edges) if
there is exactly one, otherwise it emits the final node's text on
completion.
node_ids ¶
node_ids()
Return every node id referenced by this graph (entry + edge ends).
Source code in src/kaboo_workflows/config/schema.py
354 355 356 357 358 359 360 | |
terminal_nodes ¶
terminal_nodes()
Return nodes with no outgoing edge (candidate chat-output nodes).
Source code in src/kaboo_workflows/config/schema.py
362 363 364 365 | |
reference_fields
classmethod
¶
reference_fields()
Return mapping of JSON paths to reference types for name sanitization.
Source code in src/kaboo_workflows/config/schema.py
377 378 379 380 381 382 383 384 385 | |
HookDef ¶
Bases: BaseModel
Hook provider reference.
type must be a module.path:ClassName import path or a
./file.py:ClassName file-based import path. The resolver raises
ValueError if there is no colon separator. params are forwarded
as constructor kwargs.
MCPClientDef ¶
Bases: BaseModel
MCP client connection definition.
Exactly one of server, url, or command must be set.
params are forwarded to strands MCPClient (e.g., startup_timeout,
tool_filters, prefix). transport_options are forwarded to the
transport factory (e.g., headers, auth, timeout, http_client).
MCPServerDef ¶
Bases: BaseModel
MCP server definition.
ModelDef ¶
Bases: BaseModel
LLM model configuration.
SessionManagerDef ¶
Bases: BaseModel
Session manager configuration.
Built-in providers: "file", "s3", "agentcore".
For a custom class, set type to an import path
("module.path:ClassName"). The class must be a subclass of
strands.session.SessionManager. When type is set, provider
is ignored.
Session ID resolution order
- Runtime override (e.g., HTTP session header)
params.session_id- Random UUID (fresh session per CLI run)
SwarmOrchestrationDef ¶
Bases: BaseModel
Swarm mode: collaborative handoffs between peer agents.
Agents transfer control to each other via handoff_to_agent tool. Uses strands Swarm under the hood.
chat_output names the member agent whose streamed text becomes the
assistant reply when the swarm is a first-class AG-UI entry. When omitted,
the adapter emits the final active node's text once the run completes.
reference_fields
classmethod
¶
reference_fields()
Return mapping of JSON paths to reference types for name sanitization.
Source code in src/kaboo_workflows/config/schema.py
311 312 313 314 315 316 317 318 | |
interpolate ¶
interpolate(raw, *, variables=None, env=None)
Interpolate ${VAR} and ${VAR:-default} references in a YAML config dict.
Lookup order: variables dict -> env dict -> default value -> raise error.
Uses a two-pass strategy to resolve cross-variable references inside the
vars: block before interpolating the rest of the config. Pass 1
resolves each var against env only; Pass 2 resolves each var sequentially
against the pass-1 results so chains like B: "${A}y" work correctly.
Any ${VAR} pattern still present after two passes indicates a circular
or undefined reference and raises ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
dict[str, Any]
|
Raw parsed YAML dict (will not be mutated — returns a new dict). |
required |
variables
|
dict[str, Any] | None
|
User-defined variables (from the |
None
|
env
|
dict[str, str] | None
|
Environment variables (defaults to |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
New dict with all string values interpolated. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a variable is referenced but not found and has no default, or if a circular reference is detected in the vars block. |
Source code in src/kaboo_workflows/config/interpolation.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | |
strip_anchors ¶
strip_anchors(raw)
Remove x-* keys (YAML anchor scratch pads) from the top level.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
dict[str, Any]
|
Raw parsed YAML dict. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
New dict without top-level |
Source code in src/kaboo_workflows/config/interpolation.py
70 71 72 73 74 75 76 77 78 79 | |
load ¶
load(config)
Load config from file(s) or YAML string(s) and resolve to live objects.
This is the main entry point for zero-code usage.
Accepts a single source or a list of sources. Each source is either
a file path (str or Path) or a raw YAML string. File paths
are detected by checking if the path exists on disk; anything else
is parsed as inline YAML.
Pipeline:¶
- Parse each source (file read or inline YAML)
- Per-source: strip anchors, interpolate variables
- Sanitize collection keys (spaces/special chars -> underscores)
- Merge sources (if multiple), detect duplicate names
- Validate against schema (Pydantic)
- Resolve infrastructure (models, MCP — pure; no session manager)
- Start MCP servers (so clients can connect)
- Create agents (Agent.init auto-starts MCP clients)
- Wire orchestration / entry point
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
ConfigInput | list[ConfigInput]
|
File path, raw YAML string, or list of either. |
required |
Returns:
| Type | Description |
|---|---|
ResolvedConfig
|
ResolvedConfig with agents, entry (callable), and mcp_lifecycle. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
Config file doesn't exist. |
ConfigurationError
|
Invalid YAML syntax, schema validation failure, or invalid references. |
REMARKS:¶
When multiple sources are provided, collection sections (agents,
models, mcp_servers, mcp_clients, orchestrations) are
merged. Duplicate names within the same section raise ValueError.
Singleton fields (entry, session_manager, log_level) use
last-wins semantics.
Side effect: this function starts MCP servers during resolution.
Agent.__init__ auto-starts MCP clients (via process_tools() ->
MCPClient.load_tools()), and those clients need running servers to
connect to. MCPLifecycle.start() is called before agent
creation to satisfy this dependency.
MCPLifecycle.start() is idempotent, so the caller's context
manager (async with resolved.mcp_lifecycle:) is a no-op on enter
but still required for graceful shutdown — __aexit__ stops
clients first, then servers.
Source code in src/kaboo_workflows/config/loaders/loaders.py
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | |
load_config ¶
load_config(config)
Parse and validate config from file(s) or YAML string(s).
Accepts a single source or a list. Each source is auto-detected:
Pathobjects are always treated as file paths.strvalues are treated as file paths if the file exists on disk; otherwise they are parsed as inline YAML content.
When multiple sources are provided, their collection sections
(agents, models, mcp_servers, mcp_clients,
orchestrations) are merged. Duplicate names within the same
section raise ValueError. Singleton fields (entry,
session_manager, log_level) use last-wins semantics.
Each source's vars: block is applied only to that source
(interpolation is per-source).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
ConfigInput | list[ConfigInput]
|
File path, raw YAML string, or list of either. |
required |
Returns:
| Type | Description |
|---|---|
AppConfig
|
Validated AppConfig instance. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
A |
ConfigurationError
|
Invalid YAML, schema validation failure, or invalid references. |
Source code in src/kaboo_workflows/config/loaders/loaders.py
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 | |
load_session ¶
load_session(config, infra, *, session_id=None)
Create agents and orchestration from already-started infrastructure.
This is the session-level counterpart to :func:load. Use it when
you want to share MCP servers across multiple sessions (e.g. one
session per HTTP request) while creating isolated agents per
session.
infra does NOT carry a session manager; instances are built per
agent/orchestration from config.session_manager plus an
effective_session_id computed here.
Typical server pattern::
app_config = load_config("config.yaml")
infra = resolve_infra(app_config)
infra.mcp_lifecycle.start()
# Per request:
resolved = load_session(app_config, infra, session_id="abc")
infra.mcp_lifecycle must already be started before calling this.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
AppConfig
|
The validated AppConfig. |
required |
infra
|
ResolvedInfra
|
Resolved infrastructure with servers already started. |
required |
session_id
|
str | None
|
Optional runtime session ID. Combined with
|
None
|
Returns:
| Type | Description |
|---|---|
ResolvedConfig
|
ResolvedConfig with freshly created agents and entry point. |
Note
No SessionManager instance is built in this function; instances
are constructed at the leaves (build_agent_from_def,
OrchestrationBuilder._build_one).
Source code in src/kaboo_workflows/config/loaders/loaders.py
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 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | |
resolve_infra ¶
resolve_infra(config)
Resolve infrastructure from an AppConfig (pure, no I/O).
Creates model objects, MCP server/client objects, and a lifecycle manager. Nothing is started.
Resolution order:
- Models (no dependencies)
- MCP servers (no dependencies)
- MCP clients (depend on servers)
- MCP lifecycle (assembles servers + clients, not started)
- Session manager validation only —
agentcoreprovider rejected globally; no instance is constructed (instances are built per-leaf at session time).
Agents and orchestration are resolved in :func:load after
mcp_lifecycle.start() because Agent.__init__ auto-starts
MCP clients which need servers to be running first. The lifecycle
start in load() is idempotent — the context manager is still
used for graceful shutdown.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
AppConfig
|
Parsed AppConfig from YAML. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
ResolvedInfra
|
class: |
Source code in src/kaboo_workflows/config/resolvers/config.py
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | |