117 lines
3.7 KiB
Python
117 lines
3.7 KiB
Python
import asyncio
|
||
import json
|
||
|
||
from gfa_core.mas.agents.intent_v2 import IntentAgentV2
|
||
from gfa_core.mas.agents.conversation_tools import build_plantai_conversation_tools
|
||
from gfa_core.mas.llm import LLMManager
|
||
from gfa_core.mas.workflow_models import GoalLedger
|
||
|
||
|
||
def _registry(tmp_path, *, job_id="job-data-preparation-handoff"):
|
||
ledger = GoalLedger(
|
||
conversation_id="conversation-data-preparation-handoff",
|
||
revision=0,
|
||
user_terms={
|
||
"active_job_id": job_id,
|
||
"gene_family": "SPL",
|
||
"target_species": ["Ft"],
|
||
"reference_species": ["At"],
|
||
"config_confirmed": True,
|
||
},
|
||
)
|
||
return build_plantai_conversation_tools(
|
||
llm_manager=LLMManager({}),
|
||
project_root=tmp_path,
|
||
bound_job_id=job_id,
|
||
goal_ledger=ledger,
|
||
)
|
||
|
||
|
||
def test_analysis_handoff_is_not_rewritten_to_genome_prepare(tmp_path):
|
||
resolved = _registry(tmp_path).resolve_analysis_handoff_request(
|
||
"执行亚家族分类",
|
||
workflow_id="gene_family",
|
||
guidance=True,
|
||
)
|
||
|
||
assert resolved.startswith("执行亚家族分类\n")
|
||
assert "执行数据准备(genome_prepare)" not in resolved
|
||
assert "目标物种 Ft" in resolved
|
||
assert "参考物种 At" in resolved
|
||
assert "正式 config.xlsx 已确认" in resolved
|
||
|
||
|
||
def test_genome_prepare_manifest_does_not_change_analysis_handoff(tmp_path):
|
||
job_id = "job-manifest-independent-handoff"
|
||
registry = _registry(tmp_path, job_id=job_id)
|
||
before = registry.resolve_analysis_handoff_request(
|
||
"执行亚家族分类",
|
||
workflow_id="gene_family",
|
||
guidance=True,
|
||
)
|
||
final_dir = tmp_path / "workspace" / job_id / "final"
|
||
final_dir.mkdir(parents=True)
|
||
(final_dir / "genome_prepare.genome_prepare.manifest.json").write_text(
|
||
json.dumps({"stage": "genome_prepare", "status": "success"}),
|
||
encoding="utf-8",
|
||
)
|
||
|
||
after = registry.resolve_analysis_handoff_request(
|
||
"执行亚家族分类",
|
||
workflow_id="gene_family",
|
||
guidance=True,
|
||
)
|
||
|
||
assert after == before
|
||
|
||
|
||
def test_explicit_data_preparation_request_is_preserved(tmp_path):
|
||
resolved = _registry(tmp_path).resolve_analysis_handoff_request(
|
||
"执行数据准备",
|
||
workflow_id="data_preparation",
|
||
guidance=False,
|
||
)
|
||
|
||
assert resolved.startswith("执行数据准备\n")
|
||
assert "当前业务动作已由数据准备契约唯一确定" not in resolved
|
||
|
||
|
||
def test_next_step_question_is_not_rewritten_to_genome_prepare(tmp_path):
|
||
resolved = _registry(tmp_path).resolve_analysis_handoff_request(
|
||
"接下来需要做什么?",
|
||
workflow_id="gene_family",
|
||
guidance=True,
|
||
)
|
||
|
||
assert resolved.startswith("接下来需要做什么?\n")
|
||
assert "执行数据准备(genome_prepare)" not in resolved
|
||
|
||
|
||
def test_bound_analysis_intent_uses_default_language(monkeypatch, tmp_path):
|
||
captured_queries = []
|
||
|
||
async def fake_execute(_self, state, message):
|
||
captured_queries.append(message.payload["query"])
|
||
state.results["results"] = {
|
||
"intent": {
|
||
"gene_family": "SPL",
|
||
"stages": ["ppi", "kaks"],
|
||
"primary_stage": "ppi",
|
||
}
|
||
}
|
||
return state
|
||
|
||
monkeypatch.setattr(IntentAgentV2, "execute", fake_execute)
|
||
result = json.loads(
|
||
asyncio.run(
|
||
_registry(tmp_path).dispatch(
|
||
"recognize_analysis_intent",
|
||
json.dumps({"query": "执行Ft的PPI和kaks分析"}, ensure_ascii=False),
|
||
)
|
||
)
|
||
)
|
||
|
||
assert result["ok"] is True
|
||
assert result["data"]["stages"] == ["ppi", "kaks"]
|
||
assert captured_queries[0].startswith("执行Ft的PPI和kaks分析\n")
|