From cd5c9c01fb00990e92147beb6fb887799937a9b9 Mon Sep 17 00:00:00 2001 From: iomgaa Date: Sun, 12 Jul 2026 22:34:47 -0400 Subject: [PATCH] feat(app): add PoolStrategy Protocol to application ports --- app/ports.py | 27 ++++++++++++++++++++++++++- tests/unit/test_core_protocols.py | 23 +++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/app/ports.py b/app/ports.py index 4a0b6ce..5fdb77f 100644 --- a/app/ports.py +++ b/app/ports.py @@ -8,8 +8,9 @@ from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable if TYPE_CHECKING: import numpy as np + from app.harness.pools import Pools from app.tree.index import TreeIndex - from core.types import GeneratedQuestion + from core.types import GeneratedQuestion, PoolConfig @runtime_checkable @@ -144,3 +145,27 @@ class PromptBuilderFactory(Protocol): skills_dir: Path | None = None, prompts_dir: Path | None = None, ) -> PromptBuilderFn: ... + + +@runtime_checkable +class PoolStrategy(Protocol): + """池构建策略端口。 + + 应用层端口(非 core 层),因为返回类型 Pools 定义在 app/harness/pools.py。 + 两个具体策略(GlobalPoolStrategy / PerCategoryPoolStrategy)实现此接口。 + """ + + def build( + self, + questions: list[GeneratedQuestion], + correctness: dict[str, bool], + config: PoolConfig, + ) -> Pools: ... + + def build_incremental( + self, + new_task_types: list[str], + questions: list[GeneratedQuestion], + correctness: dict[str, bool], + config: PoolConfig, + ) -> dict[str, dict[str, list[str]]]: ... diff --git a/tests/unit/test_core_protocols.py b/tests/unit/test_core_protocols.py index 4db157b..b600fde 100644 --- a/tests/unit/test_core_protocols.py +++ b/tests/unit/test_core_protocols.py @@ -65,3 +65,26 @@ def test_plain_object_does_not_satisfy() -> None: assert not isinstance(object(), LLMProvider) assert not isinstance(object(), VLMProvider) assert not isinstance(object(), TelemetryRecorder) + + +from app.ports import PoolStrategy + + +class TestPoolStrategyProtocol: + """PoolStrategy Protocol runtime_checkable 验证。""" + + def test_pool_strategy_is_runtime_checkable(self) -> None: + """PoolStrategy 支持 isinstance 检查。""" + from app.harness.pools import Pools + + class FakeStrategy: + def build(self, questions, correctness, config): + return Pools( + diagnosis=[], validation=[], test=[], + baseline_run_id="", baseline_val_accuracy=0.0, + ) + + def build_incremental(self, new_task_types, questions, correctness, config): + return {} + + assert isinstance(FakeStrategy(), PoolStrategy)