feat(s41): PORTFOLIO_MODEL_MAP override + placeholder fail-fast in resolve_model
This commit is contained in:
parent
0670b2a6d8
commit
eb552f854e
3 changed files with 97 additions and 8 deletions
|
|
@ -10,11 +10,22 @@ synthetic client (conftest ``make_portfolio_client_factory``) selects each proje
|
|||
scanning the prompt for its id, so one production-shaped factory serves the whole portfolio.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from portfolio_optimiser.run import PortfolioResult, RunResult, run_portfolio, run_project
|
||||
from portfolio_optimiser.validator import Rejection
|
||||
|
||||
# S4.1: the azure block in the bundled model_map now ships REPLACE-WITH-* placeholders that
|
||||
# resolve_model refuses. This test resolves azure directly (line ~224), so it points
|
||||
# PORTFOLIO_MODEL_MAP at a complete, non-placeholder map (BOTH blocks — resolve_model does no
|
||||
# structural validation) for BOTH parametrizations.
|
||||
_OFFLINE_MODEL_MAP = {
|
||||
"local": {"default": "qwen3:4b", "proposer": "qwen3:4b", "checker": "qwen3:4b"},
|
||||
"azure": {"default": "gpt-4o-mini", "proposer": "gpt-4o-mini", "checker": "gpt-4o-mini"},
|
||||
}
|
||||
|
||||
# The synthetic reply IS the proposal: generate._parse_ir builds affected_items (each with its
|
||||
# own quantity/unit_cost) straight from this JSON, and the validator's P90 = 0.30 x Σ(qty·unit_cost)
|
||||
# ONLY when ``assumptions`` is empty (degenerate Monte Carlo, validator.py:108-113). All three
|
||||
|
|
@ -198,7 +209,7 @@ async def test_c_execution_state_isolation_is_load_bearing(
|
|||
|
||||
@pytest.mark.parametrize("profile", ["local", "azure"])
|
||||
async def test_d_both_profiles_run_offline(
|
||||
make_portfolio_client_factory, fresh_store, profile
|
||||
make_portfolio_client_factory, fresh_store, profile, tmp_path, monkeypatch
|
||||
) -> None:
|
||||
"""SC7: both profiles drive the portfolio contract path OFFLINE under the synthetic client
|
||||
(the path is actually executed, not just the backend instantiated). Teeth: ``resolve_model``
|
||||
|
|
@ -210,6 +221,12 @@ async def test_d_both_profiles_run_offline(
|
|||
``resolve_model`` is the only profile-dependent seam provable offline."""
|
||||
from portfolio_optimiser.backends import resolve_model
|
||||
|
||||
# Unconditionally (both params): the azure branch of line ~224 resolves azure even when
|
||||
# profile=="local", so the placeholder-free override must be active in both runs.
|
||||
map_path = tmp_path / "model_map.json"
|
||||
map_path.write_text(json.dumps(_OFFLINE_MODEL_MAP), encoding="utf-8")
|
||||
monkeypatch.setenv("PORTFOLIO_MODEL_MAP", str(map_path))
|
||||
|
||||
result = await run_portfolio(
|
||||
_PORTFOLIO_IDS,
|
||||
profile,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue