For a (technique_id, role_id) pair, return modules that can fill the role, ranked by affordance match.
Use this when the user has named a technique and you need to recommend modules for a specific role within it (e.g., "what should I use for the lpg role in a lowpass-gate-pluck patch?"). Optionally pass available_modules to restrict the search to the user's rack — the tool surfaces both documented realizations in the rack AND undocumented candidates whose capability tags match the role's required affordances (or, for roles that declare only optional affordances, those optional ones).
This tool exists to STOP the model from inventing module-role recipes from training-data priors. The output is editorially grounded: documented realizations carry corpus-curated notes; undocumented candidates are explicitly tagged so the agent can weigh confidence.
Args:
- technique_id (required): kebab-case technique id (see list_techniques).
- role_id (required): kebab-case role id (e.g., "lpg", "voice", "env", "clock"). See list_techniques → role_definitions for the roles a technique declares.
- available_modules (optional): array of "<manufacturer>/<module-slug>" ids — typically the user's rack. When supplied, restricts results AND surfaces undocumented candidates whose module_capabilities match the role's required affordances — or, for an optional-only role (no required affordances), its optional affordances.
Returns:
{
"technique_id": "low-pass-gate-pluck",
"role_id": "lpg",
"role": { "label": "Low-Pass Gate", "description": "Vactrol-style..." },
"role_definition_description": "The vactrol-based or vactrol-emulating element...",
"required_affordances": ["lowpass-gate"],
"optional_affordances": [],
"realizations": [
{
"module_id": "make-noise/optomix",
"documented": true,
"affordances_provided": ["lowpass-gate"],
"required_matched": ["lowpass-gate"],
"optional_matched": [],
"missing_required": [],
"fit_score": { "required": 1, "optional": 0 },
"notes": "Two-channel vactrol-based LPG..."
},
...
],
"_meta": {
"available_modules_filter": null,
"documented_count": 19,
"candidate_count": 19
}
}
Ranking: by required_matched.length desc, then optional_matched.length desc, then module_id asc. A candidate with missing_required.length > 0 is NOT a valid realization but is still returned (sorted last) so the agent can explain why a rack module isn't a fit.
satisfied_via: a rack module can fill a role through a capability-satisfaction edge rather than a literal affordance tag — e.g. a module with an internal low-pass gate (capability internal-lpg) fills the lpg affordance and self-plucks, so it realizes a low-pass-gate-pluck on its own. Such matches carry a satisfied_via:[{ affordance, via, kind }] entry (kind="self-contained" means it fills the role internally, not as an externally-routable instance you patch into) so you can distinguish "this module self-plucks" from "this is an external LPG." Present only on undocumented rack candidates and only for non-literal matches.
Errors:
- "Technique not found: <id>"
- "Role not defined for technique: <role_id> in <technique_id>"
- Empty realizations[] with a feedback_hint when filters produce no matches.