mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-11 00:58:30 +00:00
Fixing interpolation imports
This commit is contained in:
@@ -25,7 +25,7 @@ from crewai.tools.base_tool import BaseTool, Tool
|
|||||||
from crewai.utilities import I18N, Logger, RPMController
|
from crewai.utilities import I18N, Logger, RPMController
|
||||||
from crewai.utilities.config import process_config
|
from crewai.utilities.config import process_config
|
||||||
from crewai.utilities.converter import Converter
|
from crewai.utilities.converter import Converter
|
||||||
from crewai.utilities.formatter import interpolate_only
|
from crewai.utilities.string_utils import interpolate_only
|
||||||
|
|
||||||
T = TypeVar("T", bound="BaseAgent")
|
T = TypeVar("T", bound="BaseAgent")
|
||||||
|
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ from crewai.utilities.events import (
|
|||||||
TaskStartedEvent,
|
TaskStartedEvent,
|
||||||
)
|
)
|
||||||
from crewai.utilities.events.crewai_event_bus import crewai_event_bus
|
from crewai.utilities.events.crewai_event_bus import crewai_event_bus
|
||||||
from crewai.utilities.formatter import interpolate_only
|
|
||||||
from crewai.utilities.i18n import I18N
|
from crewai.utilities.i18n import I18N
|
||||||
from crewai.utilities.printer import Printer
|
from crewai.utilities.printer import Printer
|
||||||
|
from crewai.utilities.string_utils import interpolate_only
|
||||||
|
|
||||||
|
|
||||||
class Task(BaseModel):
|
class Task(BaseModel):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import re
|
import re
|
||||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
from typing import TYPE_CHECKING, List
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from crewai.task import Task
|
from crewai.task import Task
|
||||||
@@ -20,83 +20,3 @@ def aggregate_raw_outputs_from_tasks(tasks: List["Task"]) -> str:
|
|||||||
task_outputs = [task.output for task in tasks if task.output is not None]
|
task_outputs = [task.output for task in tasks if task.output is not None]
|
||||||
|
|
||||||
return aggregate_raw_outputs_from_task_outputs(task_outputs)
|
return aggregate_raw_outputs_from_task_outputs(task_outputs)
|
||||||
|
|
||||||
|
|
||||||
def interpolate_only(
|
|
||||||
input_string: Optional[str],
|
|
||||||
inputs: Dict[str, Union[str, int, float, Dict[str, Any], List[Any]]],
|
|
||||||
) -> str:
|
|
||||||
"""Interpolate placeholders (e.g., {key}) in a string while leaving JSON untouched.
|
|
||||||
Only interpolates placeholders that follow the pattern {variable_name} where
|
|
||||||
variable_name starts with a letter/underscore and contains only letters, numbers, and underscores.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
input_string: The string containing template variables to interpolate.
|
|
||||||
Can be None or empty, in which case an empty string is returned.
|
|
||||||
inputs: Dictionary mapping template variables to their values.
|
|
||||||
Supported value types are strings, integers, floats, and dicts/lists
|
|
||||||
containing only these types and other nested dicts/lists.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The interpolated string with all template variables replaced with their values.
|
|
||||||
Empty string if input_string is None or empty.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
ValueError: If a value contains unsupported types or a template variable is missing
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Validation function for recursive type checking
|
|
||||||
def validate_type(value: Any) -> None:
|
|
||||||
if value is None:
|
|
||||||
return
|
|
||||||
if isinstance(value, (str, int, float, bool)):
|
|
||||||
return
|
|
||||||
if isinstance(value, (dict, list)):
|
|
||||||
for item in value.values() if isinstance(value, dict) else value:
|
|
||||||
validate_type(item)
|
|
||||||
return
|
|
||||||
raise ValueError(
|
|
||||||
f"Unsupported type {type(value).__name__} in inputs. "
|
|
||||||
"Only str, int, float, bool, dict, and list are allowed."
|
|
||||||
)
|
|
||||||
|
|
||||||
# Validate all input values
|
|
||||||
for key, value in inputs.items():
|
|
||||||
try:
|
|
||||||
validate_type(value)
|
|
||||||
except ValueError as e:
|
|
||||||
raise ValueError(f"Invalid value for key '{key}': {str(e)}") from e
|
|
||||||
|
|
||||||
if input_string is None or not input_string:
|
|
||||||
return ""
|
|
||||||
if "{" not in input_string and "}" not in input_string:
|
|
||||||
return input_string
|
|
||||||
if not inputs:
|
|
||||||
raise ValueError(
|
|
||||||
"Inputs dictionary cannot be empty when interpolating variables"
|
|
||||||
)
|
|
||||||
|
|
||||||
# The regex pattern to find valid variable placeholders
|
|
||||||
# Matches {variable_name} where variable_name starts with a letter/underscore
|
|
||||||
# and contains only letters, numbers, and underscores
|
|
||||||
pattern = r"\{([A-Za-z_][A-Za-z0-9_]*)\}"
|
|
||||||
|
|
||||||
# Find all matching variables in the input string
|
|
||||||
variables = re.findall(pattern, input_string)
|
|
||||||
result = input_string
|
|
||||||
|
|
||||||
# Check if all variables exist in inputs
|
|
||||||
missing_vars = [var for var in variables if var not in inputs]
|
|
||||||
if missing_vars:
|
|
||||||
raise KeyError(
|
|
||||||
f"Template variable '{missing_vars[0]}' not found in inputs dictionary"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Replace each variable with its value
|
|
||||||
for var in variables:
|
|
||||||
if var in inputs:
|
|
||||||
placeholder = "{" + var + "}"
|
|
||||||
value = str(inputs[var])
|
|
||||||
result = result.replace(placeholder, value)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|||||||
82
src/crewai/utilities/string_utils.py
Normal file
82
src/crewai/utilities/string_utils.py
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import re
|
||||||
|
from typing import Any, Dict, List, Optional, Union
|
||||||
|
|
||||||
|
|
||||||
|
def interpolate_only(
|
||||||
|
input_string: Optional[str],
|
||||||
|
inputs: Dict[str, Union[str, int, float, Dict[str, Any], List[Any]]],
|
||||||
|
) -> str:
|
||||||
|
"""Interpolate placeholders (e.g., {key}) in a string while leaving JSON untouched.
|
||||||
|
Only interpolates placeholders that follow the pattern {variable_name} where
|
||||||
|
variable_name starts with a letter/underscore and contains only letters, numbers, and underscores.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_string: The string containing template variables to interpolate.
|
||||||
|
Can be None or empty, in which case an empty string is returned.
|
||||||
|
inputs: Dictionary mapping template variables to their values.
|
||||||
|
Supported value types are strings, integers, floats, and dicts/lists
|
||||||
|
containing only these types and other nested dicts/lists.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The interpolated string with all template variables replaced with their values.
|
||||||
|
Empty string if input_string is None or empty.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If a value contains unsupported types or a template variable is missing
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Validation function for recursive type checking
|
||||||
|
def validate_type(value: Any) -> None:
|
||||||
|
if value is None:
|
||||||
|
return
|
||||||
|
if isinstance(value, (str, int, float, bool)):
|
||||||
|
return
|
||||||
|
if isinstance(value, (dict, list)):
|
||||||
|
for item in value.values() if isinstance(value, dict) else value:
|
||||||
|
validate_type(item)
|
||||||
|
return
|
||||||
|
raise ValueError(
|
||||||
|
f"Unsupported type {type(value).__name__} in inputs. "
|
||||||
|
"Only str, int, float, bool, dict, and list are allowed."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Validate all input values
|
||||||
|
for key, value in inputs.items():
|
||||||
|
try:
|
||||||
|
validate_type(value)
|
||||||
|
except ValueError as e:
|
||||||
|
raise ValueError(f"Invalid value for key '{key}': {str(e)}") from e
|
||||||
|
|
||||||
|
if input_string is None or not input_string:
|
||||||
|
return ""
|
||||||
|
if "{" not in input_string and "}" not in input_string:
|
||||||
|
return input_string
|
||||||
|
if not inputs:
|
||||||
|
raise ValueError(
|
||||||
|
"Inputs dictionary cannot be empty when interpolating variables"
|
||||||
|
)
|
||||||
|
|
||||||
|
# The regex pattern to find valid variable placeholders
|
||||||
|
# Matches {variable_name} where variable_name starts with a letter/underscore
|
||||||
|
# and contains only letters, numbers, and underscores
|
||||||
|
pattern = r"\{([A-Za-z_][A-Za-z0-9_]*)\}"
|
||||||
|
|
||||||
|
# Find all matching variables in the input string
|
||||||
|
variables = re.findall(pattern, input_string)
|
||||||
|
result = input_string
|
||||||
|
|
||||||
|
# Check if all variables exist in inputs
|
||||||
|
missing_vars = [var for var in variables if var not in inputs]
|
||||||
|
if missing_vars:
|
||||||
|
raise KeyError(
|
||||||
|
f"Template variable '{missing_vars[0]}' not found in inputs dictionary"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Replace each variable with its value
|
||||||
|
for var in variables:
|
||||||
|
if var in inputs:
|
||||||
|
placeholder = "{" + var + "}"
|
||||||
|
value = str(inputs[var])
|
||||||
|
result = result.replace(placeholder, value)
|
||||||
|
|
||||||
|
return result
|
||||||
@@ -15,6 +15,7 @@ from crewai import Agent, Crew, Process, Task
|
|||||||
from crewai.tasks.conditional_task import ConditionalTask
|
from crewai.tasks.conditional_task import ConditionalTask
|
||||||
from crewai.tasks.task_output import TaskOutput
|
from crewai.tasks.task_output import TaskOutput
|
||||||
from crewai.utilities.converter import Converter
|
from crewai.utilities.converter import Converter
|
||||||
|
from crewai.utilities.string_utils import interpolate_only
|
||||||
|
|
||||||
|
|
||||||
def test_task_tool_reflect_agent_tools():
|
def test_task_tool_reflect_agent_tools():
|
||||||
@@ -822,7 +823,7 @@ def test_interpolate_only():
|
|||||||
|
|
||||||
# Test JSON structure preservation
|
# Test JSON structure preservation
|
||||||
json_string = '{"info": "Look at {placeholder}", "nested": {"val": "{nestedVal}"}}'
|
json_string = '{"info": "Look at {placeholder}", "nested": {"val": "{nestedVal}"}}'
|
||||||
result = task.interpolate_only(
|
result = interpolate_only(
|
||||||
input_string=json_string,
|
input_string=json_string,
|
||||||
inputs={"placeholder": "the data", "nestedVal": "something else"},
|
inputs={"placeholder": "the data", "nestedVal": "something else"},
|
||||||
)
|
)
|
||||||
@@ -833,20 +834,18 @@ def test_interpolate_only():
|
|||||||
|
|
||||||
# Test normal string interpolation
|
# Test normal string interpolation
|
||||||
normal_string = "Hello {name}, welcome to {place}!"
|
normal_string = "Hello {name}, welcome to {place}!"
|
||||||
result = task.interpolate_only(
|
result = interpolate_only(
|
||||||
input_string=normal_string, inputs={"name": "John", "place": "CrewAI"}
|
input_string=normal_string, inputs={"name": "John", "place": "CrewAI"}
|
||||||
)
|
)
|
||||||
assert result == "Hello John, welcome to CrewAI!"
|
assert result == "Hello John, welcome to CrewAI!"
|
||||||
|
|
||||||
# Test empty string
|
# Test empty string
|
||||||
result = task.interpolate_only(input_string="", inputs={"unused": "value"})
|
result = interpolate_only(input_string="", inputs={"unused": "value"})
|
||||||
assert result == ""
|
assert result == ""
|
||||||
|
|
||||||
# Test string with no placeholders
|
# Test string with no placeholders
|
||||||
no_placeholders = "Hello, this is a test"
|
no_placeholders = "Hello, this is a test"
|
||||||
result = task.interpolate_only(
|
result = interpolate_only(input_string=no_placeholders, inputs={"unused": "value"})
|
||||||
input_string=no_placeholders, inputs={"unused": "value"}
|
|
||||||
)
|
|
||||||
assert result == no_placeholders
|
assert result == no_placeholders
|
||||||
|
|
||||||
|
|
||||||
@@ -858,7 +857,7 @@ def test_interpolate_only_with_dict_inside_expected_output():
|
|||||||
)
|
)
|
||||||
|
|
||||||
json_string = '{"questions": {"main_question": "What is the user\'s name?", "secondary_question": "What is the user\'s age?"}}'
|
json_string = '{"questions": {"main_question": "What is the user\'s name?", "secondary_question": "What is the user\'s age?"}}'
|
||||||
result = task.interpolate_only(
|
result = interpolate_only(
|
||||||
input_string=json_string,
|
input_string=json_string,
|
||||||
inputs={
|
inputs={
|
||||||
"questions": {
|
"questions": {
|
||||||
@@ -872,18 +871,16 @@ def test_interpolate_only_with_dict_inside_expected_output():
|
|||||||
assert result == json_string
|
assert result == json_string
|
||||||
|
|
||||||
normal_string = "Hello {name}, welcome to {place}!"
|
normal_string = "Hello {name}, welcome to {place}!"
|
||||||
result = task.interpolate_only(
|
result = interpolate_only(
|
||||||
input_string=normal_string, inputs={"name": "John", "place": "CrewAI"}
|
input_string=normal_string, inputs={"name": "John", "place": "CrewAI"}
|
||||||
)
|
)
|
||||||
assert result == "Hello John, welcome to CrewAI!"
|
assert result == "Hello John, welcome to CrewAI!"
|
||||||
|
|
||||||
result = task.interpolate_only(input_string="", inputs={"unused": "value"})
|
result = interpolate_only(input_string="", inputs={"unused": "value"})
|
||||||
assert result == ""
|
assert result == ""
|
||||||
|
|
||||||
no_placeholders = "Hello, this is a test"
|
no_placeholders = "Hello, this is a test"
|
||||||
result = task.interpolate_only(
|
result = interpolate_only(input_string=no_placeholders, inputs={"unused": "value"})
|
||||||
input_string=no_placeholders, inputs={"unused": "value"}
|
|
||||||
)
|
|
||||||
assert result == no_placeholders
|
assert result == no_placeholders
|
||||||
|
|
||||||
|
|
||||||
@@ -1085,12 +1082,12 @@ def test_interpolate_with_list_of_strings():
|
|||||||
# Test simple list of strings
|
# Test simple list of strings
|
||||||
input_str = "Available items: {items}"
|
input_str = "Available items: {items}"
|
||||||
inputs = {"items": ["apple", "banana", "cherry"]}
|
inputs = {"items": ["apple", "banana", "cherry"]}
|
||||||
result = task.interpolate_only(input_str, inputs)
|
result = interpolate_only(input_str, inputs)
|
||||||
assert result == f"Available items: {inputs['items']}"
|
assert result == f"Available items: {inputs['items']}"
|
||||||
|
|
||||||
# Test empty list
|
# Test empty list
|
||||||
empty_list_input = {"items": []}
|
empty_list_input = {"items": []}
|
||||||
result = task.interpolate_only(input_str, empty_list_input)
|
result = interpolate_only(input_str, empty_list_input)
|
||||||
assert result == "Available items: []"
|
assert result == "Available items: []"
|
||||||
|
|
||||||
|
|
||||||
@@ -1106,7 +1103,7 @@ def test_interpolate_with_list_of_dicts():
|
|||||||
{"name": "Bob", "age": 25, "skills": ["Java", "Cloud"]},
|
{"name": "Bob", "age": 25, "skills": ["Java", "Cloud"]},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
result = task.interpolate_only("{people}", input_data)
|
result = interpolate_only("{people}", input_data)
|
||||||
|
|
||||||
parsed_result = eval(result)
|
parsed_result = eval(result)
|
||||||
assert isinstance(parsed_result, list)
|
assert isinstance(parsed_result, list)
|
||||||
@@ -1138,7 +1135,7 @@ def test_interpolate_with_nested_structures():
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = task.interpolate_only("{company}", input_data)
|
result = interpolate_only("{company}", input_data)
|
||||||
parsed = eval(result)
|
parsed = eval(result)
|
||||||
|
|
||||||
assert parsed["name"] == "TechCorp"
|
assert parsed["name"] == "TechCorp"
|
||||||
@@ -1161,7 +1158,7 @@ def test_interpolate_with_special_characters():
|
|||||||
"empty": "",
|
"empty": "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = task.interpolate_only("{special_data}", input_data)
|
result = interpolate_only("{special_data}", input_data)
|
||||||
parsed = eval(result)
|
parsed = eval(result)
|
||||||
|
|
||||||
assert parsed["quotes"] == """This has "double" and 'single' quotes"""
|
assert parsed["quotes"] == """This has "double" and 'single' quotes"""
|
||||||
@@ -1188,7 +1185,7 @@ def test_interpolate_mixed_types():
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = task.interpolate_only("{data}", input_data)
|
result = interpolate_only("{data}", input_data)
|
||||||
parsed = eval(result)
|
parsed = eval(result)
|
||||||
|
|
||||||
assert parsed["name"] == "Test Dataset"
|
assert parsed["name"] == "Test Dataset"
|
||||||
@@ -1216,7 +1213,7 @@ def test_interpolate_complex_combination():
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
result = task.interpolate_only("{report}", input_data)
|
result = interpolate_only("{report}", input_data)
|
||||||
parsed = eval(result)
|
parsed = eval(result)
|
||||||
|
|
||||||
assert len(parsed) == 2
|
assert len(parsed) == 2
|
||||||
@@ -1233,7 +1230,7 @@ def test_interpolate_invalid_type_validation():
|
|||||||
|
|
||||||
# Test with invalid top-level type
|
# Test with invalid top-level type
|
||||||
with pytest.raises(ValueError) as excinfo:
|
with pytest.raises(ValueError) as excinfo:
|
||||||
task.interpolate_only("{data}", {"data": set()}) # type: ignore we are purposely testing this failure
|
interpolate_only("{data}", {"data": set()}) # type: ignore we are purposely testing this failure
|
||||||
|
|
||||||
assert "Unsupported type set" in str(excinfo.value)
|
assert "Unsupported type set" in str(excinfo.value)
|
||||||
|
|
||||||
@@ -1246,7 +1243,7 @@ def test_interpolate_invalid_type_validation():
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
with pytest.raises(ValueError) as excinfo:
|
with pytest.raises(ValueError) as excinfo:
|
||||||
task.interpolate_only("{data}", {"data": invalid_nested})
|
interpolate_only("{data}", {"data": invalid_nested})
|
||||||
assert "Unsupported type set" in str(excinfo.value)
|
assert "Unsupported type set" in str(excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
@@ -1265,24 +1262,22 @@ def test_interpolate_custom_object_validation():
|
|||||||
|
|
||||||
# Test with custom object at top level
|
# Test with custom object at top level
|
||||||
with pytest.raises(ValueError) as excinfo:
|
with pytest.raises(ValueError) as excinfo:
|
||||||
task.interpolate_only("{obj}", {"obj": CustomObject(5)}) # type: ignore we are purposely testing this failure
|
interpolate_only("{obj}", {"obj": CustomObject(5)}) # type: ignore we are purposely testing this failure
|
||||||
assert "Unsupported type CustomObject" in str(excinfo.value)
|
assert "Unsupported type CustomObject" in str(excinfo.value)
|
||||||
|
|
||||||
# Test with nested custom object in dictionary
|
# Test with nested custom object in dictionary
|
||||||
with pytest.raises(ValueError) as excinfo:
|
with pytest.raises(ValueError) as excinfo:
|
||||||
task.interpolate_only(
|
interpolate_only("{data}", {"data": {"valid": 1, "invalid": CustomObject(5)}})
|
||||||
"{data}", {"data": {"valid": 1, "invalid": CustomObject(5)}}
|
|
||||||
)
|
|
||||||
assert "Unsupported type CustomObject" in str(excinfo.value)
|
assert "Unsupported type CustomObject" in str(excinfo.value)
|
||||||
|
|
||||||
# Test with nested custom object in list
|
# Test with nested custom object in list
|
||||||
with pytest.raises(ValueError) as excinfo:
|
with pytest.raises(ValueError) as excinfo:
|
||||||
task.interpolate_only("{data}", {"data": [1, "valid", CustomObject(5)]})
|
interpolate_only("{data}", {"data": [1, "valid", CustomObject(5)]})
|
||||||
assert "Unsupported type CustomObject" in str(excinfo.value)
|
assert "Unsupported type CustomObject" in str(excinfo.value)
|
||||||
|
|
||||||
# Test with deeply nested custom object
|
# Test with deeply nested custom object
|
||||||
with pytest.raises(ValueError) as excinfo:
|
with pytest.raises(ValueError) as excinfo:
|
||||||
task.interpolate_only(
|
interpolate_only(
|
||||||
"{data}", {"data": {"level1": {"level2": [{"level3": CustomObject(5)}]}}}
|
"{data}", {"data": {"level1": {"level2": [{"level3": CustomObject(5)}]}}}
|
||||||
)
|
)
|
||||||
assert "Unsupported type CustomObject" in str(excinfo.value)
|
assert "Unsupported type CustomObject" in str(excinfo.value)
|
||||||
@@ -1306,7 +1301,7 @@ def test_interpolate_valid_complex_types():
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Should not raise any errors
|
# Should not raise any errors
|
||||||
result = task.interpolate_only("{data}", {"data": valid_data})
|
result = interpolate_only("{data}", {"data": valid_data})
|
||||||
parsed = eval(result)
|
parsed = eval(result)
|
||||||
assert parsed["name"] == "Valid Dataset"
|
assert parsed["name"] == "Valid Dataset"
|
||||||
assert parsed["stats"]["nested"]["deeper"]["b"] == 2.5
|
assert parsed["stats"]["nested"]["deeper"]["b"] == 2.5
|
||||||
@@ -1319,16 +1314,16 @@ def test_interpolate_edge_cases():
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Test empty dict and list
|
# Test empty dict and list
|
||||||
assert task.interpolate_only("{}", {"data": {}}) == "{}"
|
assert interpolate_only("{}", {"data": {}}) == "{}"
|
||||||
assert task.interpolate_only("[]", {"data": []}) == "[]"
|
assert interpolate_only("[]", {"data": []}) == "[]"
|
||||||
|
|
||||||
# Test numeric types
|
# Test numeric types
|
||||||
assert task.interpolate_only("{num}", {"num": 42}) == "42"
|
assert interpolate_only("{num}", {"num": 42}) == "42"
|
||||||
assert task.interpolate_only("{num}", {"num": 3.14}) == "3.14"
|
assert interpolate_only("{num}", {"num": 3.14}) == "3.14"
|
||||||
|
|
||||||
# Test boolean values (valid JSON types)
|
# Test boolean values (valid JSON types)
|
||||||
assert task.interpolate_only("{flag}", {"flag": True}) == "True"
|
assert interpolate_only("{flag}", {"flag": True}) == "True"
|
||||||
assert task.interpolate_only("{flag}", {"flag": False}) == "False"
|
assert interpolate_only("{flag}", {"flag": False}) == "False"
|
||||||
|
|
||||||
|
|
||||||
def test_interpolate_valid_types():
|
def test_interpolate_valid_types():
|
||||||
@@ -1346,7 +1341,7 @@ def test_interpolate_valid_types():
|
|||||||
"nested": {"flag": True, "empty": None},
|
"nested": {"flag": True, "empty": None},
|
||||||
}
|
}
|
||||||
|
|
||||||
result = task.interpolate_only("{data}", {"data": valid_data})
|
result = interpolate_only("{data}", {"data": valid_data})
|
||||||
parsed = eval(result)
|
parsed = eval(result)
|
||||||
|
|
||||||
assert parsed["active"] is True
|
assert parsed["active"] is True
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from typing import Any, Dict, List, Union
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from crewai.utilities.formatter import interpolate_only
|
from crewai.utilities.string_utils import interpolate_only
|
||||||
|
|
||||||
|
|
||||||
class TestInterpolateOnly:
|
class TestInterpolateOnly:
|
||||||
Reference in New Issue
Block a user