mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-19 04:14:46 +08:00
fix: the exception of plan validation (#714)
* fix: Missing Required Fields in Plan Validation * fix: the exception of plan validation * Fixed the test errors * Addressed the comments of the PR reviews
This commit is contained in:
@@ -167,8 +167,8 @@ class TestValidateAndFixPlanStepTypeRepair:
|
||||
validate_and_fix_plan(plan)
|
||||
# Should log repair operation
|
||||
mock_logger.info.assert_called()
|
||||
call_args = str(mock_logger.info.call_args)
|
||||
assert "Repaired missing step_type" in call_args
|
||||
# Check that any of the info calls contains "Repaired missing step_type"
|
||||
assert any("Repaired missing step_type" in str(call) for call in mock_logger.info.call_args_list)
|
||||
|
||||
def test_non_dict_plan_returns_unchanged(self):
|
||||
"""Test that non-dict plans are returned unchanged."""
|
||||
@@ -363,6 +363,154 @@ class TestValidateAndFixPlanIntegration:
|
||||
assert result["steps"][1]["need_search"] is False
|
||||
|
||||
|
||||
class TestValidateAndFixPlanIssue710:
|
||||
"""Specific tests for Issue #710 scenarios - missing required Plan fields."""
|
||||
|
||||
def test_missing_locale_field_added(self):
|
||||
"""Test that missing locale field is added with default value."""
|
||||
plan = {
|
||||
"has_enough_context": True,
|
||||
"title": "Test Plan",
|
||||
"steps": []
|
||||
}
|
||||
|
||||
result = validate_and_fix_plan(plan)
|
||||
|
||||
assert "locale" in result
|
||||
assert result["locale"] == "en-US"
|
||||
|
||||
def test_empty_locale_field_replaced(self):
|
||||
"""Test that empty locale field is replaced with default value."""
|
||||
plan = {
|
||||
"locale": "",
|
||||
"has_enough_context": True,
|
||||
"title": "Test Plan",
|
||||
"steps": []
|
||||
}
|
||||
|
||||
result = validate_and_fix_plan(plan)
|
||||
|
||||
assert "locale" in result
|
||||
assert result["locale"] == "en-US"
|
||||
|
||||
def test_missing_has_enough_context_field_added(self):
|
||||
"""Test that missing has_enough_context field is added with default value."""
|
||||
plan = {
|
||||
"locale": "en-US",
|
||||
"title": "Test Plan",
|
||||
"steps": []
|
||||
}
|
||||
|
||||
result = validate_and_fix_plan(plan)
|
||||
|
||||
assert "has_enough_context" in result
|
||||
assert result["has_enough_context"] is False
|
||||
|
||||
def test_missing_title_field_added_from_step(self):
|
||||
"""Test that missing title field is inferred from first step."""
|
||||
plan = {
|
||||
"locale": "en-US",
|
||||
"has_enough_context": True,
|
||||
"steps": [
|
||||
{
|
||||
"need_search": True,
|
||||
"title": "Step Title",
|
||||
"description": "Step description",
|
||||
"step_type": "research"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
result = validate_and_fix_plan(plan)
|
||||
|
||||
assert "title" in result
|
||||
assert result["title"] == "Step Title"
|
||||
|
||||
def test_missing_title_field_added_default(self):
|
||||
"""Test that missing title field is added with default when no steps available."""
|
||||
plan = {
|
||||
"locale": "en-US",
|
||||
"has_enough_context": True,
|
||||
"steps": []
|
||||
}
|
||||
|
||||
result = validate_and_fix_plan(plan)
|
||||
|
||||
assert "title" in result
|
||||
assert result["title"] == "Research Plan"
|
||||
|
||||
def test_all_required_fields_missing(self):
|
||||
"""Test that all missing required fields are added."""
|
||||
plan = {
|
||||
"steps": [
|
||||
{
|
||||
"need_search": True,
|
||||
"title": "Step 1",
|
||||
"description": "Description",
|
||||
"step_type": "research"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
result = validate_and_fix_plan(plan)
|
||||
|
||||
# All required fields should be present
|
||||
assert "locale" in result
|
||||
assert "has_enough_context" in result
|
||||
assert "title" in result
|
||||
|
||||
# With appropriate defaults
|
||||
assert result["locale"] == "en-US"
|
||||
assert result["has_enough_context"] is False
|
||||
assert result["title"] == "Step 1" # Inferred from first step
|
||||
|
||||
def test_issue_710_scenario_passes_pydantic_validation(self):
|
||||
"""Test that fixed plan can be validated by Pydantic schema (reproduces issue #710 fix)."""
|
||||
from src.prompts.planner_model import Plan as PlanModel
|
||||
|
||||
# Simulate the problematic plan from issue #710 that's missing required fields
|
||||
plan = {
|
||||
"content": '{\n "locale": "en-US",\n "has_enough_context": false,\n "title": "Test Plan",\n "steps": [\n {\n "need_search": true,\n "title": "Research Step",\n "description": "Gather data",\n "step_type": "research"\n }\n ]\n}',
|
||||
"reasoning": 2368
|
||||
}
|
||||
|
||||
# Extract just the JSON part (simulating what would happen in the actual flow)
|
||||
import json
|
||||
json_content = json.loads(plan["content"])
|
||||
|
||||
# Remove required fields to simulate the issue
|
||||
del json_content["locale"]
|
||||
del json_content["has_enough_context"]
|
||||
del json_content["title"]
|
||||
|
||||
# First validate and fix
|
||||
fixed_plan = validate_and_fix_plan(json_content)
|
||||
|
||||
# Then try Pydantic validation (should not raise)
|
||||
validated = PlanModel.model_validate(fixed_plan)
|
||||
|
||||
# Validation should succeed
|
||||
assert validated.locale == "en-US"
|
||||
assert validated.has_enough_context is False
|
||||
assert validated.title == "Research Step" # Inferred from first step
|
||||
|
||||
def test_existing_fields_preserved(self):
|
||||
"""Test that existing valid fields are preserved."""
|
||||
plan = {
|
||||
"locale": "zh-CN",
|
||||
"has_enough_context": True,
|
||||
"title": "Existing Title",
|
||||
"steps": []
|
||||
}
|
||||
|
||||
result = validate_and_fix_plan(plan)
|
||||
|
||||
# Existing values should be preserved
|
||||
assert result["locale"] == "zh-CN"
|
||||
assert result["has_enough_context"] is True
|
||||
assert result["title"] == "Existing Title"
|
||||
|
||||
|
||||
class TestValidateAndFixPlanIssue650:
|
||||
"""Specific tests for Issue #650 scenarios."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user