fix: preserve species roles through confirmation

This commit is contained in:
potaser
2026-08-07 08:57:22 +08:00
parent 8c3d601072
commit 822baab367
4 changed files with 201 additions and 21 deletions
+58
View File
@@ -1,3 +1,6 @@
import pytest
from gfa_core.mas.agents.intent_v2 import IntentAgentV2
from gfa_core.mas.utils.intent_parser import (
parse_explicit_species_role_mentions,
parse_gene_family_scope_selection,
@@ -30,3 +33,58 @@ def test_explicit_role_parser_keeps_unassigned_mentions_separate() -> None:
"comparativeSpecies": [],
"unassigned": ["Ppy"],
}
@pytest.mark.parametrize("species", ["Gm", "Br", "Pt", "Sb"])
def test_scope_parser_preserves_species_supported_by_legacy_intent(species: str) -> None:
scope = parse_gene_family_scope_selection(f"分析 {species} 的 SPL 基因家族")
assert scope["targetSpecies"] == [species]
def test_scope_parser_accepts_explicit_role_bound_custom_species_code() -> None:
scope = parse_gene_family_scope_selection("目标物种 Sv;参考物种 At")
assert scope["targetSpecies"] == ["Sv"]
assert scope["referenceSpecies"] == ["At"]
def test_scope_parser_does_not_treat_gene_family_as_species() -> None:
scope = parse_gene_family_scope_selection("目标物种 Ft;分析 SPL 基因家族")
assert scope["targetSpecies"] == ["Ft"]
def test_scope_parser_does_not_bind_custom_code_to_generic_goal_word() -> None:
scope = parse_gene_family_scope_selection("分析目标 SPL 基因家族")
assert scope["targetSpecies"] == []
def test_intent_validation_keeps_confirmed_target_and_reference_separate() -> None:
agent = object.__new__(IntentAgentV2)
intent = agent._validate_intent(
{"gene_family": "SPL", "stages": ["identify"], "params": {}},
(
"请按照你规划的步骤来帮我执行\n"
"已确认上下文:基因家族 SPL;目标物种 Ft;参考物种 At。"
),
)
assert intent["target_species"] == ["Ft"]
assert intent["reference_species"] == ["At"]
assert intent["species"] == "Ft"
def test_intent_validation_preserves_unlabelled_multi_target_request() -> None:
agent = object.__new__(IntentAgentV2)
intent = agent._validate_intent(
{"gene_family": "SPL", "stages": ["identify"], "params": {}},
"分析 Ft 和 Os 的 SPL 基因家族",
)
assert intent["target_species"] == ["Ft", "Os"]
assert intent["reference_species"] == []
assert intent["species"] == "Multi"
@@ -426,6 +426,64 @@ def test_confirmed_multi_species_roles_remain_separate(monkeypatch):
assert resolved["classification_species"] == ["Ft", "Ppy"]
def test_confirmation_ack_normalizes_structured_role_drift(monkeypatch):
main = _load_vue3_main()
monkeypatch.setattr(
main,
"_confirmed_config_species_scope",
lambda _job_id: {
"targetSpecies": ["Ft"],
"referenceSpecies": ["At"],
"comparativeSpecies": [],
},
)
resolved = main._reconcile_confirmed_gene_family_species(
"job-confirmed-ack",
"是",
{
"gene_family": "SPL",
"stages": ["identify"],
"target_species": ["Ft", "At"],
"params": {"targetSpecies": ["Ft", "At"]},
},
)
assert resolved["conflicts"] == []
assert resolved["target_species"] == ["Ft"]
assert resolved["reference_species"] == ["At"]
def test_unassigned_reference_species_analysis_request_remains_blocked(monkeypatch):
main = _load_vue3_main()
monkeypatch.setattr(
main,
"_confirmed_config_species_scope",
lambda _job_id: {
"targetSpecies": ["Ft"],
"referenceSpecies": ["At"],
"comparativeSpecies": [],
},
)
resolved = main._reconcile_confirmed_gene_family_species(
"job-unassigned-reference",
"分析 At 的 SPL 基因家族",
{
"gene_family": "SPL",
"stages": ["identify"],
"target_species": ["At"],
"params": {"targetSpecies": ["At"]},
},
)
assert any(
conflict["code"] == "analysis_target_config_role_conflict"
and conflict["species"] == "At"
for conflict in resolved["conflicts"]
)
def test_confirmed_config_duplicate_roles_are_blocked(monkeypatch):
main = _load_vue3_main()
monkeypatch.setattr(