lionagi 0.2.10__py3-none-any.whl → 0.3.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- lionagi/core/action/function_calling.py +13 -6
- lionagi/core/action/tool.py +10 -9
- lionagi/core/action/tool_manager.py +18 -9
- lionagi/core/agent/README.md +1 -1
- lionagi/core/agent/base_agent.py +5 -2
- lionagi/core/agent/eval/README.md +1 -1
- lionagi/core/collections/README.md +1 -1
- lionagi/core/collections/_logger.py +16 -6
- lionagi/core/collections/abc/README.md +1 -1
- lionagi/core/collections/abc/component.py +35 -11
- lionagi/core/collections/abc/concepts.py +5 -3
- lionagi/core/collections/abc/exceptions.py +3 -1
- lionagi/core/collections/flow.py +16 -5
- lionagi/core/collections/model.py +34 -8
- lionagi/core/collections/pile.py +65 -28
- lionagi/core/collections/progression.py +1 -2
- lionagi/core/collections/util.py +11 -2
- lionagi/core/director/README.md +1 -1
- lionagi/core/engine/branch_engine.py +35 -10
- lionagi/core/engine/instruction_map_engine.py +14 -5
- lionagi/core/engine/sandbox_.py +3 -1
- lionagi/core/engine/script_engine.py +6 -2
- lionagi/core/executor/base_executor.py +10 -3
- lionagi/core/executor/graph_executor.py +12 -4
- lionagi/core/executor/neo4j_executor.py +18 -6
- lionagi/core/generic/edge.py +7 -2
- lionagi/core/generic/graph.py +23 -7
- lionagi/core/generic/node.py +14 -5
- lionagi/core/generic/tree_node.py +5 -1
- lionagi/core/mail/mail_manager.py +3 -1
- lionagi/core/mail/package.py +3 -1
- lionagi/core/message/action_request.py +9 -2
- lionagi/core/message/action_response.py +9 -3
- lionagi/core/message/instruction.py +8 -2
- lionagi/core/message/util.py +15 -5
- lionagi/core/report/base.py +12 -7
- lionagi/core/report/form.py +7 -4
- lionagi/core/report/report.py +10 -3
- lionagi/core/report/util.py +3 -1
- lionagi/core/rule/action.py +4 -1
- lionagi/core/rule/base.py +17 -6
- lionagi/core/rule/rulebook.py +8 -4
- lionagi/core/rule/string.py +3 -1
- lionagi/core/session/branch.py +15 -4
- lionagi/core/session/session.py +6 -2
- lionagi/core/unit/parallel_unit.py +9 -3
- lionagi/core/unit/template/action.py +1 -1
- lionagi/core/unit/template/predict.py +3 -1
- lionagi/core/unit/template/select.py +5 -3
- lionagi/core/unit/unit.py +50 -2
- lionagi/core/unit/unit_form.py +13 -15
- lionagi/core/unit/unit_mixin.py +45 -27
- lionagi/core/unit/util.py +7 -3
- lionagi/core/validator/validator.py +28 -15
- lionagi/core/work/work_edge.py +7 -3
- lionagi/core/work/work_task.py +11 -5
- lionagi/core/work/worker.py +20 -5
- lionagi/core/work/worker_engine.py +6 -2
- lionagi/core/work/worklog.py +3 -1
- lionagi/experimental/compressor/llm_compressor.py +20 -5
- lionagi/experimental/directive/README.md +1 -1
- lionagi/experimental/directive/parser/base_parser.py +41 -14
- lionagi/experimental/directive/parser/base_syntax.txt +23 -23
- lionagi/experimental/directive/template/base_template.py +14 -6
- lionagi/experimental/directive/tokenizer.py +3 -1
- lionagi/experimental/evaluator/README.md +1 -1
- lionagi/experimental/evaluator/ast_evaluator.py +6 -2
- lionagi/experimental/evaluator/base_evaluator.py +27 -16
- lionagi/integrations/bridge/autogen_/autogen_.py +7 -3
- lionagi/integrations/bridge/langchain_/documents.py +13 -10
- lionagi/integrations/bridge/llamaindex_/llama_pack.py +36 -12
- lionagi/integrations/bridge/llamaindex_/node_parser.py +8 -3
- lionagi/integrations/bridge/llamaindex_/reader.py +3 -1
- lionagi/integrations/bridge/llamaindex_/textnode.py +9 -3
- lionagi/integrations/bridge/pydantic_/pydantic_bridge.py +7 -1
- lionagi/integrations/bridge/transformers_/install_.py +3 -1
- lionagi/integrations/chunker/chunk.py +5 -2
- lionagi/integrations/loader/load.py +7 -3
- lionagi/integrations/loader/load_util.py +35 -16
- lionagi/integrations/provider/oai.py +13 -4
- lionagi/integrations/provider/openrouter.py +13 -4
- lionagi/integrations/provider/services.py +3 -1
- lionagi/integrations/provider/transformers.py +5 -3
- lionagi/integrations/storage/neo4j.py +23 -7
- lionagi/integrations/storage/storage_util.py +23 -7
- lionagi/integrations/storage/structure_excel.py +7 -2
- lionagi/integrations/storage/to_csv.py +8 -2
- lionagi/integrations/storage/to_excel.py +11 -3
- lionagi/libs/ln_api.py +41 -19
- lionagi/libs/ln_context.py +4 -4
- lionagi/libs/ln_convert.py +35 -14
- lionagi/libs/ln_dataframe.py +9 -3
- lionagi/libs/ln_func_call.py +53 -18
- lionagi/libs/ln_image.py +9 -5
- lionagi/libs/ln_knowledge_graph.py +21 -7
- lionagi/libs/ln_nested.py +57 -16
- lionagi/libs/ln_parse.py +45 -15
- lionagi/libs/ln_queue.py +8 -3
- lionagi/libs/ln_tokenize.py +19 -6
- lionagi/libs/ln_validate.py +14 -3
- lionagi/libs/sys_util.py +44 -12
- lionagi/lions/coder/coder.py +24 -8
- lionagi/lions/coder/util.py +6 -2
- lionagi/lions/researcher/data_source/google_.py +12 -4
- lionagi/lions/researcher/data_source/wiki_.py +3 -1
- lionagi/version.py +1 -1
- {lionagi-0.2.10.dist-info → lionagi-0.3.0.dist-info}/METADATA +6 -7
- lionagi-0.3.0.dist-info/RECORD +226 -0
- lionagi/tests/__init__.py +0 -0
- lionagi/tests/api/__init__.py +0 -0
- lionagi/tests/api/aws/__init__.py +0 -0
- lionagi/tests/api/aws/conftest.py +0 -25
- lionagi/tests/api/aws/test_aws_s3.py +0 -6
- lionagi/tests/integrations/__init__.py +0 -0
- lionagi/tests/libs/__init__.py +0 -0
- lionagi/tests/libs/test_api.py +0 -48
- lionagi/tests/libs/test_convert.py +0 -89
- lionagi/tests/libs/test_field_validators.py +0 -354
- lionagi/tests/libs/test_func_call.py +0 -701
- lionagi/tests/libs/test_nested.py +0 -382
- lionagi/tests/libs/test_parse.py +0 -171
- lionagi/tests/libs/test_queue.py +0 -68
- lionagi/tests/libs/test_sys_util.py +0 -222
- lionagi/tests/test_core/__init__.py +0 -0
- lionagi/tests/test_core/collections/__init__.py +0 -0
- lionagi/tests/test_core/collections/test_component.py +0 -208
- lionagi/tests/test_core/collections/test_exchange.py +0 -139
- lionagi/tests/test_core/collections/test_flow.py +0 -146
- lionagi/tests/test_core/collections/test_pile.py +0 -172
- lionagi/tests/test_core/collections/test_progression.py +0 -130
- lionagi/tests/test_core/generic/__init__.py +0 -0
- lionagi/tests/test_core/generic/test_edge.py +0 -69
- lionagi/tests/test_core/generic/test_graph.py +0 -97
- lionagi/tests/test_core/generic/test_node.py +0 -107
- lionagi/tests/test_core/generic/test_structure.py +0 -194
- lionagi/tests/test_core/generic/test_tree_node.py +0 -74
- lionagi/tests/test_core/graph/__init__.py +0 -0
- lionagi/tests/test_core/graph/test_graph.py +0 -71
- lionagi/tests/test_core/graph/test_tree.py +0 -76
- lionagi/tests/test_core/mail/__init__.py +0 -0
- lionagi/tests/test_core/mail/test_mail.py +0 -98
- lionagi/tests/test_core/test_branch.py +0 -116
- lionagi/tests/test_core/test_form.py +0 -47
- lionagi/tests/test_core/test_report.py +0 -106
- lionagi/tests/test_core/test_structure/__init__.py +0 -0
- lionagi/tests/test_core/test_structure/test_base_structure.py +0 -198
- lionagi/tests/test_core/test_structure/test_graph.py +0 -55
- lionagi/tests/test_core/test_structure/test_tree.py +0 -49
- lionagi/tests/test_core/test_validator.py +0 -112
- lionagi-0.2.10.dist-info/RECORD +0 -267
- {lionagi-0.2.10.dist-info → lionagi-0.3.0.dist-info}/LICENSE +0 -0
- {lionagi-0.2.10.dist-info → lionagi-0.3.0.dist-info}/WHEEL +0 -0
@@ -1,146 +0,0 @@
|
|
1
|
-
import unittest
|
2
|
-
|
3
|
-
from lionagi import Node, flow, pile, progression
|
4
|
-
|
5
|
-
|
6
|
-
class TestFlow(unittest.TestCase):
|
7
|
-
|
8
|
-
def setUp(self):
|
9
|
-
# Setup for creating initial nodes, piles, and progressions
|
10
|
-
self.nodes = [Node(content=i) for i in range(10)]
|
11
|
-
self.pile1 = pile(self.nodes)
|
12
|
-
self.prog1 = progression(self.nodes[:5], name="left")
|
13
|
-
self.prog2 = progression(self.nodes[5:], name="right")
|
14
|
-
self.flow = flow([self.prog1, self.prog2])
|
15
|
-
|
16
|
-
def test_initialization(self):
|
17
|
-
self.assertEqual(len(self.flow.sequences), 2)
|
18
|
-
self.assertIn("left", self.flow.registry)
|
19
|
-
self.assertIn("right", self.flow.registry)
|
20
|
-
|
21
|
-
def test_append_to_flow(self):
|
22
|
-
new_node = Node(content="new_node")
|
23
|
-
self.flow.append(new_node, "left")
|
24
|
-
self.assertIn(new_node.ln_id, self.flow.get("left"))
|
25
|
-
|
26
|
-
def test_exclude_from_flow(self):
|
27
|
-
node_to_remove = self.nodes[0]
|
28
|
-
self.flow.exclude("left", node_to_remove)
|
29
|
-
self.assertNotIn(node_to_remove.ln_id, self.flow.get("left"))
|
30
|
-
|
31
|
-
def test_get_sequence(self):
|
32
|
-
seq = self.flow.get("left")
|
33
|
-
self.assertEqual(seq, self.prog1)
|
34
|
-
seq_default = self.flow.get("nonexistent", default=None)
|
35
|
-
self.assertIsNone(seq_default)
|
36
|
-
|
37
|
-
def test_register_sequence(self):
|
38
|
-
new_prog = progression(self.nodes[2:4], name="middle")
|
39
|
-
self.flow.register(new_prog)
|
40
|
-
self.assertIn("middle", self.flow.registry)
|
41
|
-
|
42
|
-
def test_popleft(self):
|
43
|
-
first_node_id = self.prog1[0]
|
44
|
-
removed_node_id = self.flow.popleft("left")
|
45
|
-
self.assertEqual(first_node_id, removed_node_id)
|
46
|
-
self.assertNotIn(removed_node_id, self.flow.get("left"))
|
47
|
-
|
48
|
-
def test_shape_and_size(self):
|
49
|
-
shape = self.flow.shape()
|
50
|
-
self.assertEqual(shape["left"], 5)
|
51
|
-
self.assertEqual(shape["right"], 5)
|
52
|
-
size = self.flow.size()
|
53
|
-
self.assertEqual(size, 10)
|
54
|
-
|
55
|
-
def test_clear(self):
|
56
|
-
self.flow.clear()
|
57
|
-
self.assertEqual(len(self.flow.sequences), 0)
|
58
|
-
self.assertEqual(len(self.flow.registry), 0)
|
59
|
-
|
60
|
-
def test_iteration(self):
|
61
|
-
items = list(self.flow)
|
62
|
-
self.assertEqual(len(items), 2)
|
63
|
-
|
64
|
-
def test_to_df(self):
|
65
|
-
df = self.flow.to_df()
|
66
|
-
self.assertEqual(df.shape[0], 2)
|
67
|
-
self.assertEqual(df.columns.tolist(), ["order", "name"])
|
68
|
-
|
69
|
-
def test_inclusion_check(self):
|
70
|
-
self.assertTrue(self.prog1 in self.flow)
|
71
|
-
self.assertTrue(self.prog2 in self.flow)
|
72
|
-
try:
|
73
|
-
a = Node(content="nonexistent") in self.flow
|
74
|
-
except TypeError:
|
75
|
-
pass
|
76
|
-
|
77
|
-
# Additional Tests for Edge Cases
|
78
|
-
def test_empty_flow_initialization(self):
|
79
|
-
empty_flow = flow()
|
80
|
-
self.assertEqual(len(empty_flow.sequences), 0)
|
81
|
-
self.assertEqual(len(empty_flow.registry), 0)
|
82
|
-
|
83
|
-
def test_append_to_nonexistent_sequence(self):
|
84
|
-
new_node = Node(content="new_node")
|
85
|
-
self.flow.append(new_node, "nonexistent")
|
86
|
-
self.assertIn(new_node.ln_id, self.flow.get("nonexistent"))
|
87
|
-
|
88
|
-
def test_exclude_nonexistent_item(self):
|
89
|
-
non_existent_node = Node(content="nonexistent")
|
90
|
-
result = self.flow.exclude("left", non_existent_node)
|
91
|
-
self.assertTrue(result)
|
92
|
-
|
93
|
-
def test_exclude_nonexistent_sequence(self):
|
94
|
-
result = self.flow.exclude("nonexistent")
|
95
|
-
self.assertFalse(result)
|
96
|
-
|
97
|
-
def test_get_nonexistent_sequence(self):
|
98
|
-
try:
|
99
|
-
self.flow.get("nonexistent")
|
100
|
-
except Exception as e:
|
101
|
-
if e.__class__.__name__ == "LionTypeError":
|
102
|
-
return
|
103
|
-
raise AssertionError("LionTypeError not raised")
|
104
|
-
|
105
|
-
def test_register_existing_sequence_name(self):
|
106
|
-
with self.assertRaises(ValueError):
|
107
|
-
self.flow.register(self.prog1, name="right")
|
108
|
-
|
109
|
-
def test_popleft_nonexistent_sequence(self):
|
110
|
-
try:
|
111
|
-
self.flow.popleft("nonexistent")
|
112
|
-
except Exception as e:
|
113
|
-
if e.__class__.__name__ == "LionTypeError":
|
114
|
-
return
|
115
|
-
raise AssertionError("LionTypeError not raised")
|
116
|
-
|
117
|
-
def test_append_multiple_items(self):
|
118
|
-
new_nodes = [Node(content="new_node1"), Node(content="new_node2")]
|
119
|
-
for new_node in new_nodes:
|
120
|
-
self.flow.append(new_node, "left")
|
121
|
-
for new_node in new_nodes:
|
122
|
-
self.assertIn(new_node.ln_id, self.flow.get("left"))
|
123
|
-
|
124
|
-
def test_remove_from_all_sequences(self):
|
125
|
-
node_to_remove = self.nodes[0]
|
126
|
-
self.flow.append(node_to_remove, "right")
|
127
|
-
self.flow.remove(node_to_remove)
|
128
|
-
self.assertNotIn(node_to_remove.ln_id, self.flow.get("right"))
|
129
|
-
|
130
|
-
def test_shape_empty_flow(self):
|
131
|
-
empty_flow = flow()
|
132
|
-
self.assertEqual(empty_flow.shape(), {})
|
133
|
-
|
134
|
-
def test_size_empty_flow(self):
|
135
|
-
empty_flow = flow()
|
136
|
-
self.assertEqual(empty_flow.size(), 0)
|
137
|
-
|
138
|
-
def test_clear_empty_flow(self):
|
139
|
-
empty_flow = flow()
|
140
|
-
empty_flow.clear()
|
141
|
-
self.assertEqual(len(empty_flow.sequences), 0)
|
142
|
-
self.assertEqual(len(empty_flow.registry), 0)
|
143
|
-
|
144
|
-
|
145
|
-
if __name__ == "__main__":
|
146
|
-
unittest.main()
|
@@ -1,172 +0,0 @@
|
|
1
|
-
import asyncio
|
2
|
-
import unittest
|
3
|
-
|
4
|
-
from lionagi import Node
|
5
|
-
from lionagi.core.collections.pile import Pile
|
6
|
-
|
7
|
-
|
8
|
-
class TestPile(unittest.TestCase):
|
9
|
-
|
10
|
-
def setUp(self):
|
11
|
-
"""Create initial nodes and piles for testing."""
|
12
|
-
self.nodes1 = [Node(content=i) for i in ["A", "B", "C"]]
|
13
|
-
self.nodes2 = [Node(content=i) for i in ["D", "E", "F"]]
|
14
|
-
self.p1 = Pile(self.nodes1)
|
15
|
-
self.p2 = Pile(self.nodes2)
|
16
|
-
|
17
|
-
def test_add_piles(self):
|
18
|
-
"""Test adding two piles."""
|
19
|
-
combined_pile = self.p1 + self.p2
|
20
|
-
self.assertEqual(len(combined_pile), 6)
|
21
|
-
contents = [node.content for node in combined_pile.values()]
|
22
|
-
self.assertListEqual(contents, ["A", "B", "C", "D", "E", "F"])
|
23
|
-
|
24
|
-
def test_subtract_piles(self):
|
25
|
-
"""Test subtracting nodes from a pile."""
|
26
|
-
with self.assertRaises(Exception):
|
27
|
-
result_pile = self.p1 - self.nodes2[0] # D not in p1
|
28
|
-
|
29
|
-
def test_containment(self):
|
30
|
-
"""Test containment check."""
|
31
|
-
self.assertIn(self.nodes1[1], self.p1) # B in p1
|
32
|
-
self.assertNotIn(self.nodes2[0], self.p1) # D not in p1
|
33
|
-
|
34
|
-
def test_include_nodes(self):
|
35
|
-
"""Test including nodes in a pile."""
|
36
|
-
self.p1.include(self.nodes2)
|
37
|
-
self.assertEqual(len(self.p1), 6)
|
38
|
-
contents = [node.content for node in self.p1.values()]
|
39
|
-
self.assertListEqual(contents, ["A", "B", "C", "D", "E", "F"])
|
40
|
-
|
41
|
-
def test_exclude_nodes(self):
|
42
|
-
"""Test excluding nodes from a pile."""
|
43
|
-
self.p1.include(self.nodes2) # Include first to have something to exclude
|
44
|
-
self.p1.exclude(self.nodes2)
|
45
|
-
self.assertEqual(len(self.p1), 5)
|
46
|
-
contents = [node.content for node in self.p1.values()]
|
47
|
-
self.assertListEqual(contents, ["A", "B", "C", "E", "F"])
|
48
|
-
|
49
|
-
def test_get_item_by_index(self):
|
50
|
-
"""Test getting an item by index."""
|
51
|
-
node = self.p1[0]
|
52
|
-
self.assertEqual(node.content, "A")
|
53
|
-
|
54
|
-
def test_set_item_by_index(self):
|
55
|
-
"""Test setting an item at a specific index."""
|
56
|
-
new_node = Node(content="Updated Node")
|
57
|
-
self.p1[0] = new_node
|
58
|
-
self.assertEqual(self.p1[0].content, "Updated Node")
|
59
|
-
|
60
|
-
def test_insert_item(self):
|
61
|
-
"""Test inserting an item at a specific position."""
|
62
|
-
new_node = Node(content="Inserted Node")
|
63
|
-
self.p1.insert(0, new_node)
|
64
|
-
self.assertEqual(self.p1[0].content, "Inserted Node")
|
65
|
-
self.assertEqual(len(self.p1), 4)
|
66
|
-
|
67
|
-
def test_homogenous(self):
|
68
|
-
"""Test if all items in the pile are of the same type."""
|
69
|
-
self.assertTrue(self.p1.is_homogenous())
|
70
|
-
with self.assertRaises(AttributeError):
|
71
|
-
mixed_pile = Pile(self.nodes1 + [123]) # Adding an int to mix types
|
72
|
-
|
73
|
-
def test_is_empty(self):
|
74
|
-
"""Test if the pile is empty."""
|
75
|
-
empty_pile = Pile()
|
76
|
-
self.assertTrue(empty_pile.is_empty())
|
77
|
-
self.assertFalse(self.p1.is_empty())
|
78
|
-
|
79
|
-
def test_pop_item(self):
|
80
|
-
"""Test popping an item from the pile."""
|
81
|
-
popped_node = self.p1.pop(self.nodes1[0].ln_id)
|
82
|
-
self.assertEqual(popped_node.content, "A")
|
83
|
-
self.assertEqual(len(self.p1), 2)
|
84
|
-
|
85
|
-
def test_clear_pile(self):
|
86
|
-
"""Test clearing the pile."""
|
87
|
-
self.p1.clear()
|
88
|
-
self.assertTrue(self.p1.is_empty())
|
89
|
-
|
90
|
-
def test_update_pile(self):
|
91
|
-
"""Test updating the pile with another pile."""
|
92
|
-
self.p1.update(self.p2)
|
93
|
-
self.assertEqual(len(self.p1), 6)
|
94
|
-
contents = [node.content for node in self.p1.values()]
|
95
|
-
self.assertListEqual(contents, ["A", "B", "C", "D", "E", "F"])
|
96
|
-
|
97
|
-
def test_to_dataframe(self):
|
98
|
-
"""Test converting the pile to a DataFrame."""
|
99
|
-
df = self.p1.to_df()
|
100
|
-
self.assertEqual(len(df), 3)
|
101
|
-
self.assertListEqual(df["content"].tolist(), ["A", "B", "C"])
|
102
|
-
|
103
|
-
def test_create_index(self):
|
104
|
-
"""Test creating an index for the pile."""
|
105
|
-
with self.assertRaises(ValueError):
|
106
|
-
self.p1.create_index(index_type="llama_index")
|
107
|
-
|
108
|
-
def test_create_query_engine(self):
|
109
|
-
"""Test creating a query engine for the pile."""
|
110
|
-
with self.assertRaises(ValueError):
|
111
|
-
self.p1.create_query_engine(index_type="llama_index")
|
112
|
-
|
113
|
-
def test_create_chat_engine(self):
|
114
|
-
"""Test creating a chat engine for the pile."""
|
115
|
-
with self.assertRaises(ValueError):
|
116
|
-
self.p1.create_chat_engine(index_type="llama_index")
|
117
|
-
|
118
|
-
# async def test_query_pile(self):
|
119
|
-
# """Test querying the pile."""
|
120
|
-
# self.p1.create_query_engine(index_type="llama_index")
|
121
|
-
# response = await self.p1.query_pile(query="test query")
|
122
|
-
# self.assertIsInstance(response, str)
|
123
|
-
|
124
|
-
# async def test_chat_pile(self):
|
125
|
-
# """Test chatting with the pile."""
|
126
|
-
# self.p1.create_chat_engine(index_type="llama_index")
|
127
|
-
# response = await self.p1.chat_pile(query="test chat")
|
128
|
-
# self.assertIsInstance(response, str)
|
129
|
-
|
130
|
-
# async def test_embed_pile(self):
|
131
|
-
# """Test embedding the items in the pile."""
|
132
|
-
# await self.p1.embed_pile()
|
133
|
-
# for node in self.p1.values():
|
134
|
-
# self.assertIn("embedding", node._all_fields)
|
135
|
-
|
136
|
-
def test_to_csv(self):
|
137
|
-
"""Test saving the pile to a CSV file."""
|
138
|
-
self.p1.to_csv("test_pile.csv")
|
139
|
-
with open("test_pile.csv", "r") as f:
|
140
|
-
content = f.read()
|
141
|
-
self.assertIn("content", content)
|
142
|
-
|
143
|
-
def test_from_csv(self):
|
144
|
-
"""Test loading a pile from a CSV file."""
|
145
|
-
self.p1.to_csv("test_pile.csv")
|
146
|
-
loaded_pile = Pile.from_csv("test_pile.csv")
|
147
|
-
self.assertEqual(len(loaded_pile), 3)
|
148
|
-
self.assertEqual(loaded_pile[0].content, "A")
|
149
|
-
|
150
|
-
def test_from_dataframe(self):
|
151
|
-
"""Test loading a pile from a DataFrame."""
|
152
|
-
df = self.p1.to_df()
|
153
|
-
loaded_pile = Pile.from_df(df)
|
154
|
-
self.assertEqual(len(loaded_pile), 3)
|
155
|
-
self.assertEqual(loaded_pile[0].content, "A")
|
156
|
-
|
157
|
-
def test_as_query_tool(self):
|
158
|
-
"""Test creating a query tool for the pile."""
|
159
|
-
with self.assertRaises(ValueError):
|
160
|
-
tool = self.p1.as_query_tool(index_type="llama_index")
|
161
|
-
|
162
|
-
def test_str_representation(self):
|
163
|
-
"""Test the string representation of the pile."""
|
164
|
-
self.assertIsInstance(str(self.p1), str)
|
165
|
-
|
166
|
-
def test_repr_representation(self):
|
167
|
-
"""Test the representation of the pile."""
|
168
|
-
self.assertIsInstance(repr(self.p1), str)
|
169
|
-
|
170
|
-
|
171
|
-
if __name__ == "__main__":
|
172
|
-
unittest.main()
|
@@ -1,130 +0,0 @@
|
|
1
|
-
import unittest
|
2
|
-
|
3
|
-
from lionagi import Node
|
4
|
-
from lionagi.core.collections import Progression
|
5
|
-
from lionagi.core.collections.abc import ItemNotFoundError
|
6
|
-
|
7
|
-
|
8
|
-
class TestProgression(unittest.TestCase):
|
9
|
-
|
10
|
-
def setUp(self):
|
11
|
-
self.nodes = [Node() for _ in range(5)]
|
12
|
-
self.p = Progression(order=[node.ln_id for node in self.nodes])
|
13
|
-
|
14
|
-
def test_initial_order(self):
|
15
|
-
self.assertEqual(self.p.order, [node.ln_id for node in self.nodes])
|
16
|
-
|
17
|
-
def test_append_node(self):
|
18
|
-
new_node = Node()
|
19
|
-
self.p.append(new_node)
|
20
|
-
self.assertIn(new_node.ln_id, self.p.order)
|
21
|
-
self.assertEqual(len(self.p), 6)
|
22
|
-
|
23
|
-
def test_extend_single_node(self):
|
24
|
-
new_node = Node()
|
25
|
-
self.p.extend(new_node)
|
26
|
-
self.assertIn(new_node.ln_id, self.p.order)
|
27
|
-
self.assertEqual(len(self.p), 6)
|
28
|
-
|
29
|
-
def test_extend_multiple_nodes(self):
|
30
|
-
new_nodes = [Node() for _ in range(3)]
|
31
|
-
self.p.extend(new_nodes)
|
32
|
-
for node in new_nodes:
|
33
|
-
self.assertIn(node.ln_id, self.p.order)
|
34
|
-
self.assertEqual(len(self.p), 8)
|
35
|
-
|
36
|
-
def test_include_node(self):
|
37
|
-
new_node = Node()
|
38
|
-
self.p.include(new_node)
|
39
|
-
self.assertIn(new_node.ln_id, self.p.order)
|
40
|
-
|
41
|
-
def test_getitem_slice(self):
|
42
|
-
slice_result = self.p[1:5]
|
43
|
-
self.assertEqual(slice_result.order, self.p.order[1:5])
|
44
|
-
|
45
|
-
def test_setitem(self):
|
46
|
-
new_node = Node()
|
47
|
-
self.p[0] = new_node.ln_id
|
48
|
-
self.assertEqual(self.p[0], new_node.ln_id)
|
49
|
-
|
50
|
-
def test_add_node(self):
|
51
|
-
new_node = Node()
|
52
|
-
new_prog = self.p + new_node
|
53
|
-
self.assertIn(new_node.ln_id, new_prog.order)
|
54
|
-
|
55
|
-
def test_iadd_node(self):
|
56
|
-
new_node = Node()
|
57
|
-
self.p += new_node
|
58
|
-
self.assertIn(new_node.ln_id, self.p.order)
|
59
|
-
|
60
|
-
def test_subtract_node(self):
|
61
|
-
node_to_remove = self.nodes[0]
|
62
|
-
self.p -= node_to_remove.ln_id
|
63
|
-
self.assertNotIn(node_to_remove.ln_id, self.p.order)
|
64
|
-
|
65
|
-
def test_isubtract_node(self):
|
66
|
-
node_to_remove = self.nodes[0]
|
67
|
-
self.p -= node_to_remove.ln_id
|
68
|
-
self.assertNotIn(node_to_remove.ln_id, self.p.order)
|
69
|
-
|
70
|
-
def test_popleft(self):
|
71
|
-
leftmost = self.p.order[0]
|
72
|
-
self.assertEqual(self.p.popleft(), leftmost)
|
73
|
-
self.assertNotIn(leftmost, self.p.order)
|
74
|
-
|
75
|
-
def test_exclude_node(self):
|
76
|
-
node_to_exclude = self.nodes[0]
|
77
|
-
self.p.exclude(node_to_exclude.ln_id)
|
78
|
-
self.assertNotIn(node_to_exclude.ln_id, self.p.order)
|
79
|
-
|
80
|
-
def test_clear(self):
|
81
|
-
self.p.clear()
|
82
|
-
self.assertEqual(len(self.p), 0)
|
83
|
-
|
84
|
-
def test_to_dict(self):
|
85
|
-
p_dict = self.p.to_dict()
|
86
|
-
self.assertEqual(p_dict["order"], self.p.order)
|
87
|
-
self.assertEqual(p_dict["name"], self.p.name)
|
88
|
-
|
89
|
-
def test_bool(self):
|
90
|
-
self.assertTrue(bool(self.p))
|
91
|
-
|
92
|
-
def test_remove_nonexistent_node(self):
|
93
|
-
non_existent_node = Node()
|
94
|
-
with self.assertRaises(ItemNotFoundError):
|
95
|
-
self.p.remove(non_existent_node.ln_id)
|
96
|
-
|
97
|
-
def test_pop_index_error(self):
|
98
|
-
with self.assertRaises(ItemNotFoundError):
|
99
|
-
self.p.pop(100)
|
100
|
-
|
101
|
-
def test_popleft_index_error(self):
|
102
|
-
empty_prog = Progression()
|
103
|
-
with self.assertRaises(ItemNotFoundError):
|
104
|
-
empty_prog.popleft()
|
105
|
-
|
106
|
-
def test_iteration(self):
|
107
|
-
nodes_list = [node.ln_id for node in self.nodes]
|
108
|
-
for i, node in enumerate(self.p):
|
109
|
-
self.assertEqual(node, nodes_list[i])
|
110
|
-
|
111
|
-
def test_contains(self):
|
112
|
-
node_to_check = self.nodes[0]
|
113
|
-
self.assertIn(node_to_check.ln_id, self.p)
|
114
|
-
|
115
|
-
def test_not_contains(self):
|
116
|
-
non_existent_node = Node()
|
117
|
-
self.assertNotIn(non_existent_node.ln_id, self.p)
|
118
|
-
|
119
|
-
def test_equality(self):
|
120
|
-
new_prog = Progression(order=[node.ln_id for node in self.nodes])
|
121
|
-
self.assertEqual(self.p.order, new_prog.order)
|
122
|
-
|
123
|
-
def test_inequality(self):
|
124
|
-
new_node = Node()
|
125
|
-
new_prog = self.p + new_node
|
126
|
-
self.assertNotEqual(self.p.order, new_prog)
|
127
|
-
|
128
|
-
|
129
|
-
if __name__ == "__main__":
|
130
|
-
unittest.main()
|
File without changes
|
@@ -1,69 +0,0 @@
|
|
1
|
-
import unittest
|
2
|
-
from unittest.mock import AsyncMock, patch
|
3
|
-
|
4
|
-
from pydantic import ValidationError
|
5
|
-
|
6
|
-
from lionagi.core.collections.abc import Component, Condition, LionIDable, get_lion_id
|
7
|
-
from lionagi.core.generic.edge import Edge
|
8
|
-
from lionagi.core.generic.edge_condition import EdgeCondition
|
9
|
-
|
10
|
-
|
11
|
-
class TestEdge(unittest.TestCase):
|
12
|
-
|
13
|
-
def setUp(self):
|
14
|
-
self.node1 = Component()
|
15
|
-
self.node2 = Component()
|
16
|
-
self.edge = Edge(head=self.node1.ln_id, tail=self.node2.ln_id)
|
17
|
-
|
18
|
-
def test_initialization(self):
|
19
|
-
"""Test initialization of the Edge class."""
|
20
|
-
self.assertEqual(self.edge.head, self.node1.ln_id)
|
21
|
-
self.assertEqual(self.edge.tail, self.node2.ln_id)
|
22
|
-
self.assertIsNone(self.edge.condition)
|
23
|
-
self.assertIsNone(self.edge.label)
|
24
|
-
self.assertFalse(self.edge.bundle)
|
25
|
-
|
26
|
-
async def test_check_condition_without_condition(self):
|
27
|
-
"""Test check_condition raises ValueError when condition is not set."""
|
28
|
-
with self.assertRaises(ValueError):
|
29
|
-
await self.edge.check_condition({})
|
30
|
-
|
31
|
-
@patch("lionagi.core.models.edge.EdgeCondition.applies", new_callable=AsyncMock)
|
32
|
-
async def test_check_condition_with_condition(self, mock_applies):
|
33
|
-
"""Test check_condition with a set condition."""
|
34
|
-
mock_applies.return_value = True
|
35
|
-
condition = EdgeCondition()
|
36
|
-
self.edge.condition = condition
|
37
|
-
result = await self.edge.check_condition({})
|
38
|
-
self.assertTrue(result)
|
39
|
-
mock_applies.assert_awaited_once()
|
40
|
-
|
41
|
-
def test_validate_head_tail(self):
|
42
|
-
"""Test the head and tail validation."""
|
43
|
-
try:
|
44
|
-
valid_id = get_lion_id("valid_head")
|
45
|
-
except Exception as e:
|
46
|
-
if e.__class__.__name__ == "LionTypeError":
|
47
|
-
return
|
48
|
-
self.assertEqual(Edge._validate_head_tail(valid_id), valid_id)
|
49
|
-
with self.assertRaises(ValidationError):
|
50
|
-
Edge._validate_head_tail("invalid_id")
|
51
|
-
|
52
|
-
def test_string_condition_none(self):
|
53
|
-
"""Test string_condition method when condition is None."""
|
54
|
-
self.assertIsNone(self.edge.string_condition())
|
55
|
-
|
56
|
-
def test_len(self):
|
57
|
-
"""Test the __len__ method."""
|
58
|
-
self.assertEqual(len(self.edge), 1)
|
59
|
-
|
60
|
-
def test_contains(self):
|
61
|
-
"""Test the __contains__ method."""
|
62
|
-
self.assertIn(self.node1.ln_id, self.edge)
|
63
|
-
self.assertIn(self.node2.ln_id, self.edge)
|
64
|
-
fake_node = Component()
|
65
|
-
self.assertNotIn(fake_node.ln_id, self.edge)
|
66
|
-
|
67
|
-
|
68
|
-
if __name__ == "__main__":
|
69
|
-
unittest.main()
|
@@ -1,97 +0,0 @@
|
|
1
|
-
import unittest
|
2
|
-
|
3
|
-
from lionagi.core.collections.abc import ItemNotFoundError, LionTypeError
|
4
|
-
from lionagi.core.generic import Edge, Graph, Node
|
5
|
-
from lionagi.libs.ln_convert import to_list
|
6
|
-
|
7
|
-
|
8
|
-
class TestGraph(unittest.TestCase):
|
9
|
-
|
10
|
-
def setUp(self):
|
11
|
-
"""Set up a basic graph for testing."""
|
12
|
-
self.node1 = Node()
|
13
|
-
self.node2 = Node()
|
14
|
-
self.node3 = Node()
|
15
|
-
self.node4 = Node()
|
16
|
-
self.g = Graph()
|
17
|
-
|
18
|
-
def test_initial_size(self):
|
19
|
-
"""Test the initial size of the graph."""
|
20
|
-
self.assertEqual(self.g.size(), 0)
|
21
|
-
|
22
|
-
def test_initial_internal_edges(self):
|
23
|
-
"""Test the initial number of internal edges."""
|
24
|
-
self.assertEqual(len(self.g.internal_edges), 0)
|
25
|
-
|
26
|
-
def test_add_node_no_edge(self):
|
27
|
-
"""Test that adding nodes does not create any edges."""
|
28
|
-
self.g.add_node([self.node1, self.node2, self.node3, self.node4])
|
29
|
-
self.assertEqual(len(self.g.internal_edges), 0)
|
30
|
-
|
31
|
-
def test_add_edges(self):
|
32
|
-
"""Test adding edges between nodes."""
|
33
|
-
self.g.add_edge(self.node1, self.node2)
|
34
|
-
self.g.add_edge(self.node2, self.node3)
|
35
|
-
self.g.add_edge(self.node3, self.node4)
|
36
|
-
self.assertEqual(len(self.g.internal_edges), 3)
|
37
|
-
|
38
|
-
def test_get_node(self):
|
39
|
-
"""Test retrieving a node by its identifier."""
|
40
|
-
self.g.add_node(self.node2)
|
41
|
-
node5 = self.g.get_node(self.node2)
|
42
|
-
self.assertEqual(node5, self.node2)
|
43
|
-
|
44
|
-
def test_get_node_edges(self):
|
45
|
-
"""Test getting the edges of a node."""
|
46
|
-
self.g.add_edge(self.node1, self.node2)
|
47
|
-
self.assertEqual(len(self.g.get_node_edges(self.node1)), 1)
|
48
|
-
|
49
|
-
def test_get_heads(self):
|
50
|
-
"""Test getting head nodes."""
|
51
|
-
self.g.add_edge(self.node1, self.node2)
|
52
|
-
self.g.add_edge(self.node2, self.node3)
|
53
|
-
self.g.add_edge(self.node3, self.node4)
|
54
|
-
self.assertEqual(len(self.g.get_heads()), 1)
|
55
|
-
|
56
|
-
def test_is_acyclic(self):
|
57
|
-
"""Test if the graph is acyclic."""
|
58
|
-
self.g.add_edge(self.node1, self.node2)
|
59
|
-
self.g.add_edge(self.node2, self.node3)
|
60
|
-
self.g.add_edge(self.node3, self.node4)
|
61
|
-
self.assertTrue(self.g.is_acyclic())
|
62
|
-
|
63
|
-
def test_remove_edge(self):
|
64
|
-
"""Test removing an edge from the graph."""
|
65
|
-
self.g.add_edge(self.node1, self.node2)
|
66
|
-
self.g.add_edge(self.node2, self.node3)
|
67
|
-
self.g.add_edge(self.node3, self.node4)
|
68
|
-
edge = self.g.internal_edges[0]
|
69
|
-
self.g.remove_edge(edge)
|
70
|
-
self.assertEqual(len(self.g.internal_edges), 2)
|
71
|
-
|
72
|
-
def test_remove_nonexistent_edge(self):
|
73
|
-
"""Test removing a nonexistent edge."""
|
74
|
-
self.g.add_edge(self.node1, self.node2)
|
75
|
-
with self.assertRaises(ItemNotFoundError):
|
76
|
-
self.g.remove_edge(edge=Edge(head=self.node2, tail=self.node3))
|
77
|
-
|
78
|
-
def test_clear(self):
|
79
|
-
"""Test clearing all nodes and edges from the graph."""
|
80
|
-
self.g.add_node([self.node1, self.node2, self.node3, self.node4])
|
81
|
-
self.g.add_edge(self.node1, self.node2)
|
82
|
-
self.g.add_edge(self.node2, self.node3)
|
83
|
-
self.g.add_edge(self.node3, self.node4)
|
84
|
-
self.g.clear()
|
85
|
-
self.assertTrue(self.g.is_empty())
|
86
|
-
self.assertEqual(len(self.g.internal_edges), 0)
|
87
|
-
|
88
|
-
def test_display(self):
|
89
|
-
"""Test displaying the graph (visual check)."""
|
90
|
-
self.g.add_edge(self.node1, self.node2)
|
91
|
-
self.g.add_edge(self.node2, self.node3)
|
92
|
-
self.g.add_edge(self.node3, self.node4)
|
93
|
-
self.g.display() # This should display the graph visually
|
94
|
-
|
95
|
-
|
96
|
-
if __name__ == "__main__":
|
97
|
-
unittest.main()
|