mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-10 16:48:30 +00:00
We’re currently using the JSON Schema standard for these fields
This commit is contained in:
@@ -44,83 +44,98 @@ def test_unwrap_schema(extractor):
|
||||
assert result["value"] == "test"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"schema, expected",
|
||||
[
|
||||
({"type": "str"}, "str"),
|
||||
({"type": "list", "items_schema": {"type": "str"}}, "list[str]"),
|
||||
({"type": "dict", "keys_schema": {"type": "str"}, "values_schema": {"type": "int"}}, "dict[str, int]"),
|
||||
({"type": "union", "choices": [{"type": "str"}, {"type": "int"}]}, "union[str, int]"),
|
||||
({"type": "custom_type"}, "custom_type"),
|
||||
({}, "unknown"),
|
||||
]
|
||||
)
|
||||
def test_schema_type_to_str(extractor, schema, expected):
|
||||
assert extractor._schema_type_to_str(schema) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"info, expected_type",
|
||||
[
|
||||
({"schema": {"type": "str"}}, "str"),
|
||||
({"schema": {"type": "nullable", "schema": {"type": "int"}}}, "int"),
|
||||
({"schema": {"type": "default", "schema": {"type": "list", "items_schema": {"type": "str"}}}}, "list[str]"),
|
||||
]
|
||||
)
|
||||
def test_extract_param_type(extractor, info, expected_type):
|
||||
assert extractor._extract_param_type(info) == expected_type
|
||||
|
||||
|
||||
def test_extract_all_tools(extractor):
|
||||
@pytest.fixture
|
||||
def mock_tool_extractor(extractor):
|
||||
with mock.patch("generate_tool_specs.dir", return_value=["MockTool"]), \
|
||||
mock.patch("generate_tool_specs.getattr", return_value=MockTool):
|
||||
extractor.extract_all_tools()
|
||||
|
||||
assert len(extractor.tools_spec) == 1
|
||||
tool_info = extractor.tools_spec[0]
|
||||
return extractor.tools_spec[0]
|
||||
|
||||
assert tool_info.keys() == {
|
||||
"name",
|
||||
"humanized_name",
|
||||
"description",
|
||||
"run_params",
|
||||
"env_vars",
|
||||
"init_params",
|
||||
"package_dependencies",
|
||||
}
|
||||
def test_extract_basic_tool_info(mock_tool_extractor):
|
||||
tool_info = mock_tool_extractor
|
||||
|
||||
assert tool_info["name"] == "MockTool"
|
||||
assert tool_info["humanized_name"] == "Mock Search Tool"
|
||||
assert tool_info["description"] == "A tool that mocks search functionality"
|
||||
assert tool_info.keys() == {
|
||||
"name",
|
||||
"humanized_name",
|
||||
"description",
|
||||
"run_params_schema",
|
||||
"env_vars",
|
||||
"init_params_schema",
|
||||
"package_dependencies",
|
||||
}
|
||||
|
||||
assert len(tool_info["env_vars"]) == 2
|
||||
api_key_var, rate_limit_var = tool_info["env_vars"]
|
||||
assert tool_info["name"] == "MockTool"
|
||||
assert tool_info["humanized_name"] == "Mock Search Tool"
|
||||
assert tool_info["description"] == "A tool that mocks search functionality"
|
||||
|
||||
assert api_key_var["name"] == "SERPER_API_KEY"
|
||||
assert api_key_var["description"] == "API key for Serper"
|
||||
assert api_key_var["required"] == True
|
||||
assert api_key_var["default"] == None
|
||||
def test_extract_init_params_schema(mock_tool_extractor):
|
||||
tool_info = mock_tool_extractor
|
||||
init_params_schema = tool_info["init_params_schema"]
|
||||
|
||||
assert rate_limit_var["name"] == "API_RATE_LIMIT"
|
||||
assert rate_limit_var["description"] == "API rate limit"
|
||||
assert rate_limit_var["required"] == False
|
||||
assert rate_limit_var["default"] == "100"
|
||||
assert init_params_schema.keys() == {
|
||||
"$defs",
|
||||
"properties",
|
||||
"title",
|
||||
"type",
|
||||
}
|
||||
|
||||
assert len(tool_info["run_params"]) == 3
|
||||
another_parameter = init_params_schema['properties']['another_parameter']
|
||||
assert another_parameter["description"] == ""
|
||||
assert another_parameter["default"] == "Another way to define a default value"
|
||||
assert another_parameter["type"] == "string"
|
||||
|
||||
params = {p["name"]: p for p in tool_info["run_params"]}
|
||||
assert params["query"]["description"] == "The query parameter"
|
||||
assert params["query"]["type"] == "str"
|
||||
assert params["query"]["default"] == ""
|
||||
my_parameter = init_params_schema['properties']['my_parameter']
|
||||
assert my_parameter["description"] == "What a description"
|
||||
assert my_parameter["default"] == "This is default value"
|
||||
assert my_parameter["type"] == "string"
|
||||
|
||||
assert params["count"]["type"] == "int"
|
||||
assert params["count"]["default"] == 5
|
||||
my_parameter_bool = init_params_schema['properties']['my_parameter_bool']
|
||||
assert my_parameter_bool["default"] == False
|
||||
assert my_parameter_bool["type"] == "boolean"
|
||||
|
||||
assert params["filters"]["description"] == "Optional filters to apply"
|
||||
assert params["filters"]["type"] == "list[str]"
|
||||
assert params["filters"]["default"] == ""
|
||||
def test_extract_env_vars(mock_tool_extractor):
|
||||
tool_info = mock_tool_extractor
|
||||
|
||||
assert tool_info["package_dependencies"] == ["this-is-a-required-package", "another-required-package"]
|
||||
assert len(tool_info["env_vars"]) == 2
|
||||
api_key_var, rate_limit_var = tool_info["env_vars"]
|
||||
assert api_key_var["name"] == "SERPER_API_KEY"
|
||||
assert api_key_var["description"] == "API key for Serper"
|
||||
assert api_key_var["required"] == True
|
||||
assert api_key_var["default"] == None
|
||||
|
||||
assert rate_limit_var["name"] == "API_RATE_LIMIT"
|
||||
assert rate_limit_var["description"] == "API rate limit"
|
||||
assert rate_limit_var["required"] == False
|
||||
assert rate_limit_var["default"] == "100"
|
||||
|
||||
def test_extract_run_params_schema(mock_tool_extractor):
|
||||
tool_info = mock_tool_extractor
|
||||
|
||||
run_params_schema = tool_info["run_params_schema"]
|
||||
assert run_params_schema.keys() == {
|
||||
"properties",
|
||||
"required",
|
||||
"title",
|
||||
"type",
|
||||
}
|
||||
|
||||
query_param = run_params_schema["properties"]["query"]
|
||||
assert query_param["description"] == "The query parameter"
|
||||
assert query_param["type"] == "string"
|
||||
|
||||
count_param = run_params_schema["properties"]["count"]
|
||||
assert count_param["type"] == "integer"
|
||||
assert count_param["default"] == 5
|
||||
|
||||
filters_param = run_params_schema["properties"]["filters"]
|
||||
assert filters_param["description"] == "Optional filters to apply"
|
||||
assert filters_param["default"] == None
|
||||
assert filters_param['anyOf'] == [{'items': {'type': 'string'}, 'type': 'array'}, {'type': 'null'}]
|
||||
|
||||
def test_extract_package_dependencies(mock_tool_extractor):
|
||||
tool_info = mock_tool_extractor
|
||||
assert tool_info["package_dependencies"] == ["this-is-a-required-package", "another-required-package"]
|
||||
|
||||
|
||||
def test_save_to_json(extractor, tmp_path):
|
||||
@@ -128,7 +143,7 @@ def test_save_to_json(extractor, tmp_path):
|
||||
"name": "TestTool",
|
||||
"humanized_name": "Test Tool",
|
||||
"description": "A test tool",
|
||||
"run_params": [
|
||||
"run_params_schema": [
|
||||
{"name": "param1", "description": "Test parameter", "type": "str"}
|
||||
]
|
||||
}]
|
||||
@@ -144,20 +159,4 @@ def test_save_to_json(extractor, tmp_path):
|
||||
assert "tools" in data
|
||||
assert len(data["tools"]) == 1
|
||||
assert data["tools"][0]["humanized_name"] == "Test Tool"
|
||||
assert data["tools"][0]["run_params"][0]["name"] == "param1"
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_full_extraction_process():
|
||||
extractor = ToolSpecExtractor()
|
||||
specs = extractor.extract_all_tools()
|
||||
|
||||
assert len(specs) > 0
|
||||
|
||||
for tool in specs:
|
||||
assert "name" in tool
|
||||
assert "humanized_name" in tool and tool["humanized_name"]
|
||||
assert "description" in tool
|
||||
assert isinstance(tool["run_params"], list)
|
||||
for param in tool["run_params"]:
|
||||
assert "name" in param and param["name"]
|
||||
assert data["tools"][0]["run_params_schema"][0]["name"] == "param1"
|
||||
|
||||
Reference in New Issue
Block a user