fix(hooks-routing): register model_role_resolver capability in mount()#27
Open
bkrabach wants to merge 1 commit into
Open
fix(hooks-routing): register model_role_resolver capability in mount()#27bkrabach wants to merge 1 commit into
bkrabach wants to merge 1 commit into
Conversation
MatrixModelRoleResolver was instantiated but never registered via coordinator.register_capability(), leaving tool-delegate with no resolver for model_role parameters. Effect: every delegate(..., model_role=...) call emitted a spurious WARNING on stderr and silently fell back to the agent's declared role, discarding the caller's override. Fix: after computing effective_matrix in mount(), instantiate a MatrixModelRoleResolver and register it under 'model_role_resolver'. Guard on effective_matrix being non-empty so the capability is absent (not silent-empty) when the matrix file is missing. Adds a regression test (TestModelRoleResolverCapability) that asserts the capability is registered and that the resolver returns correct ProviderPreference objects for a known role.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Registers the
model_role_resolvercapability inhooks-routingmount()so that consumers callingcoordinator.get_capability("model_role_resolver")actually receive the matrix-strategy resolver.Why
The
MatrixModelRoleResolverclass shipped inresolver_class.py(introduced in commit3f20ad3) was never wired into the capability registry. As a result:Every
delegate(..., model_role=X, ...)call where the caller supplied amodel_roletriggered the stderr warning atamplifier-foundation/modules/tool-delegate/__init__.py:790-794:despite this bundle being mounted and the matrix loaded correctly.
Silent functional regression: the caller's
model_roleoverride was discarded attool-delegate/__init__.py:781-806. The spawn proceeded with the agent's pre-resolved defaultprovider_preferencesinstead, ignoring caller intent.Evidence
Reproduced end-to-end in a Digital Twin Universe environment running upstream
main:amplifier tool invoke delegate agent=foundation:explorer model_role=writing instruction="..."emitted the warning above on every call (deterministic — confirmed with bothwritingandcodingroles, byte-identical event sequences across runs, ruling out a race condition).model_role 'X' resolved to no candidates against installed providers (resolver=balanced)— emitted from the success branch of the capability check (tool-delegate/__init__.py:801-806), proving the resolver is now registered, looked up, and invoked. The matrix namebalancedis correctly reported viaMatrixModelRoleResolver.name.Changes
modules/hooks-routing/amplifier_module_hooks_routing/__init__.py(+17 lines): instantiateMatrixModelRoleResolveraftereffective_matrixis composed, register viacoordinator.register_capability("model_role_resolver", resolver). Guarded byeffective_matrixtruthy andhasattr(coordinator, "register_capability").modules/hooks-routing/tests/test_init.py(+84 lines): newTestModelRoleResolverCapabilitytest class assertingregister_capability("model_role_resolver", ...)is called frommount()and the registered resolver'sresolve("fast")returns a non-empty list ofProviderPreference.All 8 tests in
modules/hooks-routing/tests/test_init.pypass.Cascade and fallback semantics
The fix preserves the existing five-step fallback cascade. Confirmed by code reading:
provider_preferences(delegate input) — highest prioritymodel_role— now actually honored (was previously discarded)provider_preferences(fromsession:starthook, resolved from agent's frontmattermodel_rolechain)provider_preferences:(hard-pinned, bundle-portable)provider_preferences=None→ child spawn inherits parent's current providerThe role-level fallback chain (
resolve_model_roleiterating an ordered list) is unchanged. Agent-frontmattermodel_role: [list]still honors chains.Behavioral change to flag
Any caller that was incidentally relying on the override being silently discarded (i.e., expecting the agent's default model_role chain to win even when passing
model_role=Xtodelegate) will see different behavior after this fix. I have no evidence such callers exist in the wild, but the bug-fix-shifts-behavior risk is non-zero — worth a heads-up.Out of scope (intentionally)
model_roleas a string only, not a list. The resolver itself and the agent-frontmatter path both accept list-form chains. This asymmetry pre-dates the bug and is not addressed here.bundle.md: deferred. The matrix bundle has no established versioning discipline for hook-only behavior fixes. Maintainer call.Verification commands