Hosting: resolving roles
A role is a named set of functions a mod promises to provide — a transcriber, a formatter, a data provider. Cross-mod collaboration goes through roles, not hardcoded globals. The host resolves the active provider and calls its functions. Declaring a role grants nothing; each named function stays gated by its own capability.
Resolving a provider
Section titled “Resolving a provider”runtime.resolveRole(role)returns the activeRoleResolution, ornullwhen no mod provides it.runtime.resolveRoleAll(role)returns every provider, for when the host wants to fan out rather than pick one.
A RoleResolution is { addon, role, fns }, where fns maps each role-function name to the provider mod’s export name. The host calls them through runtime.invokeExport(fns[name], args) — it never assumes a global of that name exists.
Picking among providers
Section titled “Picking among providers”When more than one mod provides a role, the host chooses. Set rolePreferences on createRuntime ({ "transcriber": "my-whisper-addon" }) to prefer a named provider per role; resolveRole honors it, falling back to the highest-priority provider otherwise. Use resolveRoleAll when every provider should run.
Roles grant nothing on their own
Section titled “Roles grant nothing on their own”Providing a role is not a capability. A role function that reaches a gated binding still needs that capability granted to its mod (granting capabilities). Resolving a role tells the host who provides it and what to call; it never widens what those functions may do.
Common mistakes
Section titled “Common mistakes”- Assuming a provider exists.
resolveRolereturnsnullwhen nothing provides the role. Handle absence; do not call into a null resolution. - Calling role functions by their role name. Call the export name from
fns, throughinvokeExport. The role name is a label, not a global. - Treating a role as a grant. A provider’s functions are still gated by the capabilities its mod was granted.