[claude] Fix ruff S105/S106/B017/E402 errors in bannerlord (#1161) #1165

Merged
Timmy merged 1 commits from :claude/issue-1161 into main 2026-03-23 19:56:08 +00:00
4 changed files with 82 additions and 39 deletions

View File

@@ -126,8 +126,7 @@ class KingAgent:
if victory.achieved:
logger.info(
"SOVEREIGN VICTORY — King of Calradia! "
"Territory: %.1f%%, tick: %d",
"SOVEREIGN VICTORY — King of Calradia! Territory: %.1f%%, tick: %d",
victory.territory_control_pct,
self._tick,
)
@@ -186,7 +185,7 @@ class KingAgent:
logger.warning(
"King LLM decision failed at tick %d: %s — defaulting to RECRUIT", self._tick, exc
)
return KingSubgoal(token="RECRUIT", context="LLM unavailable — safe default")
return KingSubgoal(token="RECRUIT", context="LLM unavailable — safe default") # noqa: S106
def _llm_decide(self, state: dict[str, Any]) -> KingSubgoal:
"""Synchronous Ollama call (runs in a thread via asyncio.to_thread)."""

View File

@@ -76,9 +76,7 @@ class BaseVassal:
msg = self._subgoal_queue.get_nowait()
if msg.to_agent == self.name:
self._active_subgoal = msg.subgoal
logger.debug(
"%s received subgoal %s", self.name, msg.subgoal.token
)
logger.debug("%s received subgoal %s", self.name, msg.subgoal.token)
except asyncio.QueueEmpty:
pass
@@ -147,10 +145,8 @@ class WarVassal(BaseVassal):
subgoal_bonus=bonus,
)
def _plan_action(
self, state: dict[str, Any], subgoal: KingSubgoal
) -> TaskMessage | None:
if subgoal.token == "EXPAND_TERRITORY" and subgoal.target:
def _plan_action(self, state: dict[str, Any], subgoal: KingSubgoal) -> TaskMessage | None:
if subgoal.token == "EXPAND_TERRITORY" and subgoal.target: # noqa: S105
return TaskMessage(
from_agent=self.name,
to_agent="logistics_companion",
@@ -158,7 +154,7 @@ class WarVassal(BaseVassal):
args={"destination": subgoal.target},
priority=subgoal.priority,
)
if subgoal.token == "RECRUIT":
if subgoal.token == "RECRUIT": # noqa: S105
qty = subgoal.quantity or 20
return TaskMessage(
from_agent=self.name,
@@ -167,7 +163,7 @@ class WarVassal(BaseVassal):
args={"troop_type": "infantry", "quantity": qty},
priority=subgoal.priority,
)
if subgoal.token == "TRAIN":
if subgoal.token == "TRAIN": # noqa: S105
return TaskMessage(
from_agent=self.name,
to_agent="logistics_companion",
@@ -219,10 +215,8 @@ class EconomyVassal(BaseVassal):
subgoal_bonus=bonus,
)
def _plan_action(
self, state: dict[str, Any], subgoal: KingSubgoal
) -> TaskMessage | None:
if subgoal.token == "FORTIFY" and subgoal.target:
def _plan_action(self, state: dict[str, Any], subgoal: KingSubgoal) -> TaskMessage | None:
if subgoal.token == "FORTIFY" and subgoal.target: # noqa: S105
return TaskMessage(
from_agent=self.name,
to_agent="logistics_companion",
@@ -230,7 +224,7 @@ class EconomyVassal(BaseVassal):
args={"settlement": subgoal.target},
priority=subgoal.priority,
)
if subgoal.token == "TRADE":
if subgoal.token == "TRADE": # noqa: S105
return TaskMessage(
from_agent=self.name,
to_agent="caravan_companion",
@@ -282,10 +276,8 @@ class DiplomacyVassal(BaseVassal):
subgoal_bonus=bonus,
)
def _plan_action(
self, state: dict[str, Any], subgoal: KingSubgoal
) -> TaskMessage | None:
if subgoal.token == "ALLY" and subgoal.target:
def _plan_action(self, state: dict[str, Any], subgoal: KingSubgoal) -> TaskMessage | None:
if subgoal.token == "ALLY" and subgoal.target: # noqa: S105
return TaskMessage(
from_agent=self.name,
to_agent="scout_companion",
@@ -293,7 +285,7 @@ class DiplomacyVassal(BaseVassal):
args={"name": subgoal.target},
priority=subgoal.priority,
)
if subgoal.token == "SPY" and subgoal.target:
if subgoal.token == "SPY" and subgoal.target: # noqa: S105
return TaskMessage(
from_agent=self.name,
to_agent="scout_companion",

View File

@@ -1,12 +1,9 @@
"""Tests for the three-tier metabolic LLM router (issue #966)."""
import asyncio
from unittest.mock import AsyncMock, MagicMock, patch
from unittest.mock import AsyncMock, MagicMock
import pytest
pytestmark = pytest.mark.unit
from infrastructure.router.metabolic import (
DEFAULT_TIER_MODELS,
MetabolicRouter,
@@ -16,6 +13,7 @@ from infrastructure.router.metabolic import (
get_metabolic_router,
)
pytestmark = pytest.mark.unit
# ── classify_complexity ──────────────────────────────────────────────────────
@@ -198,7 +196,12 @@ class TestMetabolicRouter:
async def test_t1_uses_t1_model(self):
mock_cascade = MagicMock()
mock_cascade.complete = AsyncMock(
return_value={"content": "ok", "provider": "ollama-local", "model": "qwen3:8b", "latency_ms": 100}
return_value={
"content": "ok",
"provider": "ollama-local",
"model": "qwen3:8b",
"latency_ms": 100,
}
)
router = MetabolicRouter(cascade=mock_cascade)
await router.route("go north", state={})
@@ -208,7 +211,12 @@ class TestMetabolicRouter:
async def test_t2_uses_t2_model(self):
mock_cascade = MagicMock()
mock_cascade.complete = AsyncMock(
return_value={"content": "ok", "provider": "ollama-local", "model": "qwen3:14b", "latency_ms": 300}
return_value={
"content": "ok",
"provider": "ollama-local",
"model": "qwen3:14b",
"latency_ms": 300,
}
)
router = MetabolicRouter(cascade=mock_cascade)
await router.route("what should I say to the innkeeper", state={})
@@ -218,7 +226,12 @@ class TestMetabolicRouter:
async def test_t3_uses_t3_model(self):
mock_cascade = MagicMock()
mock_cascade.complete = AsyncMock(
return_value={"content": "ok", "provider": "ollama-local", "model": "qwen3:30b", "latency_ms": 2000}
return_value={
"content": "ok",
"provider": "ollama-local",
"model": "qwen3:30b",
"latency_ms": 2000,
}
)
router = MetabolicRouter(cascade=mock_cascade)
await router.route("plan the optimal quest route", state={})
@@ -228,7 +241,12 @@ class TestMetabolicRouter:
async def test_custom_tier_models_respected(self):
mock_cascade = MagicMock()
mock_cascade.complete = AsyncMock(
return_value={"content": "ok", "provider": "test", "model": "custom-8b", "latency_ms": 100}
return_value={
"content": "ok",
"provider": "test",
"model": "custom-8b",
"latency_ms": 100,
}
)
custom = {ModelTier.T1_ROUTINE: "custom-8b"}
router = MetabolicRouter(cascade=mock_cascade, tier_models=custom)
@@ -239,7 +257,12 @@ class TestMetabolicRouter:
async def test_t3_pauses_world_before_inference(self):
mock_cascade = MagicMock()
mock_cascade.complete = AsyncMock(
return_value={"content": "ok", "provider": "ollama", "model": "qwen3:30b", "latency_ms": 1500}
return_value={
"content": "ok",
"provider": "ollama",
"model": "qwen3:30b",
"latency_ms": 1500,
}
)
router = MetabolicRouter(cascade=mock_cascade)
@@ -281,7 +304,12 @@ class TestMetabolicRouter:
async def test_t1_does_not_pause_world(self):
mock_cascade = MagicMock()
mock_cascade.complete = AsyncMock(
return_value={"content": "ok", "provider": "ollama", "model": "qwen3:8b", "latency_ms": 120}
return_value={
"content": "ok",
"provider": "ollama",
"model": "qwen3:8b",
"latency_ms": 120,
}
)
router = MetabolicRouter(cascade=mock_cascade)
@@ -297,7 +325,12 @@ class TestMetabolicRouter:
async def test_t2_does_not_pause_world(self):
mock_cascade = MagicMock()
mock_cascade.complete = AsyncMock(
return_value={"content": "ok", "provider": "ollama", "model": "qwen3:14b", "latency_ms": 350}
return_value={
"content": "ok",
"provider": "ollama",
"model": "qwen3:14b",
"latency_ms": 350,
}
)
router = MetabolicRouter(cascade=mock_cascade)
@@ -314,7 +347,12 @@ class TestMetabolicRouter:
"""If world.act() raises, inference must still complete."""
mock_cascade = MagicMock()
mock_cascade.complete = AsyncMock(
return_value={"content": "done", "provider": "ollama", "model": "qwen3:30b", "latency_ms": 2000}
return_value={
"content": "done",
"provider": "ollama",
"model": "qwen3:30b",
"latency_ms": 2000,
}
)
router = MetabolicRouter(cascade=mock_cascade)
@@ -329,7 +367,12 @@ class TestMetabolicRouter:
async def test_no_world_adapter_t3_still_works(self):
mock_cascade = MagicMock()
mock_cascade.complete = AsyncMock(
return_value={"content": "plan done", "provider": "ollama", "model": "qwen3:30b", "latency_ms": 2000}
return_value={
"content": "plan done",
"provider": "ollama",
"model": "qwen3:30b",
"latency_ms": 2000,
}
)
router = MetabolicRouter(cascade=mock_cascade)
# No set_world() called
@@ -347,7 +390,12 @@ class TestMetabolicRouter:
"""Calling route without ui_state should not raise."""
mock_cascade = MagicMock()
mock_cascade.complete = AsyncMock(
return_value={"content": "ok", "provider": "ollama", "model": "qwen3:8b", "latency_ms": 100}
return_value={
"content": "ok",
"provider": "ollama",
"model": "qwen3:8b",
"latency_ms": 100,
}
)
router = MetabolicRouter(cascade=mock_cascade)
# No ui_state argument
@@ -357,7 +405,12 @@ class TestMetabolicRouter:
async def test_temperature_and_max_tokens_forwarded(self):
mock_cascade = MagicMock()
mock_cascade.complete = AsyncMock(
return_value={"content": "ok", "provider": "ollama", "model": "qwen3:14b", "latency_ms": 200}
return_value={
"content": "ok",
"provider": "ollama",
"model": "qwen3:14b",
"latency_ms": 200,
}
)
router = MetabolicRouter(cascade=mock_cascade)
await router.route("describe the scene", state={}, temperature=0.1, max_tokens=50)

View File

@@ -15,7 +15,6 @@ from bannerlord.models import (
WarReward,
)
# ── KingSubgoal ───────────────────────────────────────────────────────────────
@@ -35,7 +34,7 @@ class TestKingSubgoal:
KingSubgoal(token="NUKE_CALRADIA")
def test_priority_clamp(self):
with pytest.raises(Exception):
with pytest.raises(ValueError):
KingSubgoal(token="TRADE", priority=3.0)
def test_optional_fields_default_none(self):