Repository: Marker-Inc-Korea/AutoRAG

Issue:
[HotFix] [threshold cutoff] Error when the input 'scores_list' is np.ndarray.
In the running of AutoRAG, the input of `threshold_cutoff_pure` function's parameter `scores_list` is np.ndarray, it occurs error.

```python
def threshold_cutoff_pure(scores_list: List[float],
                          threshold: float,
                          reverse: bool = False) -> List[int]:
    if reverse:
        remain_indices = [i for i, score in enumerate(scores_list) if score <= threshold]
        default_index = scores_list.index(min(scores_list)) # error here
    else:
        remain_indices = [i for i, score in enumerate(scores_list) if score >= threshold]
        default_index = scores_list.index(max(scores_list)) # error here

    return remain_indices if remain_indices else [default_index]
```

Discussion:

Patch:
diff --git a/autorag/nodes/passagefilter/threshold_cutoff.py b/autorag/nodes/passagefilter/threshold_cutoff.py
index 1369344..3fb4b60 100644
--- a/autorag/nodes/passagefilter/threshold_cutoff.py
+++ b/autorag/nodes/passagefilter/threshold_cutoff.py
@@ -1,5 +1,7 @@
 from typing import List, Tuple
 
+import numpy as np
+
 from autorag.nodes.passagefilter.base import passage_filter_node
 
 
@@ -43,11 +45,20 @@ def threshold_cutoff_pure(scores_list: List[float],
         Default is False.
     :return: Indices to remain at the contents
     """
-    if reverse:
-        remain_indices = [i for i, score in enumerate(scores_list) if score <= threshold]
-        default_index = scores_list.index(min(scores_list))
+    if isinstance(scores_list, np.ndarray):
+        if reverse:
+            remain_indices = np.where(scores_list <= threshold)[0]
+            default_index = np.argmin(scores_list)
+        else:
+            remain_indices = np.where(scores_list >= threshold)[0]
+            default_index = np.argmax(scores_list)
     else:
-        remain_indices = [i for i, score in enumerate(scores_list) if score >= threshold]
-        default_index = scores_list.index(max(scores_list))
+        if reverse:
+            remain_indices = [i for i, score in enumerate(scores_list) if score <= threshold]
+            default_index = scores_list.index(min(scores_list))
+        else:
+            remain_indices = [i for i, score in enumerate(scores_list) if score >= threshold]
+            default_index = scores_list.index(max(scores_list))
 
-    return remain_indices if remain_indices else [default_index]
+    return remain_indices.tolist() if isinstance(remain_indices, np.ndarray) and remain_indices.size > 0 else \
+        remain_indices if remain_indices else [default_index]


Test patch:
diff --git a/tests/autorag/nodes/passagefilter/test_threshold_cutoff.py b/tests/autorag/nodes/passagefilter/test_threshold_cutoff.py
index 59d1d91..868b827 100644
--- a/tests/autorag/nodes/passagefilter/test_threshold_cutoff.py
+++ b/tests/autorag/nodes/passagefilter/test_threshold_cutoff.py
@@ -1,3 +1,5 @@
+import numpy as np
+
 from autorag.nodes.passagefilter import threshold_cutoff
 from tests.autorag.nodes.passagefilter.test_passage_filter_base import queries_example, contents_example, \
     scores_example, ids_example, base_passage_filter_test, project_dir, previous_result, base_passage_filter_node_test
@@ -19,6 +21,16 @@ def test_threshold_cutoff_reverse():
     assert contents[0] == ["NomaDamas is Great Team", "havertz is suck at soccer"]
 
 
+def test_threshold_cutoff_numpy():
+    original_cutoff = threshold_cutoff.__wrapped__
+    numpy_scores = np.array([[0.1, 0.8, 0.1, 0.5], [0.1, 0.2, 0.7, 0.3]])
+    contents, ids, scores = original_cutoff(
+        queries_example, contents_example, numpy_scores, ids_example, threshold=0.6)
+    base_passage_filter_test(contents, ids, scores)
+    assert scores == [[0.8], [0.7]]
+    assert contents == [["Paris is the capital of France."], ["Newjeans has 5 members."]]
+
+
 def test_threshold_cutoff_node():
     result_df = threshold_cutoff(
         project_dir=project_dir, previous_result=previous_result, threshold=0.9)