mirror of
https://github.com/hoshikawa2/agent_platform_oci.git
synced 2026-11-06 03:14:12 +00:00
bugfix: Multi-item
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
51
tests/test_multi_item_documentation.py
Normal file
51
tests/test_multi_item_documentation.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def test_multi_item_guide_documents_runtime_contract():
|
||||
text = (ROOT / "docs" / "MCP_MULTI_ITEM_DEVELOPER_GUIDE.md").read_text(encoding="utf-8")
|
||||
for token in (
|
||||
"type: array",
|
||||
"resolved_arguments",
|
||||
"results[]",
|
||||
"PARTIAL_SUCCESS",
|
||||
"workflow.output[tool_name].results",
|
||||
"eligible: false",
|
||||
"Não faça loop de negócio no agente.",
|
||||
):
|
||||
assert token in text
|
||||
|
||||
|
||||
def test_multi_item_guide_is_discoverable_from_main_entry_points():
|
||||
for path in (
|
||||
ROOT / "README.md",
|
||||
ROOT / "Documentacao" / "README_MCP.md",
|
||||
ROOT / "docs" / "developer" / "pt" / "INDEX_DEVELOPER_GUIDE.md",
|
||||
ROOT / "templates" / "agent_template_backend" / "README.md",
|
||||
):
|
||||
assert "MCP_MULTI_ITEM" in path.read_text(encoding="utf-8") or "MCP multi-item" in path.read_text(encoding="utf-8") or "MCP Multi-item" in path.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_multi_item_is_discoverable_from_tuning_performance():
|
||||
tuning_index = (ROOT / "Tuning-Performance" / "README.md").read_text(encoding="utf-8")
|
||||
tuning_readme = (ROOT / "Tuning-Performance" / "Multi_Item_MCP" / "README.md").read_text(encoding="utf-8")
|
||||
implementation = (ROOT / "Tuning-Performance" / "Multi_Item_MCP" / "IMPLEMENTACAO_MULTI_ITEM_MCP.md").read_text(encoding="utf-8")
|
||||
|
||||
assert "Multi_Item_MCP" in tuning_index
|
||||
for token in (
|
||||
"tools.yaml",
|
||||
"tool_policies.yaml",
|
||||
"results[]",
|
||||
"PARTIAL_SUCCESS",
|
||||
"NÃO cria motor multi-item",
|
||||
):
|
||||
assert token in tuning_readme
|
||||
|
||||
for token in (
|
||||
"MCP Server ou workflow",
|
||||
"success",
|
||||
"PARTIAL_SUCCESS",
|
||||
"Checklist do desenvolvedor",
|
||||
):
|
||||
assert token in implementation
|
||||
87
tests/test_multi_item_result_normalization.py
Normal file
87
tests/test_multi_item_result_normalization.py
Normal file
@@ -0,0 +1,87 @@
|
||||
from agent_framework.runtime.agent_runtime import AgentRuntimeMixin
|
||||
|
||||
|
||||
def _workflow_result(*, items, ok=False, error="secondary step failed"):
|
||||
return {
|
||||
"tool_name": "cancelar_vas_avulso",
|
||||
"ok": ok,
|
||||
"result": {
|
||||
"status": "COMPLETED",
|
||||
"output": {
|
||||
"cancelar_vas_avulso": {
|
||||
"success": all(bool(item.get("success")) for item in items),
|
||||
"results": items,
|
||||
},
|
||||
"secondary_step": {"success": False, "error": error},
|
||||
},
|
||||
},
|
||||
"error": error,
|
||||
"metadata": {"workflow_status": "COMPLETED"},
|
||||
}
|
||||
|
||||
|
||||
def test_multi_item_partial_success_preserves_successful_items():
|
||||
raw = _workflow_result(items=[
|
||||
{"subject": "A", "success": True},
|
||||
{"subject": "B", "success": False, "reason": "not_found"},
|
||||
{"subject": "C", "success": True},
|
||||
])
|
||||
|
||||
result = AgentRuntimeMixin._normalize_multi_item_tool_result("cancelar_vas_avulso", raw)
|
||||
|
||||
assert result["ok"] is True
|
||||
assert result["original_ok"] is False
|
||||
assert result["partial_success"] is True
|
||||
assert result["multi_item_status"] == "PARTIAL_SUCCESS"
|
||||
assert result["metadata"]["multi_item"] == {
|
||||
"status": "PARTIAL_SUCCESS",
|
||||
"items_count": 3,
|
||||
"items_succeeded_count": 2,
|
||||
"items_failed_count": 1,
|
||||
"primary_tool": "cancelar_vas_avulso",
|
||||
}
|
||||
assert result["secondary_error"] == "secondary step failed"
|
||||
assert raw["ok"] is False # normalizer is non-mutating
|
||||
|
||||
|
||||
def test_multi_item_primary_success_is_not_overwritten_by_secondary_composite_failure():
|
||||
raw = _workflow_result(items=[
|
||||
{"subject": "TIM Fashion Mensal", "success": True},
|
||||
{"subject": "Aya Audiobooks Premium", "success": True},
|
||||
{"subject": "Neymar Jr", "success": True},
|
||||
], error="Item ausente em validação posterior")
|
||||
|
||||
result = AgentRuntimeMixin._normalize_multi_item_tool_result("cancelar_vas_avulso", raw)
|
||||
|
||||
assert result["ok"] is True
|
||||
assert result["multi_item_status"] == "SUCCESS"
|
||||
assert result["partial_success"] is False
|
||||
assert result["metadata"]["multi_item"]["items_succeeded_count"] == 3
|
||||
assert result["secondary_error"] == "Item ausente em validação posterior"
|
||||
|
||||
|
||||
def test_single_item_result_does_not_change_existing_semantics():
|
||||
raw = _workflow_result(items=[{"subject": "A", "success": True}])
|
||||
result = AgentRuntimeMixin._normalize_multi_item_tool_result("cancelar_vas_avulso", raw)
|
||||
assert result == raw
|
||||
|
||||
|
||||
def test_unrelated_nested_results_do_not_override_primary_tool_failure():
|
||||
raw = {
|
||||
"tool_name": "cancelar_vas_avulso",
|
||||
"ok": False,
|
||||
"result": {
|
||||
"status": "COMPLETED",
|
||||
"output": {
|
||||
"other_tool": {
|
||||
"results": [
|
||||
{"subject": "A", "success": True},
|
||||
{"subject": "B", "success": True},
|
||||
]
|
||||
}
|
||||
},
|
||||
},
|
||||
"error": "primary tool failed",
|
||||
}
|
||||
result = AgentRuntimeMixin._normalize_multi_item_tool_result("cancelar_vas_avulso", raw)
|
||||
assert result == raw
|
||||
Reference in New Issue
Block a user