From 705c5dd49a3b2bfb0b3563023e27237ef897b802 Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Fri, 3 Jul 2026 00:32:49 +0200 Subject: [PATCH] chore(format): ruff format the 4 drifted files (no behavior change) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01AaQCFnfsh3tfq1VfzdJpoi --- src/portfolio_optimiser/backends.py | 4 +- src/portfolio_optimiser/budget.py | 4 +- src/portfolio_optimiser/verdicts.py | 113 ++++++++++++++++++++++------ tests/test_contracts.py | 5 +- 4 files changed, 95 insertions(+), 31 deletions(-) diff --git a/src/portfolio_optimiser/backends.py b/src/portfolio_optimiser/backends.py index 5d84b34..6e44d44 100644 --- a/src/portfolio_optimiser/backends.py +++ b/src/portfolio_optimiser/backends.py @@ -73,9 +73,7 @@ class AzureFoundryBackend: def create_chat_client(self, *, model: str) -> BaseChatClient: endpoint = os.environ.get("PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT") if not endpoint: - raise ValueError( - "PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT is required for the AZURE profile" - ) + raise ValueError("PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT is required for the AZURE profile") # Credential resolves lazily via Azure DefaultAzureCredential (az login / MI). return FoundryChatClient(project_endpoint=endpoint, model=model) diff --git a/src/portfolio_optimiser/budget.py b/src/portfolio_optimiser/budget.py index 58b0790..95bc8df 100644 --- a/src/portfolio_optimiser/budget.py +++ b/src/portfolio_optimiser/budget.py @@ -86,9 +86,7 @@ class BudgetMiddleware(ChatMiddleware): self._meter = meter self._strict = strict_usage - async def process( - self, context: ChatContext, call_next: Callable[[], Awaitable[None]] - ) -> None: + async def process(self, context: ChatContext, call_next: Callable[[], Awaitable[None]]) -> None: await call_next() usage = getattr(context.result, "usage_details", None) total = usage.get("total_token_count") if usage is not None else None diff --git a/src/portfolio_optimiser/verdicts.py b/src/portfolio_optimiser/verdicts.py index b854cac..ab01271 100644 --- a/src/portfolio_optimiser/verdicts.py +++ b/src/portfolio_optimiser/verdicts.py @@ -259,30 +259,95 @@ def seed_store() -> VerdictStore: """Seed 12 synthetic verdicts spanning the reference domain's cost codes, measure types, magnitudes, and decisions (B2 store of 10-20).""" rows = [ - ("V01", {"05.2", "03.1"}, "scope_reduction", 180_000, "approved", - "asphalt + base course trimmed within feasible range"), - ("V02", {"05.2"}, "rate_renegotiation", 60_000, "approved", - "renegotiated asphalt unit rate"), - ("V03", {"07.4"}, "material_substitution", 120_000, "rejected", - "granite kerb substitution unsafe"), - ("V04", {"09.1"}, "scope_reduction", 240_000, "approved", - "fewer LED masts on low-traffic stretch"), - ("V05", {"02.3", "03.1"}, "scope_reduction", 350_000, "rejected", - "soil replacement is load-bearing, cannot cut"), - ("V06", {"21.2"}, "rate_renegotiation", 90_000, "approved", - "blasting rate renegotiated"), - ("V07", {"22.4"}, "material_substitution", 700_000, "rejected", - "fiber shotcrete spec is mandated"), - ("V08", {"88.2"}, "scope_reduction", 150_000, "approved", - "concrete repair area re-measured smaller"), - ("V09", {"87.3"}, "material_substitution", 130_000, "approved", - "alternative membrane qualified"), - ("V10", {"05.2", "03.1"}, "rate_renegotiation", 200_000, "approved", - "combined paving rate discount"), - ("V11", {"01.1"}, "scope_reduction", 95_000, "rejected", - "rigging is fixed cost, no scope to cut"), - ("V12", {"31.3"}, "scope_reduction", 110_000, "approved", - "drainage length reduced after survey"), + ( + "V01", + {"05.2", "03.1"}, + "scope_reduction", + 180_000, + "approved", + "asphalt + base course trimmed within feasible range", + ), + ( + "V02", + {"05.2"}, + "rate_renegotiation", + 60_000, + "approved", + "renegotiated asphalt unit rate", + ), + ( + "V03", + {"07.4"}, + "material_substitution", + 120_000, + "rejected", + "granite kerb substitution unsafe", + ), + ( + "V04", + {"09.1"}, + "scope_reduction", + 240_000, + "approved", + "fewer LED masts on low-traffic stretch", + ), + ( + "V05", + {"02.3", "03.1"}, + "scope_reduction", + 350_000, + "rejected", + "soil replacement is load-bearing, cannot cut", + ), + ("V06", {"21.2"}, "rate_renegotiation", 90_000, "approved", "blasting rate renegotiated"), + ( + "V07", + {"22.4"}, + "material_substitution", + 700_000, + "rejected", + "fiber shotcrete spec is mandated", + ), + ( + "V08", + {"88.2"}, + "scope_reduction", + 150_000, + "approved", + "concrete repair area re-measured smaller", + ), + ( + "V09", + {"87.3"}, + "material_substitution", + 130_000, + "approved", + "alternative membrane qualified", + ), + ( + "V10", + {"05.2", "03.1"}, + "rate_renegotiation", + 200_000, + "approved", + "combined paving rate discount", + ), + ( + "V11", + {"01.1"}, + "scope_reduction", + 95_000, + "rejected", + "rigging is fixed cost, no scope to cut", + ), + ( + "V12", + {"31.3"}, + "scope_reduction", + 110_000, + "approved", + "drainage length reduced after survey", + ), ] return VerdictStore( verdicts=[ diff --git a/tests/test_contracts.py b/tests/test_contracts.py index 82343d0..f79da4b 100644 --- a/tests/test_contracts.py +++ b/tests/test_contracts.py @@ -28,7 +28,10 @@ def test_malformed_data_source_raises() -> None: def test_malformed_model_map_raises() -> None: - bad_map = {"local": {"proposer": "qwen3:4b"}, "azure": {"default": "x"}} # local missing 'default' + bad_map = { + "local": {"proposer": "qwen3:4b"}, + "azure": {"default": "x"}, + } # local missing 'default' with pytest.raises(ValidationError): load_contracts(_DS, _TERM, _FB, model_map=bad_map)