You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(decisioning): per-tenant ProposalManager binding via PlatformRouter
v1 shipped single-ProposalManager-per-serve(), wired through a kwarg on
serve()/PlatformHandler. Reviewer feedback (Brian, architect):
ProposalManager has to be per-tenant. Multi-tenant deployments
(salesagent, agentic-adapters social) need different proposal logic per
tenant — a GAM tenant has different products from a Kevel tenant; a Meta
tenant has different proposal assembly from a TikTok tenant.
Single-tenant binding doesn't fit.
Changes:
- PlatformRouter accepts ``proposal_managers={tenant_id:
ProposalManager}``. Validates keys are a subset of platforms keys
at construction (orphan tenants raise ValueError). The router
overrides its synthesized ``get_products`` delegation with an
explicit method that does per-tenant manager lookup, refine-mode
selection (capability + method-presence gated), and per-tenant
fall-through to ``platforms[tenant_id].get_products`` when no
manager is wired — back-compat per tenant.
- ``serve(proposal_manager=)`` and
``create_adcp_server_from_platform(proposal_manager=)`` kwargs
removed. Single-tenant adopters wire a one-entry router:
``PlatformRouter(platforms={"default": ...},
proposal_managers={"default": ...})``. Same pattern as v3 reference
seller adopted in PR #488.
- PlatformHandler's ``proposal_manager=`` field and
``_select_proposal_method`` helper removed. The router's
``get_products`` does its own dispatch and the handler delegates
uniformly via ``_invoke_platform_method``.
- ``examples/hello_proposal_manager.py`` rewritten to demonstrate the
per-tenant binding: tenant_acme has a wired MockProposalManager;
tenant_globex falls through to its platform's get_products.
- Tests rewritten to cover per-tenant routing: orphan-key validation,
per-tenant isolation, per-tenant fall-through, sync+async manager
dispatch, refine routing across all four conditions. 18 tests
total, all green; full regression suite (3720 tests) green; no
existing example modified (v3 reference seller, hello_seller,
hello_mock_seller, multi_platform_seller — back-compat preserved
since none ever used the removed ``proposal_manager=`` kwarg).
- docs/proposals/product-architecture.md § "Open questions" updated:
the tenant binding model question is now resolved (v1 ships
per-tenant via PlatformRouter).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments