Skip to content

Commit 2709a92

Browse files
fixes interpolation issues when inputs are type dict,list specificall… (crewAIInc#1992)
* fixes interpolation issues when inputs are type dict,list specifically when defined on expected_output * improvements with type hints, doc fixes and rm print statements * more tests * test passing --------- Co-authored-by: Brandon Hancock <brandon@brandonhancock.io>
1 parent d19d7b0 commit 2709a92

File tree

2 files changed

+350
-15
lines changed

2 files changed

+350
-15
lines changed

src/crewai/task.py

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,9 @@ def _execute_core(
431431
content = (
432432
json_output
433433
if json_output
434-
else pydantic_output.model_dump_json() if pydantic_output else result
434+
else pydantic_output.model_dump_json()
435+
if pydantic_output
436+
else result
435437
)
436438
self._save_file(content)
437439

@@ -452,7 +454,7 @@ def prompt(self) -> str:
452454
return "\n".join(tasks_slices)
453455

454456
def interpolate_inputs_and_add_conversation_history(
455-
self, inputs: Dict[str, Union[str, int, float]]
457+
self, inputs: Dict[str, Union[str, int, float, Dict[str, Any], List[Any]]]
456458
) -> None:
457459
"""Interpolate inputs into the task description, expected output, and output file path.
458460
Add conversation history if present.
@@ -524,25 +526,49 @@ def interpolate_inputs_and_add_conversation_history(
524526
)
525527

526528
def interpolate_only(
527-
self, input_string: Optional[str], inputs: Dict[str, Union[str, int, float]]
529+
self,
530+
input_string: Optional[str],
531+
inputs: Dict[str, Union[str, int, float, Dict[str, Any], List[Any]]],
528532
) -> str:
529533
"""Interpolate placeholders (e.g., {key}) in a string while leaving JSON untouched.
530534
531535
Args:
532536
input_string: The string containing template variables to interpolate.
533537
Can be None or empty, in which case an empty string is returned.
534538
inputs: Dictionary mapping template variables to their values.
535-
Supported value types are strings, integers, and floats.
536-
If input_string is empty or has no placeholders, inputs can be empty.
539+
Supported value types are strings, integers, floats, and dicts/lists
540+
containing only these types and other nested dicts/lists.
537541
538542
Returns:
539543
The interpolated string with all template variables replaced with their values.
540544
Empty string if input_string is None or empty.
541545
542546
Raises:
543-
ValueError: If a required template variable is missing from inputs.
544-
KeyError: If a template variable is not found in the inputs dictionary.
547+
ValueError: If a value contains unsupported types
545548
"""
549+
550+
# Validation function for recursive type checking
551+
def validate_type(value: Any) -> None:
552+
if value is None:
553+
return
554+
if isinstance(value, (str, int, float, bool)):
555+
return
556+
if isinstance(value, (dict, list)):
557+
for item in value.values() if isinstance(value, dict) else value:
558+
validate_type(item)
559+
return
560+
raise ValueError(
561+
f"Unsupported type {type(value).__name__} in inputs. "
562+
"Only str, int, float, bool, dict, and list are allowed."
563+
)
564+
565+
# Validate all input values
566+
for key, value in inputs.items():
567+
try:
568+
validate_type(value)
569+
except ValueError as e:
570+
raise ValueError(f"Invalid value for key '{key}': {str(e)}") from e
571+
546572
if input_string is None or not input_string:
547573
return ""
548574
if "{" not in input_string and "}" not in input_string:
@@ -551,15 +577,7 @@ def interpolate_only(
551577
raise ValueError(
552578
"Inputs dictionary cannot be empty when interpolating variables"
553579
)
554-
555580
try:
556-
# Validate input types
557-
for key, value in inputs.items():
558-
if not isinstance(value, (str, int, float)):
559-
raise ValueError(
560-
f"Value for key '{key}' must be a string, integer, or float, got {type(value).__name__}"
561-
)
562-
563581
escaped_string = input_string.replace("{", "{{").replace("}", "}}")
564582

565583
for key in inputs.keys():

0 commit comments

Comments
 (0)