The output file was being written with pre-guardrail output instead of
post-guardrail output. This was because the file save logic used the
original variables (json_output, pydantic_output, result) instead of
the updated task_output object after guardrails executed.
Fixed by using task_output.json_dict, task_output.pydantic, and
task_output.raw in the file save logic for both sync (_execute_core)
and async (_aexecute_core) execution paths.
Added 5 tests to verify output file contains post-guardrail results:
- test_output_file_contains_guardrail_modified_raw_result
- test_output_file_contains_guardrail_modified_json_result
- test_output_file_contains_guardrail_modified_pydantic_result
- test_output_file_with_single_guardrail_modification
- test_output_file_with_multiple_guardrails_chained_modifications
Fixes#4156
Co-Authored-By: João <joao@crewai.com>