Amplifier Feature
Integrated Session Spawning
& Event-Driven Orchestration
One unified primitive for all session spawning. Cross-session events. Reactive triggers. Background session management.
Session cbbd5d39 • February 2026 • 4 PRs across the Ecosystem
The Problem
Fragmented Session Spawning
Before this work, spawning sessions was inconsistent, duplicated, and isolated.
📋
~400 Lines Duplicated
CLI and Foreman each had their own spawning logic. Same patterns, different implementations, diverging behavior.
🔇
No Event Communication
Sessions were islands. When Session A completed, Session B had no way to know or react.
⚙️
Manual Asyncio Everywhere
Background tasks required hand-rolled async patterns. No declarative way to define long-running sessions.
The Solution
spawn_bundle()
One function that handles everything: bundle resolution, config inheritance, context passing, background execution, and event emission.
Bundle
→
spawn_bundle()
→
Session
→
Events
5 phases of implementation. 500+ tests. Zero regressions. Fully backward compatible.
Phase 1A
Core spawn_bundle() Primitive
The unified foundation for all session spawning in Amplifier.
class EventType(Enum):
SESSION_COMPLETED = "session_completed"
SESSION_ERROR = "session_error"
async def spawn_bundle(
bundle: str | BundleConfig,
instruction: str,
parent_session: AmplifierSession | None = None,
storage: SessionStorage | None = None,
background: bool = False,
) -> SpawnResult:
"""Spawn a session from a bundle - THE unified entry point."""
SpawnResult
Dataclass with session, task handle, and result access.
SessionStorage
Protocol for custom storage backends.
35 Test Cases
Comprehensive coverage of all spawning scenarios.
Phase 1B
Consumer Migration
Refactored existing consumers to use the new primitive.
Before
- CLI: custom spawn_sub_session()
- Foreman: custom worker spawning
- ~400 lines of duplicated logic
- Diverging behavior over time
After
- CLI: uses spawn_bundle()
- Foreman: uses spawn_bundle()
- Single source of truth
- ForemanSessionStorage impl
122+ tests passing. Zero regressions. Both CLI and Foreman work identically.
Phase 2
Cross-Session Event Communication
Sessions can now talk to each other through a pub/sub event system.
await session_a.emit_event("analysis_complete", {"findings": results})
async for event in router.subscribe("analysis_complete"):
await process_findings(event.payload)
event = await router.wait_for_event("build_finished", timeout=300)
SessionEvent
Typed event dataclass with source, type, and payload.
EventRouter
Central pub/sub broker for cross-session communication.
20 Test Cases
Event emission, subscription, timeouts, and error handling.
Phase 3
Reactive Trigger Infrastructure
Define when sessions should start—not just how.
⏱️
TimerTrigger
Schedule sessions on intervals. Cron-like patterns for periodic tasks.
📡
SessionEventTrigger
React to events from other sessions. Chain workflows together.
🎯
ManualTrigger
Programmatic activation. Trigger from code when conditions are met.
class TriggerSource(Protocol):
async def events(self) -> AsyncIterator[TriggerEvent]: ...
class TriggerType(Enum):
FILE_CHANGE = "file_change"
TIMER = "timer"
SESSION_EVENT = "session_event"
WEBHOOK = "webhook"
Phase 4
Background Session Manager
Declarative configuration for long-running session pools.
BackgroundSessionConfig(
name="code-reviewer",
bundle="review:code-review",
triggers=[
SessionEventTrigger("pr_opened"),
TimerTrigger(interval=3600)
],
pool_size=3,
restart_policy="on_failure"
)
Pool Size Enforcement
Control concurrent session limits per background task type.
Restart Policies
Automatic recovery: always, on_failure, or never.
Trigger Stream Merging
Multiple triggers feed into unified activation stream.
Phase 5
Foreman Integration
End-to-end integration proving the full stack works together.
Challenge
- Must work with existing Foreman
- Cannot break current workflows
- Optional dependency pattern
- Graceful fallback required
Solution
- background_sessions in orchestrator
- Optional import pattern
- Feature detection at runtime
- 6 integration test cases
Foreman can now use background_sessions declaratively, with automatic fallback to original behavior when the feature isn't available.
Architecture
The Complete Picture
┌─────────────────────────────────────────────────────────────────────┐
│ AMPLIFIER ECOSYSTEM │
├─────────────────────────────────────────────────────────────────────┤
│ amplifier-core │
│ └── EventType.SESSION_COMPLETED, SESSION_ERROR │
├─────────────────────────────────────────────────────────────────────┤
│ amplifier-foundation │
│ ├── spawn_bundle() ← The unified primitive │
│ ├── SpawnResult ← Result dataclass │
│ ├── SessionStorage ← Protocol for custom storage │
│ ├── EventRouter ← Cross-session pub/sub │
│ ├── TriggerSource ← Protocol for triggers │
│ └── BackgroundSessionManager ← Declarative background sessions │
├─────────────────────────────────────────────────────────────────────┤
│ amplifier-app-cli │
│ └── spawn_sub_session() → uses spawn_bundle() internally │
├─────────────────────────────────────────────────────────────────────┤
│ amplifier-bundle-foreman │
│ └── Worker spawning → uses spawn_bundle() + BackgroundSessionMgr │
└─────────────────────────────────────────────────────────────────────┘
Impact
Development Velocity
1
amplifier-core
New SESSION_COMPLETED and SESSION_ERROR events
2
amplifier-foundation
spawn_bundle(), EventRouter, Triggers, BackgroundSessionManager
3
amplifier-app-cli
Migrated spawn_sub_session() to use spawn_bundle()
4
amplifier-bundle-foreman
Worker spawning + background_sessions support
Get Started
Ready to Ship
All phases complete. All tests passing. PRs ready for review.
Session cbbd5d39 — From fragmented spawning to a unified, event-driven orchestration platform.
Built with Amplifier • February 2026