How three features became one step
Run steps in parallel, loop until they converge, and pick the right model per step. Each started as its own experiment.
And each one really shipped — here is the proof.
Every capability landed on origin/main, and each one's original feature branch is still visible on origin.
But look at when they landed — one after another.
The three commits arrived in sequence — each built alone, each able to ignore the others.
Sequential, independent landings are exactly how features fragment.
The three capabilities converged into a single Step model and a single recipe executor — not three separate bolt-ons.
One shared model is what makes composition possible.
Bounded parallelism isn't a standalone knob. Validation requires foreach, so it means bounded parallel iteration over items — enforced by asyncio.Semaphore.
One capability binds cleanly into the shared Step.
Per-step model choice is agent-step-only and mutually exclusive with the legacy provider/model fields — so a second capability slots in without colliding.
Two capabilities, one Step, no collision.
A single foreach step can carry bounded parallel, a while_condition convergence body, and a model_role — the three capabilities COMPOSE.
Three branches resolve into one composable declarative step.
A later rename to model_role_resolver (PR #75, 2026-05-13) deleted duplicated resolver logic — tightening the single shared design.
Merging features into one model makes ongoing cleanup and reuse possible.
Repository: microsoft/amplifier-bundle-recipes
Data as of: 2026-05-20 — origin/main HEAD b6ee26d (PR #76)
Verification: every claim independently re-derived from git commands run against origin/main at b6ee26d after a fresh fetch.
Commands run:
git branch -r | grep -E 'rate-limiting-and-bounded-parallelism|convergence-loops|model-class-routing'git log -1 --format='%h %ci %s' 997b85e 53089b1 b965b95 and git merge-base --is-ancestor $c origin/maingit show origin/main:.../models.py | grep -nE 'parallel|foreach|while_condition|break_when|model_role'git show origin/main:.../executor.py | wc -l and grep -n Semaphoregit log -1 --format='%h %ci %s' 45300d8git log origin/main -120 --format='%an' | sort | uniq -c | sort -rnGaps: the literal token model_role appears 0 times in docs/*.md; the user-facing docs describe this as class-based routing via provider_preferences. No example YAML uses model_role.
Primary contributor: Brian Krabach (99 of last 120 commits; author of all three feature commits and the rename).