feat(question_gen): register ActionRecognitionStrategy, replace temp VISUAL binding
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -104,7 +104,7 @@ class TaskTypeStrategy(Protocol):
|
||||
|
||||
# 消歧绑定表:多归属题型确定性绑定到一个 family
|
||||
_TASK_TYPE_TO_FAMILY: dict[str, QuestionFamilySpec] = {
|
||||
"Action Recognition": VISUAL_FAMILY, # Plan A 临时绑定;Plan B 替换为特化策略
|
||||
"Action Recognition": VISUAL_FAMILY, # fallback — 注册表中已被 ActionRecognitionStrategy 替换
|
||||
"Object Recognition": RETRIEVAL_FAMILY,
|
||||
"Object Reasoning": REASONING_FAMILY,
|
||||
"Action Reasoning": REASONING_FAMILY,
|
||||
@@ -200,9 +200,14 @@ def register_strategy(strategy: TaskTypeStrategy) -> None:
|
||||
_STRATEGY_REGISTRY[strategy.task_type] = strategy
|
||||
|
||||
|
||||
_BUILTIN_REGISTERED = False
|
||||
|
||||
|
||||
def get_strategy(task_type: str) -> TaskTypeStrategy:
|
||||
"""获取题型策略。未注册的自动创建 BaseTaskTypeStrategy。
|
||||
|
||||
首次调用时延迟注册内建特化策略(避免循环导入)。
|
||||
|
||||
参数:
|
||||
task_type: 题型名。
|
||||
|
||||
@@ -212,6 +217,11 @@ def get_strategy(task_type: str) -> TaskTypeStrategy:
|
||||
异常:
|
||||
KeyError: task_type 不在消歧绑定表和注册表中。
|
||||
"""
|
||||
global _BUILTIN_REGISTERED # noqa: PLW0603
|
||||
if not _BUILTIN_REGISTERED:
|
||||
_BUILTIN_REGISTERED = True
|
||||
_register_builtin_strategies()
|
||||
|
||||
if task_type in _STRATEGY_REGISTRY:
|
||||
return _STRATEGY_REGISTRY[task_type]
|
||||
return _build_default_strategy(task_type)
|
||||
@@ -231,3 +241,10 @@ def _build_default_strategy(task_type: str) -> BaseTaskTypeStrategy:
|
||||
"""
|
||||
family = _TASK_TYPE_TO_FAMILY[task_type]
|
||||
return BaseTaskTypeStrategy(task_type=task_type, family=family)
|
||||
|
||||
|
||||
def _register_builtin_strategies() -> None:
|
||||
"""注册内建的特化策略。由 get_strategy 首次调用时延迟执行。"""
|
||||
from app.question_gen.strategy_action_recognition import ActionRecognitionStrategy
|
||||
|
||||
register_strategy(ActionRecognitionStrategy())
|
||||
|
||||
@@ -116,3 +116,27 @@ class TestSubPattern:
|
||||
)
|
||||
with pytest.raises(AttributeError):
|
||||
sp.name = "changed"
|
||||
|
||||
|
||||
class TestActionRecognitionRegistration:
|
||||
"""AR 策略注册后 get_strategy 返回特化实例。"""
|
||||
|
||||
def test_get_strategy_returns_ar_strategy(self):
|
||||
"""get_strategy('Action Recognition') 返回 ActionRecognitionStrategy。"""
|
||||
from app.question_gen.strategy_action_recognition import ActionRecognitionStrategy
|
||||
|
||||
s = get_strategy("Action Recognition")
|
||||
assert isinstance(s, ActionRecognitionStrategy)
|
||||
assert s.task_type == "Action Recognition"
|
||||
assert s.strategy_name == "ACTION_RECOGNITION"
|
||||
|
||||
def test_ar_not_base_strategy(self):
|
||||
"""get_strategy('Action Recognition') 不再返回 BaseTaskTypeStrategy。"""
|
||||
s = get_strategy("Action Recognition")
|
||||
assert not isinstance(s, BaseTaskTypeStrategy)
|
||||
|
||||
def test_other_types_still_base(self):
|
||||
"""其他题型仍返回 BaseTaskTypeStrategy。"""
|
||||
for tt in ("Object Recognition", "Temporal Reasoning", "Spatial Reasoning"):
|
||||
s = get_strategy(tt)
|
||||
assert isinstance(s, BaseTaskTypeStrategy), f"{tt} 应该是 BaseTaskTypeStrategy"
|
||||
|
||||
Reference in New Issue
Block a user